华清远见教育集团 15年专注高端IT培训 做良心教育,做专业教育,做受人尊敬的职业教育
创客学院官网:http://www.makeru.com.cn/
华清远见创客学院嵌入式课程链接:http://www.makeru.com.cn/emb
华清远见创客学院物联网课程链接:http://www.makeru.com.cn/iot
https://zhuzhongwei.blog.csdn.net/article/details/90175878
制定通信的协议(结构体):
数据要怎么上传,上传的目的是为了什么?
数据要怎么下发,下发的目的又是为了什么?
数据的上传: ====> 共享内存上传数据 ====> 显示并交给用户查看环境信息
数据的下发用于控制硬件:====> 消息队列下发数据====> 控制硬件改变环境
数据上传 | 数据下发 |
---|---|
项目描述:
在main程序中申请的很多线程,每个线程代表一个任务处理,进而实现多任务并发的机制。这里A9应用层程序设计为一个应用服务器,不仅要接收底层送过来的数据包,解析处理后的数据最终要送到html文件中,最后经浏览器解析展示给用户看;而且还要求能接收客户端用户发出的命令,然后进一步实现某个设定。把整个项目功能分成多个任务,有处理客户端请求线程、解析底层数据包并填充到结构体线程、处理数据并传递到网页端线程,等等。。。这么多线程,要考虑到线程之间的同步互斥机制,如何对资源进行访问。
目的:本文将把这种多线程处理的思想,构建成一个用户程序框架,最终实现多个线程的切换。暂时不实现上图所示的这些功能。重点是项目架构的实现。
先通过 ZigBee 模块进行实时采集环境参数,例如温度、湿度、光感数据;
再通过 ZigBee 协调器进行数据接收,然后把采集到的环境参数通过串口发送给 A9;
由 A9 的 client_request 线程负责接收环境参数或其他请求,激活数据库线程对数据库进行相应的
处理,如果是环境参数则对环境参数进行判断处理进行报警。
用摄像头采集图片,存储到 A9 上。
构建嵌入式 web 服务器,使用户通过网络利用 pc 机进行监控。
在 web 页面上设置控制按钮,监控设备识别用户指令并进行相应动作
A9 通过 GPRS 短信息功能向数据描述用户报警。
pthread_client_request():处理消息队列里请求的线程.
pthread_refresh():更新共享内存里的实时数据.
pthread_sqlite():数据库线程.
pthread_transfer ():接收数据线程…
pthread_sms():短信模块控制线程.
pthread_led():A9LED 模块线程.
pthread_camera():摄像头模块控制线程
phtread_buzzer():A9 蜂鸣器模块线程.
linux@linux:/home/zzw/share/Security_Monitoring_Project$ tree -L 1 .
├── data_global.c 定义全局信息(IPC对象id和key值、条件锁、互斥锁)
├── data_global.h 一些全局变量、全局信息的声明(全局宏定义、全局函数声明、全局变量声明)
├── main.c 主线程,用于多个子线程和锁的统一申请、注销线程资源、注销消息队列 共享内存 信号量等等
├── Makefile 负责整个项目的编译
├── obj 这是一个目录,所有编译生成的中间文件在这个目录中
├── our_storage 最终编译输出的可执行文件
├── pthread_buzzer.c 线程 A9蜂鸣器控制
├── pthread_camera.c 线程 摄像头模块控制
├── pthread_client_request.c 线程 处理消息队列中的请求
├── pthread_led.c 线程 A9 LED模块
├── pthread_refresh.c 线程 更新共享内存里的实时数据
├── pthread_sms.c 线程 短信模块控制
├── pthread_sqlite.c 线程 数据库
├── pthread_transfer.c 线程 接收M0数据线程
└── sem.h 主要用于实现函数接口 对信号量的PV操作
1 directory, 14 files
zigbee 模块对象信息参数结构体
typedef struct _makeru_zigbee_info
{
uint8_t head[3]; //标识位: 'm' 's' 'm' makeru-security-monitor
uint8_t type; //数据类型 'z'---zigbee 'a'---a9
float temperature; //温度
float humidity; //湿度
float tempMIN; //温度下限
float tempMAX; //温度上限
float humidityMIN; //湿度下限
float humidityMAX; //湿度上限
uint32_t reserved[2]; //保留扩展位,默认填充0
//void *data; 内核预留的扩展接口 参考版
}ZIGBEE_INFO_T;
A9模块对象信息参数结构体
typedef struct _makeru_a9_info
{
uint8_t head[3]; //标识位: 'm' 's' 'm' makeru-security-monitor
uint8_t type; //数据类型 'z'---zigbee 'a'---a9
float adc;
short gyrox; //陀螺仪数据
short gyroy;
short gyroz;
short aacx; //加速计数据
short aacy;
short aacz;
uint32_t reserved[2]; //保留扩展位,默认填充0
//void *data; 内核预留的扩展接口 参考版
}CROTEXA9_INFO_T;
环境参数对象结构体参数
typedef struct _makeru_env_data
{
CROTEXA9_INFO_T a9_info;
ZIGBEE_INFO_T zigbee_info;
uint32_t reserved[2]; //保留扩展位,默认填充0
}ENV_DATA_T;
所有监控区域的信息结构体
struct env_info_client_addr
{
ENV_DATA_T monitor_no[MONITOR_NUM]; //数组 老家---新家
}env_info_client_addr;
设备控制对象列表
typedef enum
{
DEVICE_CTL_LED = 1, //LED控制
DEVICE_CTL_BUZZER = 2, //蜂鸣器控制
DEVICE_CTL_DIGITAL = 3, //四路LED灯模拟的数码管
DEVICE_CTL_FAN =4, //风扇
DEVICE_CTL_TEMP_HUMI=5, //温湿度最值设置
DEVICE_CTL_RESERVED=6, //用于个人的扩展
DEVICE_CTL_GPRS = 10, //3G通信模块-GPRS
DEVICE_CTL_MAX,
}DEVICE_CONTROL_LIST_E;
pthread_mutex_t mutex_client_request;
pthread_mutex_t mutex_refresh;
pthread_mutex_t mutex_sqlite;
pthread_mutex_t mutex_transfer;
pthread_mutex_t mutex_sms;
pthread_mutex_t mutex_buzzer;
pthread_mutex_t mutex_led;
pthread_mutex_t mutex_camera;
pthread_cond_t cond_client_request;
pthread_cond_t cond_refresh;
pthread_cond_t cond_sqlite;
pthread_cond_t cond_transfer;
pthread_cond_t cond_sms;
pthread_cond_t cond_buzzer;
pthread_cond_t cond_led;
pthread_cond_t cond_camera;
int msgid; //消息队列对象 id
int shmid; //共享内存对象 id
int semid; //信号量对象 id
key_t key; //msg_key 消息队列
key_t shm_key;
key_t sem_key;
char recive_phone[12] = {0};
char center_phone[12] = {0};
struct env_info_client_addr sm_all_env_info; //安防监控项目所有的环境信息
#include
#include
#include
#include
#include
#include
#include
#include
#include "data_global.h"
void release_pthread_resource(int signo);//释放线程资源
extern pthread_mutex_t mutex_client_request;
extern pthread_mutex_t mutex_refresh;
extern pthread_mutex_t mutex_sqlite;
extern pthread_mutex_t mutex_transfer;
extern pthread_mutex_t mutex_sms;
extern pthread_mutex_t mutex_buzzer;
extern pthread_mutex_t mutex_led;
extern pthread_mutex_t mutex_camera;
extern pthread_cond_t cond_client_request;
extern pthread_cond_t cond_refresh;
extern pthread_cond_t cond_sqlite;
extern pthread_cond_t cond_transfer;
extern pthread_cond_t cond_sms;
extern pthread_cond_t cond_buzzer;
extern pthread_cond_t cond_led;
extern pthread_cond_t cond_camera;
extern int msgid; //消息队列对象 id
extern int shmid; //共享内存对象 id
extern int semid; //信号量对象 id
pthread_t id_client_request;
pthread_t id_refresh;
pthread_t id_sqlite;
pthread_t id_transfer;
pthread_t id_sms;
pthread_t id_buzzer;
pthread_t id_led;
pthread_t id_camera;
int main(int argc, char const *argv[])
{
//线程互斥锁初始化
pthread_mutex_init(&mutex_client_request,NULL);
pthread_mutex_init(&mutex_refresh,NULL);
pthread_mutex_init(&mutex_sqlite,NULL);
pthread_mutex_init(&mutex_transfer,NULL);
pthread_mutex_init(&mutex_sms,NULL);
pthread_mutex_init(&mutex_buzzer,NULL);
pthread_mutex_init(&mutex_led,NULL);
pthread_mutex_init(&mutex_camera,NULL);
signal (SIGINT, release_pthread_resource);
//线程条件锁初始化
pthread_cond_init(&cond_client_request,NULL);
pthread_cond_init(&cond_refresh,NULL);
pthread_cond_init(&cond_sqlite,NULL);
pthread_cond_init(&cond_transfer,NULL);
pthread_cond_init(&cond_sms,NULL);
pthread_cond_init(&cond_led,NULL);
pthread_cond_init(&cond_camera,NULL);
//线程的创建
pthread_create(&id_client_request,NULL,pthread_client_request,NULL); //线程的创建
pthread_create(&id_refresh, NULL,pthread_refresh,NULL);
pthread_create(&id_sqlite, NULL,pthread_sqlite,NULL);
pthread_create(&id_transfer,NULL,pthread_transfer,NULL);
pthread_create(&id_sms, NULL,pthread_sms,NULL);
pthread_create(&id_buzzer, NULL,pthread_buzzer,NULL);
pthread_create(&id_led, NULL,pthread_led,NULL);
pthread_create(&id_camera, NULL,pthread_camera,NULL);
//等待线程退出
pthread_join(id_client_request,NULL); printf ("pthread1\n");
pthread_join(id_refresh,NULL); printf ("pthread2\n");
pthread_join(id_sqlite,NULL); printf ("pthread3\n");
pthread_join(id_transfer,NULL); printf ("pthread4\n");
pthread_join(id_sms,NULL); printf ("pthread5\n");
pthread_join(id_buzzer,NULL); printf ("pthread6\n");
pthread_join(id_led,NULL); printf ("pthread7\n");
pthread_join(id_camera,NULL); printf ("pthread8\n");
return 0;
}
void release_pthread_resource(int signo)
{
//释放与线程相关的资源
//释放线程锁资源
pthread_mutex_destroy (&mutex_client_request);
pthread_mutex_destroy (&mutex_refresh);
pthread_mutex_destroy (&mutex_sqlite);
pthread_mutex_destroy (&mutex_transfer);
pthread_mutex_destroy (&mutex_sms);
pthread_mutex_destroy (&mutex_buzzer);
pthread_mutex_destroy (&mutex_led);
pthread_mutex_destroy (&mutex_camera);
pthread_cond_destroy (&cond_client_request);
pthread_cond_destroy (&cond_refresh);
pthread_cond_destroy (&cond_sqlite);
pthread_cond_destroy (&cond_transfer);
pthread_cond_destroy (&cond_sms);
pthread_cond_destroy (&cond_buzzer);
pthread_cond_destroy (&cond_led);
pthread_cond_destroy (&cond_camera);
pthread_detach(id_client_request);
pthread_detach(id_refresh);
pthread_detach(id_sqlite);
pthread_detach(id_transfer);
pthread_detach(id_sms);
pthread_detach(id_buzzer);
pthread_detach(id_led);
pthread_detach(id_camera);
printf("all pthread is detached\n");
msgctl (msgid, IPC_RMID, NULL);
shmctl (shmid, IPC_RMID, NULL);
semctl (semid, 1, IPC_RMID, NULL);
exit(0);
}
//pthread_transfer.c
//接收ZigBee的数据和采集的A9平台的传感器数据
void *pthread_transfer(void *arg)
{
printf("pthread_analysis\n");
}
//pthread_refresh.c
void *pthread_refresh(void *arg)
{//更新共享内存里的实时数据
printf("pthread_refresh\n");
}
//pthread_led.c
void *pthread_led(void *arg)
{//A9 LED模块线程
printf("pthread_led\n");
}
..............
....................
按照程序的思路,主线程先创建各个子线程。内核调度子线程的执行,这里子线程只打印一句话就结束了。子线程执行结束后,主线程get到子线程的结束状态,然后进行线程回收。