首先将fsadc、fsbeeper、fsled、fsmpu6050驱动移植安装到a9,保证a9可以正常采集数据,
传感器数据交互用到的两个线程文件如下:
pthread_refresh.c
#include "data_global.h"
#include "common.h"
#include "mpu6050.h"
#include
//接收ZigBee的数据和采集的A9平台的传感器数据
int adc_fd;
int mpu_fd;
extern pthread_cond_t cond_transfer;
extern pthread_mutex_t mutex_transfer;
extern struct env_info_client_addr sm_all_env_info;
int file_env_info_a9_zigbee_debug(struct env_info_client_addr* rt_status, int home_id);
int file_env_info_a9_zigbee_stm32(struct env_info_client_addr* rt_status, int home_id);
int printf_sensor_info_debug(struct env_info_client_addr* sm_all_env_info, int home_id);
//读取adc、mpu数据
void* pthread_transfer(void* arg)
{
int home_id = 1;
adc_fd = open(ADC_DEV, O_RDWR);//打开adc驱动设备
mpu_fd = open(MPU6050_DEV, O_RDWR);//打开mpu驱动设备
if ((adc_fd == -1) || (mpu_fd == -1))
{
printf("open adc or mpu device failed.\n");
}
while (1)
{
pthread_mutex_lock(&mutex_transfer);//增加线程锁
pthread_cond_wait(&cond_transfer, &mutex_transfer);//等待条件变量变化,结束休眠,条件变量在书信数据线程
printf("pthread_analysis and tranfer.\n");
#if 1
file_env_info_a9_zigbee_stm32(&sm_all_env_info, home_id);//发生数据变化会对数据进行填充刷新,
#else
file_env_info_a9_zigbee_debug(&sm_all_env_info, home_id);
#endif
pthread_mutex_unlock(&mutex_transfer);//解锁
sleep(1);
}
close(adc_fd);
close(mpu_fd);
}
int file_env_info_a9_zigbee_debug(struct env_info_client_addr* rt_status, int home_id)
{
static int temp = 0;
int env_info_size = sizeof(struct env_info_client_addr);
// printf("env_info_size = %d.\n",env_info_size);
rt_status->monitor_no[home_id].zigbee_info.temperature = 10.0;
rt_status->monitor_no[home_id].zigbee_info.tempMIN = 2.0;
rt_status->monitor_no[home_id].zigbee_info.tempMAX = 20.0;
rt_status->monitor_no[home_id].zigbee_info.humidity = 20.0;
rt_status->monitor_no[home_id].zigbee_info.humidityMIN = 10.0;
rt_status->monitor_no[home_id].zigbee_info.humidityMAX = 30.0;
rt_status->monitor_no[home_id].zigbee_info.reserved[0] = 0.01;
rt_status->monitor_no[home_id].zigbee_info.reserved[1] = -0.01;
temp++;
rt_status->monitor_no[home_id].a9_info.adc = temp;
rt_status->monitor_no[home_id].a9_info.gyrox = -14.0;
rt_status->monitor_no[home_id].a9_info.gyroy = 20.0;
rt_status->monitor_no[home_id].a9_info.gyroz = 40.0;
rt_status->monitor_no[home_id].a9_info.aacx = 642.0;
rt_status->monitor_no[home_id].a9_info.aacy = -34.0;
rt_status->monitor_no[home_id].a9_info.aacz = 5002.0;
rt_status->monitor_no[home_id].a9_info.reserved[0] = 0.01;
rt_status->monitor_no[home_id].a9_info.reserved[1] = -0.01;
printf_sensor_info_debug(rt_status, home_id);
//添加stm32部分的数据、arduino数据,
return 0;
}
#if 0
int get_sensor_data_from_a9(struct makeru_a9_info* a9_sensor_data)
{
int adc_sensor_data;
struct mpu6050_data data;
/*get adc sensor data*/
read(adc_fd, &adc_sensor_data, 4);
printf("adc value :%0.2fV.\n", (1.8 * adc_sensor_data) / 4096);
/* get mpu6050 sensor data*/
ioctl(mpu_fd, MPU6050_GYRO, &data);
printf("gyro data: x = %05d, y = %05d, z = %05d\n", data.gyro.x, data.gyro.y, data.gyro.z);
ioctl(mpu_fd, MPU6050_ACCEL, &data);
printf("accel data: x = %05d, y = %05d, z = %05d\n", data.accel.x, data.accel.y, data.accel.z);
/*预填充,有点浪费空间,大家可以优化一下*/
a9_sensor_data->adc = (1.8 * adc_sensor_data) / 4096 * 100; //定义未int32,应该是float,放大100倍,保护小数位
a9_sensor_data->gyrox = data.gyro.x;
a9_sensor_data->gyroy = data.gyro.y;
a9_sensor_data->gyroz = data.gyro.z;
a9_sensor_data->aacx = data.accel.x;
a9_sensor_data->aacy = data.accel.y;
a9_sensor_data->aacz = data.accel.z;
return 0;
}
#endif
//读adc、mpu数据,将数据存到rt_status结构体中
int file_env_info_a9_zigbee_stm32(struct env_info_client_addr* rt_status, int home_id)
{
int env_info_size = sizeof(struct env_info_client_addr);
printf("env_info_size = %d.\n", env_info_size);
rt_status->monitor_no[home_id].zigbee_info.head[0] = 'm';
rt_status->monitor_no[home_id].zigbee_info.head[1] = 's';
rt_status->monitor_no[home_id].zigbee_info.head[2] = 'm';
rt_status->monitor_no[home_id].zigbee_info.head[3] = 'z';
rt_status->monitor_no[home_id].zigbee_info.temperature = 10.0;
rt_status->monitor_no[home_id].zigbee_info.tempMIN = 2.0;
rt_status->monitor_no[home_id].zigbee_info.tempMAX = 20.0;
rt_status->monitor_no[home_id].zigbee_info.humidity = 20.0;
rt_status->monitor_no[home_id].zigbee_info.humidityMIN = 10.0;
rt_status->monitor_no[home_id].zigbee_info.humidityMAX = 30.0;
rt_status->monitor_no[home_id].zigbee_info.reserved[0] = 0.01;
rt_status->monitor_no[home_id].zigbee_info.reserved[1] = -0.01;
//获取数据
int adc_sensor_data;
struct mpu6050_data data;
/*get adc sensor data*/
read(adc_fd, &adc_sensor_data, 4); /*遗留问题解决:忘记加载驱动了,同志们要注意了......*/
printf("adc value :%0.2fV.\n", (1.8 * adc_sensor_data) / 4096);
rt_status->monitor_no[home_id].a9_info.adc = (float)((1.8 * adc_sensor_data) / 4096);
/* get mpu6050 sensor data*/
ioctl(mpu_fd, MPU6050_GYRO, &data);
printf("gyro data: x = %d, y = %d, z = %d\n", data.gyro.x, data.gyro.y, data.gyro.z);
ioctl(mpu_fd, MPU6050_ACCEL, &data);
printf("accel data: x = %d, y = %d, z = %d\n", data.accel.x, data.accel.y, data.accel.z);
rt_status->monitor_no[home_id].a9_info.head[0] = 'm';
rt_status->monitor_no[home_id].a9_info.head[1] = 's';
rt_status->monitor_no[home_id].a9_info.head[2] = 'm';
rt_status->monitor_no[home_id].a9_info.head[3] = 'a';
rt_status->monitor_no[home_id].a9_info.gyrox = (short)data.gyro.x;
rt_status->monitor_no[home_id].a9_info.gyroy = (short)data.gyro.y;
rt_status->monitor_no[home_id].a9_info.gyroz = (short)data.gyro.z;
rt_status->monitor_no[home_id].a9_info.aacx = (short)data.accel.x;
rt_status->monitor_no[home_id].a9_info.aacy = (short)data.accel.y;
rt_status->monitor_no[home_id].a9_info.aacz = (short)data.accel.z;
rt_status->monitor_no[home_id].a9_info.reserved[0] = 0.01;
rt_status->monitor_no[home_id].a9_info.reserved[1] = -0.01;
printf_sensor_info_debug(rt_status, home_id);
//添加stm32部分的数据、arduino数据,
return 0;
}
int printf_sensor_info_debug(struct env_info_client_addr* sm_all_env_info, int home_id)
{
printf("a9_info.adc : %f.\n", sm_all_env_info->monitor_no[home_id].a9_info.adc);
printf("a9_info.gyrox: %d.\n", sm_all_env_info->monitor_no[home_id].a9_info.gyrox);
printf("a9_info.gyroy: %d.\n", sm_all_env_info->monitor_no[home_id].a9_info.gyroy);
printf("a9_info.gyroz: %d.\n", sm_all_env_info->monitor_no[home_id].a9_info.gyroz);
printf("a9_info.aacx : %d.\n", sm_all_env_info->monitor_no[home_id].a9_info.aacx);
printf("a9_info.aacy : %d.\n", sm_all_env_info->monitor_no[home_id].a9_info.aacy);
printf("a9_info.aacz : %d.\n", sm_all_env_info->monitor_no[home_id].a9_info.aacz);
printf("a9_info.reserved[0]: %d.\n", sm_all_env_info->monitor_no[home_id].a9_info.reserved[0]);
printf("a9_info.reserved[1]: %d.\n", sm_all_env_info->monitor_no[home_id].a9_info.reserved[1]);
return 0;
}
pthread_refresh.c
#include "data_global.h"
#include "sem.h"
#define N 1024 //for share memory
extern int shmid;
extern int msgid;
extern int semid;
extern key_t shm_key;
extern key_t sem_key;
extern key_t key; //msg_key
extern pthread_mutex_t mutex_client_request,
mutex_refresh,
mutex_sqlite,
mutex_transfer,
mutex_analysis,
mutex_sms,
mutex_buzzer,
mutex_led,
mutex_camera;
extern pthread_cond_t cond_client_request,
cond_refresh,
cond_sqlite,
cond_transfer,
cond_analysis,
cond_sms,
cond_buzzer,
cond_led,
cond_camera;
extern struct env_info_client_addr sm_all_env_info;
struct shm_addr
{
char shm_status; //shm_status可以等于home_id,用来区分共享内存数据
struct env_info_client_addr sm_all_env_info;
};
struct shm_addr* shm_buf;
int file_env_info_struct(struct env_info_client_addr* rt_status, int home_id);//模拟数据刷新的函数
void* pthread_refresh(void* arg)
{
//semaphore for access to resource limitsftok 访问资源限制的信号量sftok 函数用于将给定的文件路径名和一个整数标识符转换为一个唯一的 key 值,用于标识 System V IPC(进程间通信)的资源,如消息队列、信号量和共享内存等
if ((sem_key = ftok("/tmp", 'i')) < 0)
{
perror("ftok failed .\n");
exit(-1);
}
//semget 函数用于创建或访问一个 System V 信号量集。信号量是一种用于多进程(或多线程)之间进行同步和互斥的机制,用于控制对共享资源的访问。
semid = semget(sem_key, 1, IPC_CREAT | IPC_EXCL | 0666);
if (semid == -1)
{
if (errno == EEXIST)
{
semid = semget(sem_key, 1, 0777);
}
else
{
perror("fail to semget");
exit(1);
}
}
else
{
init_sem(semid, 0, 1);
}
//share memory for env_info refresh config env_info刷新配置的共享内存
if ((shm_key = ftok("/tmp", 'i')) < 0)
{
perror("ftok failed .\n");
exit(-1);
}
shmid = shmget(shm_key, N, IPC_CREAT | IPC_EXCL | 0666);
if (shmid == -1)
{
if (errno == EEXIST)
{
shmid = shmget(key, N, 0777);
}
else
{
perror("fail to shmget");
exit(1);
}
}
//share memap shmat 函数用于将共享内存段附加到调用进程的地址空间,使进程可以访问和操作共享内存中的数据
if ((shm_buf = (struct shm_addr*)shmat(shmid, NULL, 0)) == (void*)-1)
{
perror("fail to shmat");
exit(1);
}
printf("pthread_refresh ......>>>>>>>\n");
bzero(shm_buf, sizeof(struct shm_addr));
while (1)
{
sem_p(semid, 0); //P操作sem_p 函数一般用于实现信号量的 P(wait)操作,用于对信号量进行减操作。它用于控制对共享资源的访问以实现进程间的同步与互斥。
shm_buf->shm_status = 1;
int home_id = 1;
#if 1
shm_buf->sm_all_env_info.monitor_no[home_id] = sm_all_env_info.monitor_no[home_id]; //真实数据上传
#else
file_env_info_struct(&shm_buf->sm_all_env_info, shm_buf->shm_status); //模拟数据上传
#endif
sleep(1);
sem_v(semid, 0); //v操作sem_v函数是POSIX标准中用于信号量操作的函数之一。该函数的作用是对指定的信号量进行V操作。具体而言,sem_v函数会将信号量的值加1,并且如果有进程或线程正在等待该信号量,则唤醒其中的一个。V操作是一种原子操作,也就是说,它是以原子方式进行的,不会被中断。通过调用sem_v函数,可以实现对信号量进行加锁或解锁的操作,用于保护共享资源的访问。
pthread_cond_signal(&cond_transfer);//唤醒pthread_transfer线程,继续刷新数据
}
}
int file_env_info_struct(struct env_info_client_addr* rt_status, int home_id)
{
int env_info_size = sizeof(struct env_info_client_addr);
// printf("env_info_size = %d.\n",env_info_size);
rt_status->monitor_no[home_id].zigbee_info.temperature = 10.0;
rt_status->monitor_no[home_id].zigbee_info.tempMIN = 2.0;
rt_status->monitor_no[home_id].zigbee_info.tempMAX = 20.0;
rt_status->monitor_no[home_id].zigbee_info.humidity = 20.0;
rt_status->monitor_no[home_id].zigbee_info.humidityMIN = 10.0;
rt_status->monitor_no[home_id].zigbee_info.humidityMAX = 30.0;
rt_status->monitor_no[home_id].zigbee_info.reserved[0] = 0.01;
rt_status->monitor_no[home_id].zigbee_info.reserved[1] = -0.01;
rt_status->monitor_no[home_id].a9_info.adc = 9.0;
rt_status->monitor_no[home_id].a9_info.gyrox = -14.0;
rt_status->monitor_no[home_id].a9_info.gyroy = 20.0;
rt_status->monitor_no[home_id].a9_info.gyroz = 40.0;
rt_status->monitor_no[home_id].a9_info.aacx = 642.0;
rt_status->monitor_no[home_id].a9_info.aacy = -34.0;
rt_status->monitor_no[home_id].a9_info.aacz = 5002.0;
rt_status->monitor_no[home_id].a9_info.reserved[0] = 0.01;
rt_status->monitor_no[home_id].a9_info.reserved[1] = -0.01;
//添加stm32部分的数据、arduino数据,
return 0;
}