目录
一、主流程设计
1、工厂模式结构体定义
(1)指令工厂 inputCmd.h
(2)外设工厂 controlDevices.h
二、外设框架编写
1、创建外设工厂对象bathroomLight
2、编写相关函数框架
3、将浴室灯相关操作插入外设工厂链表等待被调用
三、外设框架测试
1、配置IO口输出状态
2、将函数加入到controlDevices.h
3、main函数编写
四、编写完成后拷贝到树莓派运行
1、创建一个文件夹用于保存上面所编写的三个代码
2、查看使用的GPIO口位于第几个引脚
3、编译运行
一、主流程设计
#include <stdio.h>
int main(){
	//指令工厂初始化
	//控制外设工厂初始化
	//线程池
	
	return 0;
} 
1、工厂模式结构体定义

(1)指令工厂 inputCmd.h
struct InputCmd{
	char cmdName[128];//指令名称
	char cmd[32];//指令
	int (*Init)(char *name,char *ipAdresschar *port);//初始化函数
	int (*getCmd)(char *cmd);//获取指令函数
	char *log[1024];//日志
	struct InputCmd *next;
}; 
定义一个名为 `InputCmd` 的结构体,包含以下成员:
- char cmdName[128]:一个长度为128的字符数组,用于存储指令名称。
 - char cmd[32]:一个长度为32的字符数组,用于存储指令。
 - int (*Init)(char *name, char *ipAdress, char *port):一个初始化相关指令操作的函数指针,它指向一个返回值为整型,接受三个字符指针类型的参数(名称、IP地址、端口号)的函数。
 - int (*getCmd)(char *cmd):一个用于获取指令的函数指针,它指向一个返回值为整型,接受一个字符指针类型的参数(指令)的函数。
 - char *log[1024]:一个长度为1024的字符指针数组,用于存储日志信息。
 - struct InputCmd *next:一个指向 `struct InputCmd` 类型的指针,用于链表的连接。
 
(2)外设工厂 controlDevices.h
struct Devices{
	char devicesName[128];//设备名称
	int status;//状态:开&关
    int pinNum;//引脚号
	
	int (*open)(int pinNum);//打开设备
	int (*close)(int pinNum);//关闭设备
	int (*devicesInit)(int pinNum);//设备初始化
	int (*readStatus)();//读取设备状态
	int (*changeStatus)(int status);//改变设备状态
	struct Devices *next;
}; 
定义一个名为 `Devices` 的结构体,包含以下成员:
- char devicesName[128]:一个长度为128的字符数组,用于存储设备名称。
 - int status:一个整型变量,用于存储设备的状态(如开/关等)。
 - int pinNum:一个整型变量,用于存储设备的引脚号。
 - int (*open)(int pinNum):一个用于打开相关设备的函数指针,它指向一个返回值为整型、接受一个整型的参数(引脚号)的函数。
 - int (*close)(int pinNum):一个用于关闭相关设备的函数指针,它指向一个返回值为整型、接受一个整型的参数(引脚号)的函数。
 - int (*devicesInit)(int pinNum):一个用于初始化相关设备的函数指针,它指向一个返回值为整型、接受一个整型的参数(引脚号)的函数。
 - int (*readStatus)():一个用于读取设备当前状态的函数指针,它指向一个返回值为整型、无参数的函数。
 - int (*changeStatus)(int status):一个用于更改设备状态的函数指针,它指向一个返回值为整型,接受一个字符指针类型的参数(设备状态)的函数。
 - struct Devices *next:一个指向 `struct Devices` 类型的指针,通常链表的连接。
 
二、外设框架编写
以浴室灯模块为例
bathroomLight.c
1、创建外设工厂对象bathroomLight
struct Devices bathroomLight={
	.name="bathroomLight",
    .pinNum=你选择的引脚号,
	.open=bathroomLight_open,
	.close=bathroomLight_close,
	.devicesInit=bathroomLight_init,
	.changeStatus=bathroomLight_status
}; 
2、编写相关函数框架
int bathroomLight_open(int pinNum){
	
}
int bathroomLight_close(int pinNum){
	
}
int bathroomLight_init(int pinNum){
	
}
int bathroomLight_status(int status){
}
 
3、将浴室灯相关操作插入外设工厂链表等待被调用
sturct  Devices *addbathroomLightToDevicesLink(struct Devices *phead){
	if(phead==NULL){
		ruturn &bathroomLight;
	}else{
		bathroomLight.next=phead;
		phead=&bathroomLight;
		}
} 
三、外设框架测试
1、配置IO口输出状态
pinMode()和digitalWrite()都是WiringPi库的函数,要包含wiringPi.h头文件(我在controlDevices.h里面包含了)

bathroomLight.c
#include "controlDevices.h"
int bathroomLight_open(int pinNum){
	digitalWrite(pinNum,LOW);
}
int bathroomLight_close(int pinNum){
	digitalWrite(pinNum,HIGH);
}
int bathroomLight_init(int pinNum){
	pinMode(pinNum,OUTPUT);
	digitalWrite(pinNum,HIGH);
}
int bathroomLight_status(int status){
}
struct Devices bathroomLight={
	.devicesName="bathroomLight",
	.pinNum=1,
	.open=bathroomLight_open,
	.close=bathroomLight_close,
	.devicesInit=bathroomLight_init,
	.changeStatus=bathroomLight_status
};
struct  Devices* addbathroomLightToDevicesLink(struct Devices *phead){
	if(phead== NULL){
		return &bathroomLight;
	}else{
		bathroomLight.next=phead;
		phead=&bathroomLight;
	}
}
 
2、将函数加入到controlDevices.h
controlDevices.h
#include <wiringPi.h>
#include <stdio.h>
struct Devices{
	char devicesName[128];
	int status;
	int pinNum;
	
	int (*open)(int pinNum);
	int (*close)(int pinNum);
	int (*devicesInit)(int pinNum);
	int (*readStatus)();
	int (*changeStatus)(int status);
	struct Devices *next;
};
struct Devices *addbathroomLightToDevicesLink(struct Devices *phead);
 
3、main函数编写
(1)判断树莓派接口是否初始化成功

(2)将浴室灯模块加入到工厂模式的链表中等待被调用

(3)判断+实现

mainPro.c
#include <stdio.h>
#include <string.h>
#include "controlDevices.h"
struct Devices *findDevicesName(char *name,struct Devices *phead){
	struct Devices *tmp=phead;
	if(phead==NULL){
		return NULL;
	}else{
	while(tmp!=NULL){
		if(strcmp(tmp->devicesName,name)==0){
			return tmp;
		}
		tmp=tmp->next;
	}
	return NULL;
	}
}
int main(){
	if(wiringPiSetup()==-1){
		return -1;
	}
	
	
	struct Devices *pdevicesHead=NULL;
	pdevicesHead=addbathroomLightToDevicesLink(pdevicesHead);
	char *name="bathroomLight";
	struct Devices *tmp=findDevicesName(name,pdevicesHead);
	if(tmp!=NULL){
		tmp->devicesInit(tmp->pinNum);
		tmp->open(tmp->pinNum);	
	}
	return 0;
}
 
四、编写完成后拷贝到树莓派运行
1、创建一个文件夹用于保存上面所编写的三个代码

2、查看使用的GPIO口位于第几个引脚
我是用继电器进行测试


3、编译运行
小插曲

编译

运行后可以听见继电器“哒” 的一声

输入gpio readall后查看发现GPIO1已经变为OUT










![[ 一刷完结撒花!! ] Day50 力扣单调栈 : 503.下一个更大元素II |42. 接雨水 | 84.柱状图中最大的矩形](https://img-blog.csdnimg.cn/16624f0dbb754a7587572cd9629dba35.png)







