linux嵌入式项目之安防监控一(详解)

实现的功能

安防具体实现的功能

系统运行环境

软件配置

开发平台: 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];	//数组 ,如果包含多个监控环境,对进一步封装,用结构体
                                                                //数组来表示
		};

数据的下发:(采用消息队列的方式下发数据到下位机上)
数据的下发用于控制硬件:

控制命令的制作:

image-20220308223323632

image-20220308223419205

程序

       #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端解析 ==> 向下控制硬件

暂时先记录到这,未完待续…


  • 1
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现嵌入式Linux安防监控项目需要以下步骤: 1. 硬件选型:需要选择一块适合做嵌入式Linux开发的开发板,以及相应的外设(如摄像头、显示屏等)。 2. 系统选择:需要选择一款适合该开发板的Linux操作系统,并进行相关的配置。 3. 应用开发:需要编写应用程序,实现监控摄像头的视频采集、处理和存储功能。 4. 前端开发:需要开发前端界面,实现用户对监控视频的实时查看和操作。 以下是一个基于嵌入式Linux的简单安防监控项目的代码示例: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/mman.h> #define PAGE_SIZE 4096 #define BUF_SIZE 1024 int main(int argc, char *argv[]) { int fd, fd_mem, fd_cam; char *buf, *mem; struct stat st; size_t size; ssize_t nread; // 打开视频设备 fd_cam = open("/dev/video0", O_RDWR); if (fd_cam < 0) { perror("open /dev/video0"); exit(EXIT_FAILURE); } // 设置视频采集参数 // ... // 打开映射文件 fd = open("output.mp4", O_CREAT|O_TRUNC|O_RDWR, 0644); if (fd < 0) { perror("open output.mp4"); exit(EXIT_FAILURE); } // 设置映射文件大小 size = 1024 * 1024 * 10; // 10MB if (ftruncate(fd, size) < 0) { perror("ftruncate"); exit(EXIT_FAILURE); } // 映射到内存 mem = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (mem == MAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); } // 映射到用户空间 buf = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); if (buf == MAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); } // 循环采集视频帧并写入映射文件 while (1) { nread = read(fd_cam, buf, BUF_SIZE); if (nread < 0) { perror("read"); exit(EXIT_FAILURE); } memcpy(mem, buf, nread); mem += nread; if (mem - (char *)mem % PAGE_SIZE >= size) { mem = (char *)((mem - size) + (mem - size) % PAGE_SIZE + PAGE_SIZE); } } // 解除映射 if (munmap(buf, PAGE_SIZE) < 0) { perror("munmap"); exit(EXIT_FAILURE); } if (munmap(mem - size, size) < 0) { perror("munmap"); exit(EXIT_FAILURE); } // 关闭文件和设备 if (close(fd_cam) < 0) { perror("close /dev/video0"); exit(EXIT_FAILURE); } if (close(fd) < 0) { perror("close output.mp4"); exit(EXIT_FAILURE); } return 0; } ``` 注意:该示例仅供参考,实际应用还需要考虑更多的细节问题,如视频编码、网络传输等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值