实现的功能
系统运行环境
软件配置
开发平台: Ubuntu14.04 vs2012 vs2017
开发环境: linux3.14.0、uboot2013.01、gcc4.6.4
通信协议: 串口、ZigBee、http协议等
数据库 : sqlite3
硬件配置
处理器:Cortex-A9(Exynos4412)开发板 (开发板上自带DHT11温湿度传感器,USB摄像头等数据采集装置,所以暂时可以不考虑远端的数据采集,将开发板采集的数据上传的应用层) ;usb摄像
远端数据采集设备: ZigBee/STM32(用于数据的采集)通过WIFI/蓝牙等模块实现数据的传输。如果检测的数据量种类多的话,用ZigBee搭建传感器网络是最符合实际应用的
硬件环境分析
软件框架分析
从上往下看,cgi进程作为RAM开发板与网页之间的中间层,该层实现了c语言与html语言的一个转化。从上往下看,cgi进程将得到的信息通过消息队列的方式下发给主进程->接受用户请求线程(同时还负责消息的下发),LED,蜂鸣器,GPRS等三个线程根据接受用户请求线程的信息实施各自的操作。从下往上看,数据采集线程和收集RAM开发板自身的数据和ZigBee传来的数据通过 共享内存/信号量 的方式传送给cgi进程,在由cgi进程传送给网页端
框架的搭建
通过两个方面对项目的框架进行分析
分层分析:
web网页端显示部分:
环境信息 = = =》 实时刷新环境数据
摄像头采集图像 = = =》 采集监控信息
硬件控制 = = =》下发要去控制的命令
A9数据处理部分
创建进程、线程
每条线程做自己的事情
涉及到进程间通信
数据处理《 = = =》分发(上行数据 or 下行数据)
A9-ZigBee数据采集部分
A9采集部分
ZigBee采集部分/(STM32平台(可以自己扩展))
数据流分析:
数据上传 : 如何上传? 制定通信的结构体 == == ==》共享内存上传数据 = = =》 显示并交给 用户查看环境信息
数据下发:如何下发? 数据的下发用于控制硬件== == ==》 制定控制命令 == == ==》消息队列下发数据 = = =》 控制硬件改变环境
看到这里可能有盆友会疑惑,同样是进程间的通信,为什么数据的上传通过共享内存而数据的下发是通过消息队列呢?
答: 这跟数据的特性是有关,下发的数据是用来控制硬件的一些命令,这些命令按照规定的格式(格式单一且所占字节较少),所以通过消息队列下发,实现简答且效率高。 上传的数据,包括各种各样的传感器所采集到的数据,数据量大,且格式不一,所以需要将数据打包,通过数据包的形式上传,通过共享内存的方式显然是更加容易实现的。 下面我们具体来看看如何实现处理这些数据的:
数据的处理
制定通信的结构体:!!!! 面向对象的思想
数据的上传:
// !!!! 面向对象的思想
//数据类型定义:
typedef uint8_t unsigned char; // =======参考:
typedef uint16_t unsigned short;
typedef uint32_t unsigned int;
//考虑到内存对齐的问题
struct makeru_zigbee_info{
uint8_t head[3]; //标识位: 'm' 's' 'm' makeru-security-monitor
uint8_t type; //数据类型 'z'---zigbee 'a'---a9
------------->crc ...加密算法 <--------------
float temperature; //温度
float humidity; //湿度
float tempMIN;//温度下限
float tempMAX;//温度上限
float humidityMIN; //湿度下限
float humidityMAX; //湿度上限
uint32_t reserved[2]; //保留扩展位,默认填充0
//void *data; 内核预留的扩展接口 参考版
};
struct makeru_a9_info{
uint8_t head[3]; //标识位: 'm' 's' 'm' makeru-security-monitor
uint8_t type; //数据类型 'z'---zigbee 'a'---a9
uint32_t adc;
short gyrox; //陀螺仪数据
short gyroy;
short gyroz;
short aacx; //加速计数据
short aacy;
short aacz;
uint32_t reserved[2]; //保留扩展位,默认填充0
//void *data; 内核预留的扩展接口 参考版
};
struct makeru_env_data{
struct makeru_a9_info a9_info;
struct makeru_zigbee_info zigbee_info;
};
//所有监控区域的信息结构体
struct env_info_client_addr
{
struct makeru_env_data monitor_no[MONITOR_NUM]; //数组 ,如果包含多个监控环境,对进一步封装,用结构体
//数组来表示
};
数据的下发:(采用消息队列的方式下发数据到下位机上)
数据的下发用于控制硬件:
控制命令的制作:
程序
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
int msgflg);
//消息队列用于通信的结构体: 包括数据类型和数据
//将消息队列封装成函数,直接通过参数传递的方式来发送信息:
int send_msg_queue(long type,unsigned char text)
{
struct msg msgbuf;
msgbuf.type = 1L;
msgbuf.msgtype = type; //具体的消息类型,用来建立两个进程间的链接
msgbuf.mtext[0] = text; //控制命令字
if(msgsnd(msgid,&msgbuf,sizeof(msgbuf) - sizeof(long),0) == -1){
perror("fail to msgsnd type2");
exit(1);
}
return 0;
}
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
};
//消息队列结构体
#define QUEUE_MSG_LEN 32
struct msg
{
long type; //从消息队列接收消息时用于判断的消息类型 ==== 暂时不用 1L===home1 2L===home2 ...
long msgtype;//具体的消息类型 === 指代控制的设备,是什么类型的设备
unsigned char text[QUEUE_MSG_LEN];//消息正文 ====> CMD 控制指定的设备
};
//消息队列接收消息:
msgrcv (msgid, &msgbuf, sizeof (msgbuf) - sizeof (long), 1L, 0);
// 解析buf中的数据:
printf ("Get %ldL msg\n", msgbuf.msgtype);
printf ("text[0] = %#x\n", msgbuf.text[0]);
文中程序是跑不起来的!旨在提供编程思路
数据流向分析
1、 ZigBee(采集终端) —> A9(处理平台)
2、 A9(处理平台) —> 网页(显示平台)
**3、网页(显示平台)----> A9(处理平台) **
**4、A9(处理平台) ----> ZigBee(采集终端) **
A9/ZigBee 采集部分
外设驱动 : 在应用层去获取外设的状态或数据
蜂鸣器
LED灯
A9 按键
ADC
mpu6050
Zigbee adc 主----- 协调器
风扇 从 ----- 终端节点 --------- 下发命令控制风扇
温湿度 从------终端节点 ---------- 上传温湿度数据
总结
上行:封装的结构体 == == 共享内存和信号量 = = => 交给CGI(C语言和HTML语言之间的转化接口)= = => 交给HTML
下行:封装的命令字 == = 息队列 = = == >msgbuf msgsnd = = >控制命令字封装在msgsnd的msgbuf中 = = =>A9端解析 ==> 向下控制硬件
暂时先记录到这,未完待续…