基于ARM的智能灯光控制系统总结(3-主程序及全局数据结构)

主程序包含了全局数据结构定义、系统配置文件生成或加载、建立四个独立线程并运行。

一、全局数据结构类型

封装每个设备的属性形成设备结构体类型(包含了:设备名、设备号、连接状态、开关状态、指向的下一个设备指针等)

封装每个区域的属性形成区域结构体类型(包含了:区域名、组成区域的设备号数组、区域开关状态等)

总数据结构类型:将上面两个类型数组化,从而开辟了可包含多个设备及区域的内存空间

同时将各个硬件设备及网络设备的文件描述符(网络设备为accept后的套接字)集合起来形成设备描述符结构类型

定义数据结构类型的config.h文件如下:

#ifndef __SL2000_H_
#define __SL2000_H_

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>

#define CONFIG_FILE "sl2000.cfg"
#define ON	1
#define OFF 	0

//消息队列接受索引
#define TEMP_SMG_INDEX_BASE		10
#define WEB_SMG_INDEX 				2
#define WEB_UPDATE_SMG_INDEX		3
#define UPDATE_TIME_SMG_INDEX		4	

//系统设备类型定义
#define DEV_T_MAIN		1 //主控
#define DEV_T_SUB		2//分控
#define DEV_T_RAY		3//光线感应
#define DEV_T_PIR		4//红外感应
#define DEV_T_MIC 		5//声音感应
#define DEV_T_LIGHT1	6//灯光-继电器
#define DEV_T_LIGHT2	7//灯光-继电器
#define DEV_T_LIG_NET	8//网络灯光


#define MAX_DEV 	8//系统最大设备容量
#define MAX_AREA 	4//系统最大区域容量
#define MAX_NET 	2//系统最大连接的网络客户端


#define J1_OFF 	0x00
#define J1_ON	0X01
#define J2_OFF 	0X00
#define J2_ON	0X01

#define LIGHT_DEV 	"/dev/4418_light"	 //光线感应设备
#define MIC_DEV		"/dev/4418_mic"		 //声音感应设备
#define PIR_DEV 	"/dev/4418_hongwai"      //红外感应设备
#define RELAY1_DEV	"/dev/4418_relay1"	 //延迟开关1
#define RELAY2_DEV	"/dev/4418_relay2"
#define SEARCH_DEV 	"/dev/4418_search"   //5-3.3v电压转换设备

#define ID_BASE		1

struct node_info{
	int 	id;			//设备编号,由于本项目设备较少,一类设备也就只有一个,
						//故直接用设备类型来操作各个设备了
	char ip[16];  		//设备ip,暂且没用到
	char type;		//设备类型
};

struct dev_fd{
	int relay1_fd;
	int relay2_fd;
	int pir_fd;
	int mic_fd;
	int light_fd;
	int net_fd[MAX_NET];//存储accept后的套接字
};

struct sys_dev{
	char  name[16];		//设备名
	struct node_info node;	//节点信息
	char connect_sta;	//连接状态
	char join_sta;		//是否加入系统
	char sw_sta;		//开关状态
	int  delay;		//延时开关参数,我的项目中咱且没有用到
	char bind_dev;		//用于感应设备绑定特定的灯光设备
	struct sys_dev * next;  //指向下一个设备的指针,用于形成设备链表
};

struct sys_area{
	char name[16];
	char dev_id[MAX_DEV];  //组成区域的设备数组
	char sw_sta;
	char enable_flag;
};

struct sys_all{
	struct sys_dev  sys_dev[MAX_DEV];//系统设备存储列表
	struct sys_area sys_area[MAX_AREA];//区域列表
	int net_user[MAX_NET];//网络节点
	int count_dev;//连接设备计数
};

//消息队列用到的消息结构体类型
struct st_msg_req{
	long int index;
	char req;
};

int make_default_config(struct sys_all * dev);
int  save_dev(struct sys_all * dev);
int load_dev(struct sys_all * dev);

#endif

二、配置文件的生成或加载

系统第一次运行时,生成默认的配置文件,在系统结束时将全局数据结构中的数据写入配置文件中,再次启动时读取配置文件中数据至全局数据结构内存中。

这个功能就是一个简单的文件读写编程。包含在config.c中

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include "config.h"


int make_default_config(struct sys_all * dev)
{
 	int i;
	printf("Make default configuration.\n");
	memset(dev,0,sizeof(struct sys_all));
	dev->count_dev=1;//系统初始化时只有一个主控设备

	for(i=0;i<MAX_DEV;i++)
	{
		strcpy(dev->sys_dev[i].name,"Non named device");
		dev->sys_dev[i].node.id=0;
		dev->sys_dev[i].node.type=0;
		dev->sys_dev[i].connect_sta=OFF;//系统全部设备初始化无连接
		dev->sys_dev[i].sw_sta=OFF;//系统设备初始化全关闭
		dev->sys_dev[i].bind_dev=0;
		dev->sys_dev[i].delay=0;
		dev->sys_dev[i].next=NULL;
			
		dev->sys_area[i].enable_flag=0;		
	}
	dev->sys_dev[0].connect_sta=ON;
	strcpy(dev->sys_dev[0].name,"Main device");//初始化主控设备连接
	dev->sys_dev[0].join_sta=ON;
	dev->sys_dev[0].node.id=ID_BASE;
	dev->sys_dev[0].node.type=DEV_T_MAIN;
	
	return save_dev(dev);
	
}

void print_all(struct sys_all * dev)
{
	int i;
	for(i=0;i<dev->count_dev;i++)
		{
		printf("#%d#name=%s,id=%d,connect_sta=%d,sw_sta=%d,bind_dev=%d,delay=%d",
			i+1,dev->sys_dev[i].name,dev->sys_dev[i].node.id,dev->sys_dev[i].node.type,
			dev->sys_dev[i].connect_sta,dev->sys_dev[i].sw_sta,
			dev->sys_dev[i].bind_dev,dev->sys_dev[i].delay);
		}
	for(i=0;i<MAX_DEV;i++)
		{
		printf("#%d#name=%s,flag=%d,sw_sta=%d,dev_id=%d\n",
			i+1,dev->sys_area[i].name,dev->sys_area[i].enable_flag,dev->sys_area[i].sw_sta,dev->sys_area[i].dev_id[0]);
		}
}

int save_dev(struct sys_all * dev)
{
	FILE *fp;
	if(NULL==(fp=fopen(CONFIG_FILE,"wb"))){
		printf("Config file open null....\n");
		return -1;
		}
	printf("\nSave system data!\n");
	fwrite(dev,sizeof(*dev),1,fp);
	fclose(fp);
	return 0;
}

int load_dev(struct sys_all * dev)
{
	FILE * fp;
	memset(dev,0,sizeof(*dev));
	if(NULL==(fp=fopen(CONFIG_FILE,"rb"))){
		printf("[load_dev]fopen null ....\n");
		return make_default_config(dev);
		}
	if(sizeof(*dev) !=fread(dev,1,sizeof(*dev),fp)){
		printf("[load_dev+]sizeof error....\n");
		fclose(fp);
		return -1;
		}
	fclose(fp);
	return 0;
}

三、主程序(daemon.c)

就是建立全局变量、生产或打开配置文件用于初始化全局变量、建立四个线程并运行之

#include <pthread.h>
#include "config.h"
#include "sys_ipc.h"
#include "link_pro.h"
#include "dev_pro.h"
#include "net_pro.h"
#include "sw_pro.h"

//全局数据
struct sys_all g_dev[1];           //系统配置结构体全局变量
struct sys_dev *head_node =NULL;   //系统设备动态链表头指针
struct dev_fd g_dev_fd;            //系统设备文件描述符

int area_update_flag=0;

//系统初始化函数
int init_sys(void)
{
	int i;
	printf("init system...\n");
	load_dev(g_dev);//初始化g_dev
	head_node=stu_to_link(head_node);//创建设备结构链表头结点
	dev_print(head_node);//打印设备链表中的设备属性
	return 0;
}

//main 函数
int main()
{
	pthread_t pth_ipc,pth_dev,pth_sw,pth_net;

	init_sys();

	pthread_create(&pth_dev,NULL,dev_pro,NULL);
	pthread_create(&pth_ipc,NULL,ipcs_pro,NULL);
	pthread_create(&pth_sw,NULL,sw_pro,NULL);
	pthread_create(&pth_net,NULL,net_pro,NULL);

	pthread_join(pth_dev,NULL);
	pthread_join(pth_ipc,NULL);
	pthread_join(pth_sw,NULL);
	pthread_join(pth_net,NULL);

	return 0;
	
}


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值