news 2026/4/25 17:18:44

【RTOS】智能家居-中间层

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【RTOS】智能家居-中间层

驱动和适配层开发

顶层开发

1. 代码整体架构

主要承担 “顶层业务层” 和 “底层驱动层” 的桥梁作用,同时包含了环形缓冲区(RingBuffer)的基础操作 —— 整体分为两大核心模块:传感器数据采集任务、设备开关控制任务,以及通用的环形缓冲区工具函数。

中间层的核心价值:隔离业务层和驱动层,让业务层无需关心硬件细节,驱动层无需关心业务逻辑,提升代码可维护性;
通信方式:通过 MMC(内存控制块)+ 信号量(sem_req/sem_ack)实现跨任务 / 跨层级的同步与数据传递。

2. 核心模块拆解

2.1 全局变量与数据结构(通信载体)

// MMC控制块:管理“中间层-驱动层”的内存和同步(MMC=Memory Control Block) mmc_ctrl_stru midlayer_sample_tempraure_mmc_ctrl; // 温度采集MMC mmc_ctrl_stru midlayer_sample_bright_mmc_ctrl; // 亮度采集MMC mmc_ctrl_stru midlayer_switch_light_mmc_ctrl; // 灯光开关MMC mmc_ctrl_stru midlayer_switch_fan_mmc_ctrl; // 风扇开关MMC // 采集数据结构体:存储温度/亮度的原始数据(中间层<->驱动层共享) midlayer_sample_temprature_stru midlayer_sample_temprature_values; midlayer_sample_bright_stru midlayer_sample_bright_values; // 开关控制结构体:存储灯光/风扇的开关状态(中间层<->驱动层共享) midlayer_switch_light_stru midlayer_switch_light_sw; midlayer_switch_fan_stru midlayer_switch_fan_sw; // FreeRTOS任务句柄:用于任务管理(挂起/恢复/删除等) TaskHandle_t MidLayer_Sample_Process_Task_Handler; TaskHandle_t MidLayer_Switch_Process_Task_Handler;

mmc_ctrl_stru 是核心封装:用于管理任务 / 模块间的 “共享内存 + 同步信号量”,是跨模块通信的核心载体。

成员名类型作用
sem_reqSemaphoreHandle_t请求信号量:发起方释放此信号量,通知接收方 “有请求需要处理”
sem_ackSemaphoreHandle_t应答信号量:接收方处理完请求后,释放此信号量通知发起方 “处理完成”
p_shared_memvoid *共享内存指针:指向双方共用的数据缓存区(用于传递参数 / 结果)
shared_mem_byteint共享内存的字节大小:确保双方对内存的读写不会越界


midlayer_xxx_stru:定义具体的 “数据传输格式”,与mmc_ctrl_stru的p_shared_mem配合使用,实现结构化数据的传递。

结构体名成员名类型作用
midlayer_sample_temprature_strutempratureint存储温度采集结果(中间层与驱动层之间传递)
midlayer_sample_bright_strubrightint存储亮度采集结果(如 AP3216C 传感器的环境光数据)
midlayer_switch_light_strulight_swint存储灯光开关状态(0=关,1=开,用于控制 Modbus 继电器)
midlayer_switch_fan_strufan_swint存储风扇开关状态(与灯光逻辑一致)

上层模块(如业务层)通过mmc_ctrl_stru的sem_req发起请求,并将参数写入p_shared_mem;
下层模块(如中间层 / 驱动层)等待sem_req,读取p_shared_mem的参数后执行操作,再将结果写回p_shared_mem,最后释放sem_ack;

2.2 传感器采集任务:midlayer_sample_process_task_entry

核心作用:响应顶层业务的 “数据采集请求”,调用底层采集驱动获取温度 / 亮度数据,返回给业务层。

// 1. 等待业务层的采集请求(portMAX_DELAY=无限等待,直到信号量可用) xSemaphoreTake(busi_sample_mmc_ctrl.sem_req, portMAX_DELAY); // 2. 向驱动层发起温度采集请求(MMC_DELAY_TIME=请求超时时间) if(mmc_ctrl_require(&midlayer_sample_tempraure_mmc_ctrl, MMC_DELAY_TIME) == pdPASS) { // 3. 把驱动层的温度数据,拷贝到业务层的共享内存 ((busi_sample_stru *)(busi_sample_mmc_ctrl.p_shared_mem))->temprature = ((midlayer_sample_temprature_stru *)(midlayer_sample_tempraure_mmc_ctrl.p_shared_mem))->temprature; log_i("temprature : %d", ...); // 打印调试 } // 4. 同理处理亮度采集... // 5. 填充预留字段(为后续扩展传感器预留) ((busi_sample_stru *)(busi_sample_mmc_ctrl.p_shared_mem))->reserved[0] = 1; ((busi_sample_stru *)(busi_sample_mmc_ctrl.p_shared_mem))->reserved[1] = 2; ((busi_sample_stru *)(busi_sample_mmc_ctrl.p_shared_mem))->reserved[2] = 3; ((busi_sample_stru *)(busi_sample_mmc_ctrl.p_shared_mem))->reserved[3] = 4; // 6. 释放响应信号量,通知业务层:采集完成,数据已就绪 xSemaphoreGive(busi_sample_mmc_ctrl.sem_ack);

核心函数 mmc_ctrl_require:中间层向驱动层发起 “采集请求” 的封装,内部通常会:
把采集参数写入共享内存;
释放驱动层的信号量,触发驱动层执行采集;
等待驱动层的响应信号量,超时返回失败;
共享内存转换:(busi_sample_stru *)(p_shared_mem) 是强制类型转换,把通用指针转为业务层结构体指针,实现数据传递。

2.3 设备开关控制任务:midlayer_switch_process_task_entry

核心作用:响应顶层业务的 “开关控制请求”,调用底层开关驱动控制灯光 / 风扇,获取驱动层的执行反馈,返回给业务层。

与采集任务的差异:

// 1. 先把业务层的灯光状态,同步到驱动层的共享内存 ((midlayer_switch_light_stru *)(midlayer_switch_light_mmc_ctrl.p_shared_mem))->light_sw = ((busi_switch_stru *)(busi_switch_mmc_ctrl.p_shared_mem))->light_status; // 2. 发起灯光控制请求,驱动层执行“开/关”操作 if(mmc_ctrl_require(&midlayer_switch_light_mmc_ctrl, MMC_DELAY_TIME) == pdPASS) { // 3. 读取驱动层的执行反馈(比如继电器是否真的吸合),返回给业务层 ((busi_switch_stru *)(busi_switch_mmc_ctrl.p_shared_mem))->light_status = ((midlayer_switch_light_stru *)(midlayer_switch_light_mmc_ctrl.p_shared_mem))->light_sw; }

控制任务的核心差异:先 “下发控制指令”(业务层→驱动层),再 “读取执行反馈”(驱动层→业务层),确保控制指令被正确执行;
反馈机制:避免 “业务层发了开灯光命令,但驱动层执行失败” 的情况,提升可靠性。

2.4 中间层初始化函数:midlayer_init

核心作用:初始化底层驱动,创建中间层任务,是中间层的入口函数。

void midlayer_init() { SwitchDrv_Init(); // 初始化开关驱动(灯光/风扇) SampleDrv_Init(); // 初始化采集驱动(温度/亮度) // 创建采集任务:栈大小128字,优先级2 xTaskCreate(midlayer_sample_process_task_entry, "midlayer_sample_process_task", 128, NULL, 2, &MidLayer_Sample_Process_Task_Handler); // 创建开关控制任务:栈大小128字,优先级2 xTaskCreate(midlayer_switch_process_task_entry, "midlayer_switch_process_task", 128, NULL, 2, &MidLayer_Switch_Process_Task_Handler); }

__weak 修饰的驱动初始化函数:__weak void SwitchDrv_Init(); 是 “弱定义”,允许驱动层提供 “强定义” 的实现,若驱动层未实现则为空(避免编译错误);
任务栈大小:128 字(512 字节)

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/24 19:52:53

pq|dfs|快排

lc1985简单题 简单做上堆/快排也行按字符串长度降序、长度相同则按字典序降序排序数字字符串数组&#xff0c;返回第 k 大的元素。class Solution { public:string kthLargestNumber(vector<string>& nums, int k) {sort(nums.begin(), nums.end(), [](string s1, …

作者头像 李华
网站建设 2026/4/23 0:03:27

GLM-4.7 MiniMax M2.1 实测上线:AI Ping 喊你免费体验国产大模型 “硬实力”

【前言】国产大模型又上新 “战场” 了&#xff01;12 月 23 日&#xff0c;清程 AI Ping 平台正式开放GLM-4.7与MiniMax M2.1两款旗舰模型的免费实测 —— 这俩可是当前国产模型在 “工程交付” 与 “Agent 长效运行” 赛道的代表性选手&#xff0c;直接瞄准真实场景的 “长期…

作者头像 李华
网站建设 2026/4/16 9:12:13

python+vue美特超市进销存管理系统_91crh

目录 已开发项目效果实现截图开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01; 已开发项目效果实现截图 同行可拿货,招校园代理 pythonvue美特超市进销存管理系统_91crh 开发技术路线…

作者头像 李华
网站建设 2026/4/18 11:50:21

AI论文写作工具Top9:开题报告生成与降重功能详细测评

AI写论文平台排名&#xff1a;9个实测&#xff0c;开题报告论文降重都好用工具对比排名表格工具名称核心功能突出优势Aibiye降AIGC率适配高校规则&#xff0c;AI痕迹弱化Aicheck论文降重速度快&#xff0c;保留专业术语Askpaper论文降重逻辑完整性好秘塔写作猫智能降重结合语法…

作者头像 李华
网站建设 2026/4/19 0:20:07

9个AI论文辅助平台深度测评,开题报告生成和降重功能强大

AI写论文平台排名&#xff1a;9个实测&#xff0c;开题报告论文降重都好用 工具对比排名表格 工具名称 核心功能 突出优势 Aibiye 降AIGC率 适配高校规则&#xff0c;AI痕迹弱化 Aicheck 论文降重 速度快&#xff0c;保留专业术语 Askpaper 论文降重 逻辑完整性好 …

作者头像 李华
网站建设 2026/4/23 14:27:51

nvcr.io 登录方法

docker login nvcr.io用户是固定的&#xff0c;不是某个人的用户Username: $oauthtoken Password: NGC_API_KEY密码是NGC_API_KEY申请NGC_API_KEY方法&#xff1a;访问正确的位置&#xff1a;登录 NVIDIA NGC 官网。https://catalog.ngc.nvidia.com/进入个人设置&#xff1a;点…

作者头像 李华