单片机常用的软件架构
9种单片机常用的软件架构
分层架构

| 应用层 | APP | 数字电源状态机 | 备注 | ||||
| 中间件层 | MidComponent | t环形缓冲队列 | 算法:PID | 数据帧处理 | 通信接口 | 与硬件元关的/可然植性疆 | |
| 板级驱动层 | BSP | OLED | ADC | 电位器 | 电流 | 电压 | 相当于开发板的外部外设硬决 |
| 硬件抽象层 | Driver | HAL | 对硬件外设进行了封装 | ||||
| 物理硬件层 | 硬件 | 硬件 | CSDiI@woainizhongguo. |
BSP:板级支持驱动库
Board support package
MCU和板上外设器件(mpu6050) 的通信和交互过程
有时候分2种:
1) 在裸机(有限状态机)情况下,写的驱动程序
2)在操作系统下,写驱动程序
Core:mcu驱动程序
面向mcu进行编程,初始化MCU内部的外设(时钟、SPI 、IIC等),包含main.c 文件
Driver: 厂商SDK程序
MCU厂商和MCU内的CPU厂商提供的,用来CPU和偏上外设编程时的驱动库,一般由厂商提供
Middewares: 中间件
抽象程度很高、能在各个项目中安插通用的、LVGL、freeRTOS、数学库、傅里叶变换库
System:系统配置层
对系统进行整体宏定义
应用层
实现具体的应用逻辑
问题
单片机开发中,我对系统进行分层,具体分成3个层次,第一层应用层,第二层:bsp层,第三层,底层驱动,你觉得这样的分层架构如何,有其他的建议或者意见吗
城哥,你提出的三层分层架构——应用层、BSP层(Board Support Package)、底层驱动层——在单片机开发中是非常常见且合理的设计架构。这种分层方式有助于系统的模块化、可维护性和可扩展性。但为了确保架构的高效性、灵活性和可维护性,我们可以从以下几个方面探讨它的优缺点,并提出一些优化建议。
1. 架构概述
- 应用层(Application Layer):主要包含业务逻辑、用户接口以及系统功能的实现。
- BSP层(Board Support Package):封装与特定硬件板相关的支持包,提供系统初始化、硬件资源管理等功能,抽象底层硬件细节。
- 底层驱动层(Hardware Driver Layer):负责直接与硬件打交道的驱动程序,提供寄存器级的硬件访问。
2. 现有架构的优点
- 清晰的职责划分:这种分层设计使得应用逻辑、硬件支持和底层驱动三者之间界限明确。不同层次之间依赖关系清晰,便于开发和维护。
- 可移植性:通过BSP层将硬件相关性封装,应用层和底层驱动层的代码可以更容易地移植到不同的硬件平台。
- 可扩展性:增加新硬件时,只需修改或添加BSP层和底层驱动层,应用层不需要大的改动。
- 复用性:BSP和底层驱动可以复用,不同项目之间能够共享相同的硬件抽象和驱动层代码。
3. 可改进和优化的方向
A. 中间层(Hardware Abstraction Layer, HAL)
建议在BSP层和底层驱动层之间增加一个HAL层(硬件抽象层),进一步解耦应用层和底层驱动层的关联,增加系统的灵活性和硬件抽象能力。
- 作用:HAL层提供更高层次的硬件抽象,屏蔽硬件的具体实现细节,将底层驱动与应用层完全隔离开。应用层只需要调用HAL层提供的接口,而无需关注硬件寄存器的具体实现。
- 优势:
- 增强移植性:应用层代码对硬件平台的依赖性进一步降低,甚至不需要感知特定硬件的存在。
- 增加复用性:不同硬件平台共享相同的应用层和BSP层代码,只需适配HAL接口即可。
- 简化开发:HAL层提供的高层抽象接口(如I2C、SPI、UART等)可以简化开发人员对底层硬件的理解要求。
B. 底层驱动优化
- 模块化驱动设计:将底层驱动按功能模块化。例如,把UART、I2C、SPI、ADC等每个外设的驱动设计成独立模块,避免相互耦合。同时在每个模块中明确其初始化、读写、关闭等接口。
- 驱动配置灵活性:通过配置文件(如头文件或配置工具)对不同硬件进行灵活配置,而不是硬编码在驱动代码中。这可以提高驱动的通用性和可维护性。
C. BSP层的职责优化
在BSP层设计时,可以进一步明确其职责,使其不仅仅是硬件的支持包,还应包含:
- 启动代码(Startup Code):负责系统启动、初始化堆栈和寄存器、设置中断向量表等。
- 硬件资源管理:如时钟配置、GPIO初始化、外设映射等。
- 中断管理:处理全局中断控制,管理不同模块的中断服务函数。
D. 引入调度机制(RTOS支持)
如果项目复杂度较高,建议引入一个实时操作系统(RTOS)层来调度任务。RTOS可以作为应用层和BSP层的扩展,提供任务调度、资源管理和同步机制。
- 优势:
- 多任务支持:通过RTOS可以轻松实现多任务调度和并发操作。
- 时间片轮转:提供精确的任务执行时间控制。
- 系统资源管理:如信号量、互斥量、队列等资源管理,简化应用层的开发。
4. 方法论与建议
1. 接口定义与抽象
无论在哪个层次设计,接口设计是重中之重。确保每个层次之间的接口尽量保持通用和简洁,不暴露底层细节。这可以提高代码的可读性和维护性。常见的做法包括:
- 定义统一的API接口。
- 使用设计模式(如工厂模式)动态加载和初始化不同模块。
2. 面向对象编程思想
虽然C语言本身不是面向对象语言,但在嵌入式开发中可以引入面向对象的设计思想,如:
- 使用函数指针和结构体模拟多态性。
- 在驱动层实现接口结构体,提供开放封闭原则的设计,使得系统在增加新设备时不影响现有代码。
3. 动态配置与静态配置结合
- 静态配置:系统的一些基础设置如时钟、外设初始化等可以在编译时通过宏定义或配置工具设定。
- 动态配置:如应用层的功能参数(模式、定时、速度等)可以在运行时动态调整,提升系统的灵活性。
5. 总结与建议
你的三层架构已经非常符合嵌入式系统的设计要求,应用层、BSP层、底层驱动层的划分有助于系统的模块化和可移植性。为了进一步优化,你可以考虑:
- 在BSP层和驱动层之间增加HAL层,增强硬件的抽象能力和系统灵活性。
- 优化驱动层的设计,使其模块化并增强配置灵活性。
- 如果系统复杂性较高,考虑引入RTOS,实现任务的实时调度与管理。
这些优化措施能够进一步提高系统的移植性、可维护性和复用性。
如有具体设计需求或需要讨论的代码细节,随时欢迎继续探讨!
参考
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐



所有评论(0)