四、主框架程序的搭建

1、概述

这里用到了线程的相关知识,包括线程的创建pthread _create()、线程的回收pthread_join()、线程的结束pthread_exit()
项目中根据实际情况开辟了相关的线程,比如:
pthread_client_request(void *arg)-----------接收用户请求线程
pthread_refresh(void *arg)--------------------数据刷新线程
pthread_sqlite(void *arg)----------------------数据库线程,保存数据库的数据
pthread_transfer(void *arg)-------------------数据采集线程
pthread_buzzer(void *arg)--------------------蜂鸣器控制线程
pthread_led(void *arg)-------------------------led灯控制线程
pthread_seg(void *arg)------------------------led灯模拟数码管控制线程
pthread_fan(void *arg)-------------------------zigbee风扇控制线程

数据的下发

pthread_client_request()与pthread_buzzer()、pthread_led()线程之间的通讯是通过全局变量+互斥+条件变量来实现的;
从网页发送消息到A9是通过消息队列来实现的,这里就用到了消息队列的知识点,包括消息队列的创建(msgget)、接收消息(msgrcv)、发送消息(msgsnd)、控制消息队列(msgctl);

数据的上传

pthread_refresh()与env.cgi进程间的通讯是通过共享内存+信号量来实现同步操作的;
从A9刷新数据到网页是通过共享内存来实现的,这里就用到了共享内存的知识点,包括共享内存的创建(shmget)、映射(shmat)、撤销映射(shmdt)、共享内存控制(shmctl);同时要加上信号量P(sem_wait() )、V(sem_post())操作进行临界资源同步操作
image-20220915141339974

2、主要文件

data_global.h

#ifndef __DATA_GLOBAL__H__
#define __DATA_GLOBAL__H__
/*
  全局的宏定义#define
  全局的线程函数声明
  全局的设备节点声明
  全局的消息队列发送函数外部extern声明
  全局的消息队列传递的结构体信息声明
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>
#include <termios.h>
#include <syscall.h> 
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <linux/ioctl.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <linux/input.h>
#include <errno.h>

/*********************************************************
  全局的宏定义
 *********************************************************/
#define MONITOR_NUM   1
#define QUEUE_MSG_LEN  32

/********************************************************
  对所使用设备的定义
 ********************************************************/
#define		ZIGBEE_DEV 		 "/dev/ttyUSB0"
#define		BEEPER_DEV 		 "/dev/fs4412_beep"
#define		LED_DEV    		 "/dev/fsled0"
#define		ADC_DEV    		 "/dev/fsadc0"
#define		MPU6050_DEV    "/dev/fsmpu60500"

unsigned char  cmd_led;
unsigned char  cmd_buzzer;
unsigned char  cmd_seg;
unsigned char  cmd_fan;

/*********************************************************
  全局的结构体声明
 *********************************************************/
typedef  unsigned char uint8_t;
typedef  unsigned short uint16_t;
typedef  unsigned int uint32_t;

/*zigbee所采集的数据*/
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
};

/*a9采集的数据*/
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
};

/*环境信息*/
struct makeru_env_data{
	struct 		makeru_a9_info       a9_info;    
	struct 		makeru_zigbee_info   zigbee_info;
	uint32_t 	reserved[2]; 
};

//所有房间的信息结构体
struct env_info_client_addr
{
	struct makeru_env_data  monitor_no[MONITOR_NUM];	//数组 home1  home2 
}__attribute__((aligned (1))); 
//GNU使用__attribute__选项来设置 此处设置一字节对齐

/*********************************************************
  全局的外部线程函数声明
 *********************************************************/
extern void *pthread_client_request(void *arg); 	//接收用户请求线程
extern void *pthread_refresh(void *arg);            //数据刷新线程
extern void *pthread_sqlite(void *arg);        		//数据库线程,保存数据库的数据
extern void *pthread_transfer(void *arg);  			//数据采集线程
extern void *pthread_buzzer(void *arg);    			//蜂鸣器控制线程
extern void *pthread_led(void *arg);       			//led灯控制线程
extern void *pthread_seg(void *arg);       			//led灯模拟数码管控制线程
extern void *pthread_fan(void *arg);       			//zigbee风扇控制线程

//发送消息队列
extern int send_msg_queue(long type,unsigned char text);

/*********************************************************
  全局的消息队列传递的结构体声明
 *********************************************************/
//消息队列结构体
struct msg
{
	long type;		//从消息队列接收消息时用于判断的消息类型
	long msgtype;	//具体的消息类型
	unsigned char text[QUEUE_MSG_LEN];//消息正文
};

#endif 

data_global.c

/********************************************
  	全局的互斥体声明
    全局的条件锁声明声明
    全局的id和key信息声明
    全局的消息队列发送函数声明
 ********************************************/
#include "data_global.h"
/*互斥量声明*/
pthread_mutex_t mutex_client_request,
        		mutex_refresh,
        		mutex_sqlite,
	        	mutex_transfer,
	        	mutex_fan,
	        	mutex_zigbee,
	        	mutex_buzzer,
	        	mutex_debug,
	        	mutex_camera,
	         	mutex_led;

/*条件变量声明*/
pthread_cond_t  cond_client_request,
        		cond_refresh,
        		cond_sqlite,
	        	cond_transfer,
	        	cond_fan,
	        	cond_zigbee,
	        	cond_buzzer,
				cond_led,
				cond_debug;
/*消息队列ID*/
int msgid;
/*共享内存ID*/
int shmid;
/*信号灯集ID*/
int semid;

key_t key; //msg_key
key_t shm_key;
key_t sem_key;

/*所有房间环境信息*/
struct env_info_client_addr  sm_all_env_info;
//发送消息队列
int send_msg_queue(long type,unsigned char text)
{
	struct msg msgbuf;
	msgbuf.type = 1L;
	msgbuf.msgtype = type;
	msgbuf.text[0] = text;

	if(msgsnd(msgid,&msgbuf,sizeof(msgbuf) - sizeof(long),0) == -1){
		perror("fail to msgsnd type2");
		exit(1);
	}

	return 0;
}

mian.c

#include "data_global.h"

void release_pthread_resource(int signo);
/*互斥量声明*/
extern pthread_mutex_t mutex_client_request,
        		mutex_refresh,
        		mutex_sqlite,
	        	mutex_transfer,
	        	mutex_fan,
	        	mutex_zigbee,
	        	mutex_buzzer,
	        	mutex_debug,
	         	mutex_led;
/*条件变量声明*/
extern pthread_cond_t  cond_client_request,
        		cond_refresh,
        		cond_sqlite,
	        	cond_transfer,
	        	cond_transfer,
	        	cond_fan,
	        	cond_zigbee,
	        	cond_buzzer,
	        	cond_debug,
	         	cond_led;

/*消息队列ID*/
extern int msgid;
/*共享内存ID*/
extern int shmid;
/*信号灯集ID*/
extern int semid;

pthread_t  id_client_request,
		   id_refresh,
		   id_sqlite,
		   id_transfer,
		   id_fan,
		   id_buzzer,
		   id_led;		

int main(int argc, const char *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_fan,NULL);
	pthread_mutex_init(&mutex_zigbee,NULL);
	pthread_mutex_init(&mutex_buzzer,NULL);
	pthread_mutex_init(&mutex_debug,NULL);
	pthread_mutex_init(&mutex_led,NULL);
	
	//等待接受信号,信号处理函数
	/*收到终止信号,释放线程资源
		SIGINT----CTRL C
		release_pthread_resource----释放线程资源函数
	*/
	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_fan,NULL);
	pthread_cond_init(&cond_zigbee,NULL);
	pthread_cond_init(&cond_buzzer,NULL);
	pthread_cond_init(&cond_debug,NULL);
	pthread_cond_init(&cond_led,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_fan,	NULL,pthread_fan,NULL);  	
	pthread_create(&id_buzzer, NULL,pthread_buzzer,NULL);	 
	pthread_create(&id_led,	NULL,pthread_led,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_fan,NULL);				printf ("pthread5\n");
	pthread_join(id_buzzer,NULL);			printf ("pthread6\n");
	pthread_join(id_led,NULL);				printf ("pthread7\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_fan); 
	pthread_mutex_destroy (&mutex_zigbee); 
	pthread_mutex_destroy (&mutex_buzzer); 
	pthread_mutex_destroy (&mutex_debug);  
	pthread_mutex_destroy (&mutex_led);   

	/*释放条件变量*/
 	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_fan);
 	pthread_cond_destroy (&cond_zigbee);
 	pthread_cond_destroy (&cond_buzzer);
 	pthread_cond_destroy (&cond_debug);
 	pthread_cond_destroy (&cond_led);

	/*回收线程———线程分离*/
	pthread_detach(id_client_request);
	pthread_detach(id_refresh);
	pthread_detach(id_sqlite);
	pthread_detach(id_transfer);
	pthread_detach(id_fan);
	pthread_detach(id_buzzer);
	pthread_detach(id_led);

	printf("all pthread is detached\n");
	/*删除消息队列*/
	msgctl(msgid, IPC_RMID, NULL);
	/*删除共享内存*/
	shmctl(shmid, IPC_RMID, NULL);
	/*删除信号灯*/
	semctl(semid, 1, IPC_RMID, NULL);	 

	exit(0);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值