安防监控实现之A9主框架的搭建

文章目录

  • 声明
  • 线程
  • 概念(意识)
    • 分层分析
    • 数据流分析
  • 软件层次框架图
    • 系统框架,线程关系
    • 项目目录结构
    • 数据描述
      • 结构体描述
      • 全局变量描述
  • 主线程与各个子线程的搭建
    • 主线程
    • 各个子线程的函数
    • 搭建运行效果

声明

华清远见教育集团 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

概念(意识)

  1. 分层意识
  2. 数据流

分层分析

层次结构 说明 数据
web网页端显示部分 环境信息 === 实时刷新环境数据
摄像头采集图像 === 采集监控信息
硬件控制 === 下发要去控制的命令
环境信息: adc电压数据 、mpu6050的六轴数据 、温度 、湿度
摄像头采集图像:
硬件控制:风扇、 LED灯、蜂鸣器 、GPRS ==== 发短信或打电话
A9数据处理部分 创建进程、线程
每条线程做自己的事情
涉及到进程间通信
数据处理===>分发(上行数据 or 下行数据)

数据流向分析:
1、ZigBee(采集终端)–>A9(处理平台)
2、A9(处理平台)–>网页(显示平台)
3、网页(显示平台)–>A9(处理平台)
4、A9(处理平台)—>ZigBee(采集终端)
A9-ZigBee数据采集部分 A9采集部分
ZigBee采集部分
(STM32平台(可以自己扩展))
安防监控实现之A9主框架的搭建_第1张图片
小结 安防监控实现之A9主框架的搭建_第2张图片

数据流分析

  1. 制定通信的协议(结构体):

  2. 数据要怎么上传,上传的目的是为了什么?

  3. 数据要怎么下发,下发的目的又是为了什么?

    数据的上传: ====> 共享内存上传数据 ====> 显示并交给用户查看环境信息
    数据的下发用于控制硬件:====> 消息队列下发数据====>  控制硬件改变环境
    
数据上传 数据下发
安防监控实现之A9主框架的搭建_第3张图片 安防监控实现之A9主框架的搭建_第4张图片

软件层次框架图

安防监控实现之A9主框架的搭建_第5张图片

  1. 项目描述:
    在main程序中申请的很多线程,每个线程代表一个任务处理,进而实现多任务并发的机制。这里A9应用层程序设计为一个应用服务器,不仅要接收底层送过来的数据包,解析处理后的数据最终要送到html文件中,最后经浏览器解析展示给用户看;而且还要求能接收客户端用户发出的命令,然后进一步实现某个设定。把整个项目功能分成多个任务,有处理客户端请求线程、解析底层数据包并填充到结构体线程、处理数据并传递到网页端线程,等等。。。这么多线程,要考虑到线程之间的同步互斥机制,如何对资源进行访问。

  2. 目的:本文将把这种多线程处理的思想,构建成一个用户程序框架,最终实现多个线程的切换。暂时不实现上图所示的这些功能。重点是项目架构的实现。

系统框架,线程关系

  1. 先通过 ZigBee 模块进行实时采集环境参数,例如温度、湿度、光感数据;

  2. 再通过 ZigBee 协调器进行数据接收,然后把采集到的环境参数通过串口发送给 A9;

  3. 由 A9 的 client_request 线程负责接收环境参数或其他请求,激活数据库线程对数据库进行相应的
    处理,如果是环境参数则对环境参数进行判断处理进行报警。

  4. 用摄像头采集图片,存储到 A9 上。

  5. 构建嵌入式 web 服务器,使用户通过网络利用 pc 机进行监控。

  6. 在 web 页面上设置控制按钮,监控设备识别用户指令并进行相应动作

  7. 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

数据描述

结构体描述

  1. 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;
    
  2. 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;
    
  3. 环境参数对象结构体参数

     typedef struct _makeru_env_data
     {
     	CROTEXA9_INFO_T  a9_info;    
     	ZIGBEE_INFO_T    zigbee_info;
     	uint32_t reserved[2]; //保留扩展位,默认填充0
     }ENV_DATA_T;
    
  4. 所有监控区域的信息结构体

     struct env_info_client_addr
     {
     	ENV_DATA_T  monitor_no[MONITOR_NUM];	//数组  老家---新家
     }env_info_client_addr;
    
  5. 设备控制对象列表

     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到子线程的结束状态,然后进行线程回收。
安防监控实现之A9主框架的搭建_第6张图片

你可能感兴趣的:(安防监控项目)