MCU驱动架构的初探究

news/2024/9/20 23:28:09/文章来源:https://www.cnblogs.com/huajchen/p/18400272

Handler层

什么是Handler层

:Handler是将所有的资源聚集到一起的一层,包括用到的HAL硬件,队列,信号量,锁),包括挂载哪个硬件设备;

以温湿度传感器为例,handler结构体
typedef struct bsp_temp_humi_xxx_handler
{//底层driver需要的接口timebase_interface_t *timebase_interface;iic_driver_interface_t *iic_driver_interface;yield_interface_t *yield_interface;//RToS传入的接口temp_humi_handler_os_interface_t *os_interface;//自身的接口//底层driver实例bsp_aht21_driver_t *paht21_instance;//event队列句柄void *event_queue_handle;//是否完成初始化bool inited;//获取温度时tick值uint32_t last_temp_tick;//获取湿度时tick值uint32_t last_humi_tick;
}bsp_temp_humi_xxx_handler_t;

image-20240906150914377

为什么需要Handler层

  1. 分层,handle它向上层屏蔽底层的硬件,向下搜集接口,直接操作硬件是非常敏感的,APP不去直接调用HAL的驱动,比如在某一个地方阻塞了,
  2. 容灾,比如我的驱动出现错误掉线了,不在App去处理,在Handler去处理。
  3. 我可以在内部维护温度数据。之前十秒内采集的温度就新鲜度都没有过期,那么这个温度明显是可以反复使用的。这个事件的逻辑处理,它有点像APP。因为它不属于完全的硬件操作。它就不能归类到这个HAL。
  4. APP跑业务逻辑要我们以前叫什么蜻蜓点水。一定要快。假如说我们单核的话,它可能快,你看起来就已经挺明显了,是多核。它可能读取温湿度,它通过我们的异步IO。他就给另外一个和。给IIC外设发了一个信号,然后他就立马离开了。

调用流程

先构造(注册),再初始化。

  1. RTOS启动void temp_humi_handler_thread(void *argument)作为线程的入口函数,传入temp_humi_handler_all_input_arg_t作为参数,初始化bsp_temp_humi_xxx_handler_t结构体。并且该线程不断读取队列中的event结构体,根据里面的参数去获取温度或湿度,数据新鲜度。
  2. App通过传入temp_humi_xxx_event_t结构体来调用bsp_temp_humi_xxx_read来将event传入队列中,温度获取线程根据event中的信息将需要的数据更新,并调用回调函数。
/*handler对外提供的接口*/
/*thread调用函数*/
void temp_humi_handler_thread(void *argument);/*handler构造函数*/
uint8_t bsp_temp_humi_xxx_handler_inst(bsp_temp_humi_xxx_handler_t *handler_instance,temp_humi_handler_all_input_arg_t *input_arg);/*读取温湿度*/
int8_t bsp_temp_humi_xxx_read(temp_humi_xxx_event_t *event);typedef struct
{float*temperature;//温度float*humidity;//湿度uint32_t lifetime;//数据新鲜度uint32_t timestamp;//发送事件时间戳temp_humi_xxx_event_data_type_t type;//数据类型,温度、湿度、两者void(*pfcal1back)(float*,float*);//回调函数
}temp_humi_xxx_event_t;//线程入口函数
void temp_humi_handler_thread(void *argument)
{ log_d("temp_humi_handler_thread start");float temp =0;float humi =0;temp_humi_handler_all_input_arg_t *input_arg = NULL;temp_humi_xxx_event_t event;int ret =0;uint32_t tim =0;//aht21实列bsp_aht21_driver_t bsp_aht21_driver;if(NULL == argument){log_e("temp_humi handler_thread agrument is NULL");}input_arg =(temp_humi_handler_all_input_arg_t *)argument;//构造nandler实例temp_humi_xxx_handler_instance.paht21_instance = &bsp_aht21_driver;bsp_temp_humi_xxx_handler_inst(&temp_humi_xxx_handler_instance,input_arg);for(;;){//1.读取事件队列ret = temp_humi_xxx_handler_instance.os_interface->os_queue_get(temp_humi_xxx_handler_instance.event_queue_handle,&event,MY_MAX_DELAY);log_d("get ret=%d\r\n",ret);//2.重新测量温湿度if(!(get_temp_humi(event,&temp,&humi))){//Data Correct}else{//Data error}//3.执行回调函数event.pfcallback(&temp,&humi);//temp_humi_xxx_handler_instance.os_interface->os_delay_ms(1000);//int numerator 10;//unsigned int denominator (unsigned int *)0xffffffff;//int resul//result numerator /(*denominator);}
}

什么是高内聚,低耦合?

裸机:大家有很多的全局变量。1.取名,2,随机分布在全局的Map文件上,3,CPU不会被高效利用。

操作系统:1.高内聚:相关函数分布密集,资源集中于特定的线程。2.能够在写代码时,复用框架能够将编程习
惯固化下来,在编程过程中就提前杜绝一些问题。3.能够为未来在程序上做修改提供可嵌入的接口

  1. 高内聚(High Cohesion)

    • 内聚是指一个模块内部各个部分之间的关联程度。高内聚意味着模块内的组件都是为了完成一个单一的功能或任务而紧密协作的。
    • 高内聚的模块通常更容易理解和维护,因为它们具有明确的目的和职责。
    • 高内聚可以通过以下方式实现:
      • 确保模块只处理与它直接相关的数据和操作。
      • 减少模块内部的复杂性,使得模块的行为和功能容易预测。
      • 避免在模块内部进行过多的决策或条件判断。
  2. 低耦合(Low Coupling)

    • 耦合是指不同模块之间的相互依赖程度。低耦合意味着模块之间的依赖关系尽可能的少,每个模块相对独立,对其他模块的了解和使用尽可能的少。
    • 低耦合有助于提高系统的可维护性和可扩展性,因为修改一个模块不太可能影响到其他模块。
    • 实现低耦合的方法包括:
      • 使用抽象和接口来定义模块之间的交互,而不是直接依赖具体的实现。
      • 减少模块之间的数据共享,使用参数传递或返回值来交换数据。
      • 避免循环依赖,确保模块之间的依赖关系是单向的。

函数指针定义的接口相较于包含头文件它的优势在哪里?

函数指针定义的接口相较于直接包含头文件的方式,具有以下优势:

  1. 抽象化:函数指针提供了一种抽象的接口,允许在不同的实现之间进行切换,而不需要修改使用接口的代码。这使得代码更加灵活,易于扩展。
  2. 解耦:使用函数指针可以减少模块之间的直接依赖,从而降低耦合度。模块不需要知道具体的实现细节,只需要知道如何调用接口。
  3. 模块化:通过函数指针,可以将接口和实现分离,使得代码更加模块化。这样可以更容易地重用代码,并且可以独立地开发和测试各个模块。
  4. 易于测试:在单元测试中,可以使用函数指针来注入模拟(mock)或桩(stub)实现,以测试代码在不同情况下的行为,而不需要依赖于实际的实现。
  5. 减少编译依赖:不需要包含实现的头文件,可以减少编译时的依赖,加快编译速度,并且减少因头文件更改导致的重新编译。
  6. 支持多态:在面向对象编程中,函数指针可以支持多态行为,允许通过基类指针调用派生类的方法,这在设计模式如策略模式中非常有用。
  7. 安全性:在某些情况下,使用函数指针可以提高代码的安全性,例如,通过限制对特定函数的访问,或者在调用函数之前进行权限检查。
  8. 性能优化:在某些情况下,使用函数指针可以提供性能优化的机会,例如,通过跳过某些不常用的代码路径,或者通过直接调用优化后的函数实现。

函数指针定义的接口提供了一种灵活、解耦和模块化的方法来设计软件系统,有助于提高代码的可维护性和可扩展性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/793087.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Hutool技术Excel表格导出

今天分享一下基于Hutool技术Excel表格导出,我们先看看导出Excel表格的样子第1步:引入maven依赖<dependencies><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.3.3</version></…

jekins--- 通过jekins执行远程机器的shell脚本

jekins和脚本部署的不是在同一个机器,简单的来说说如何用jekins通过SSH连接执行远程机器的shell脚本 1:简单的看一下脚本的内容,自己写的一个简单的测试脚本,执行了就会打印一个脚本已执行成功在日志中#!/bin/bash# 日志文件路径 LOG_FILE="/dongguangshu/logfile.log…

[C++ Daily] 何时调用copy构造与copy赋值

<Effective C++>:"如果一个新对象被定义,一定会有个构造函数被调用,不可能调用赋值操作.如果没有新对象被定义,就不会有构造函数被调用,那么当然是赋值操作被调用."结果:

速通spring与mybatis

Spring 1.什么叫线程安全:多个线程访问一个对象时,不需要额外的调度与交替执行也不需要额外的同步,调用这个对象的行为都可以获得正确的调度结果 如何保持线程安全:使用final修饰变量,让其只可读不可修改 使用局部变量,公共数据私有化:这样堆内读取的数据就会改成在栈内…

JS解析JSON数据到TABLE表格

效果图: 数据采用JSON,[{"时间段": "上午","XX小学班课表": [{"名称": "教师上班","时间": "8:00","星期一": "","星期二": "","星期三": "&q…

登陆微软账号,输入window密码后,提示「哎呀,出错了」

存在问题解决方案暂时关闭dai~Li 设置 账户 下滑,电子邮件和账户 添加Microsoft账户解决后的效果版权木有,侵权不究,欢迎转载

TDBC回顾 | 钛铂数据肖贝贝:TapData — 自主可控

7月,TapData CTO 肖贝贝出席“2024可信数据库发展大会”,分享了“TapData — 自主可控的实时数据平台”的主题演讲。本文为完整内容。2024年7月17日上午,“2024可信数据库发展大会”数据库生态与国际化分论坛在北京隆重召开。会上,深圳钛铂数据有限公司CTO肖贝贝重点与听众…

服务器时间同步

一、安装ntpddate #centos,redhat系列 yum install ntpdate#debian,ubuntu系列 apt install ntpdate二、在服务器都能联网情况下时间同步 #手动同步阿里云时间服务器时间 ntpdate ntp.aliyun.com 阿里云时间同步地址 ntp1.aliyun.com ntp2.aliyun.com ntp3.aliyun.com ntp4.ali…

D35XT120-ASEMI新能源专用D35XT120

D35XT120-ASEMI新能源专用D35XT120编辑:ll D35XT120-ASEMI新能源专用D35XT120 型号:D35XT120 品牌:ASEMI 封装:DXT-5 批号:2024+ 现货:50000+ 正向电流(Id):35A 反向耐压(VRRM):1200V 正向浪涌电流:450A 正向电压(VF):1.10V 引脚数量:5 芯片个数:5 芯片尺寸:…

高等数学 1.1 映射与函数

目录一、映射映射概念逆映射与复合映射二、函数函数概念函数的几种特性(1)函数的有界性(2)函数的单调性(3) 函数的奇偶性(4)函数的周期性反函数与复合函数反函数复合函数函数的运算初等函数基本初等函数初等函数双曲函数与反双曲函数 一、映射 映射概念定义 设 \(X\) ,…

rfc编写

rfc检索:https://www.rfc-editor.org/rfc-index.html rfc绘图:https://asciiflow.com/ 绘图后保存成ascii art: