基于mcu的一种分层软件架构

本文提出一种基于MCU的分层软件架构方法,通过在具体应用与硬件间加入中间层,封装硬件操作,实现软件灵活性提升。即使硬件变化,仅需修改中间层,保护应用程序免受大量改动。

基于mcu的一种分层软件架构(一)

1、写在前面

先来个图:

经过了一段时间的琢磨与思考。借鉴操作系统的分层原理,也搞出来了一种mcu的层状软件结构。好了,不说虚的啦。所有的一些方法和思想,都是对经历痛点的思考后,在人类智力范围内,被捣鼓出来,用来解决或是减弱痛点的。否则就是形而上了,没有意义。

 说说把它弄出来的初衷吧。大前提,所有的电子产品在初期研发、迭代升级阶段,都会有软件或是硬件的修改(当然,本文仅限于带mcu产品哈)。修改软件,可能是为了提高功能、定制功能等等;修改硬件,可能是为了优化成本、提高硬件稳定性,有时甚至会修改mcu。如果没有一个合适的软件结构,那我们一定会各种改改改了;更有甚者,硬件改变后,软件要推翻重做,哈哈,那个苦呀。基于上述痛苦,作为接受过九年义务教育我们,当然要与之斗争呀。

2、引子

下面说说带有mcu的产品基本构成吧(忽略结构和外观)。

 1、对于一个带有mcu的产品其硬件结构一般就是一个电路板,上面集成有mcu最小系统、led灯、lcd、继电器、WiFi模块、485串口、232串口、h桥、电源等各种东东。mcu呢是一个可编程的东西,它通过自身的io、并口、串口等各种接口与板子的其他设备产生联系。我们可以通过对mcu编程,间接控制板子上的各种设备。因为mcu的特殊性,我们可将硬件分为mcu和外围设两个部分。可以画个圈圈图,如图1所示。大圈圈代表整个板子,小圈圈代表mcu,大圈圈减小圈圈是板子上出mcu的外围设备。

图1 一般的硬件结构

 2、对于软件,我们通过mcu这个“中介”,根据一些功能逻辑进行编码,有序的控制各种设备。这样有序运动的硬件满足我们生活中的各种需求,形成形形色色的电子产品。如果没有细分软件结构。如图2所示,就是右边的代码就是我们所说的软件,自己构成的一大坨(具体是啥样呢,可能是一个带有合理架构的有序整体;也可能是混乱的夹杂各种全局变量寄存器操作;也可能里就一个.c文件一个main函数构成撑起了整个业务逻辑;当然还有,自己脑补吧)。

图2 产品整体组成

在这里,我们可以看到我们前面所说的痛点。如果图2中右边的“代码”,在软件里mcu或是板子的具体寄存器操作与具体应用混合在一起。一旦左边的“大圈圈”里的某个东东改变了,那就有可能全局搜索“代码”部分,修改各个部分的具体操作。如果没有合理的架构,回望过去尽是汗水加泪水呀!!!

我们的痛点可以描述为这样,即:硬件发生了,会带来软件的大量修改。

3、分层抽象

第一步抽象分层:

为了解决上述问题,可以对硬件加以抽象,在具体应用和硬件之间加入一个中间层,该中间层的任务是将具体的硬件操作加以封装,一旦硬件修改,仅仅修改中间层就可以了。那么软件就可以构成了一个简单的层状结构了,如图3所示。中间层在这里我们叫做“产品的硬件抽象”,具体应用是“应用程序”。

图3 带有中间层的软件架构

采用该结构的后果:硬件修改后,我们可以不必去修改具体的应用程序,只需将对应的“硬件抽象”的实现修改就好了。这样我们的程序是不是更加灵活了。

当然,使用该操作也是有一定约定的;即应用程序,不允许调用处“产品硬件接口抽象”之外的任何板子上的操作,否则,该结果就会被打乱,脱离的初衷。

第二步抽象分层

我们知道,板子的硬件构成是带有一个小圈圈的大圈圈。mcu(小圈圈)本身往往有很多外设接口(串口、并口,gipo,ad)用于与板的其他设备进行交互。这些“外设接口”代码量也往往比价大,且很多要操作寄存器,如果和mcu外围设备的编码夹杂在一起,一旦硬件修改,从mcu到具体外设都是需要大量修改的;更糟糕的如果mcu修改啦,整个硬件部分的代码都是需要修改的。就此,可进一步抽象分层。如图4所示。将硬件部分,如图实际硬件那样分为两层,这样就构成了三层结构。

采用该结构的后果:硬件修改后,我们可以不必去修改具体的应用程序,只需将对应的“硬件抽象”的实现修改就好了。这样我们的程序是不是更加灵活了;同样在mcu改变时,使得硬件相关代码部分修改达到最小化。更加灵活。

图4 三层结构

本文是为了介绍,这个分层架构方法,并不是介绍具体实施的。所以呀,可根据具体经验发挥各种编程技巧。这里介绍,该结构在实施是需要具体注意的概念,以免违反初衷。

1、该分层架构是由MCU接口抽象、产品的硬件抽象、和应用程序三个层次;

2、mcu接口抽象、定义mcu各个外设访问的接口属性和操作。切记是定义好的、标准化后的。可以自己标准化也可以根据主流架构进行标准化(比如st厂家的hal库、外设标准库)。

3、“产品的硬件抽象”大部分形式上是对板子上各个硬件属性和操作进行标准的定义。但是,切记该层是“硬件抽象”,即根据产品的具体性质,标准化的“抽象硬件”,可能会存在一个“抽象硬件”调用使用多个实际硬件才能实现,也有可能一个实际的硬件可以实现多个抽象硬件(这个抽象很重要,该层的核心,其模块定义直接关系到应用的可扩展性、效率)。

4、不允许跨层操作,如果必须的话,就在中间层提供接口进行传递。例如应用层要访问“mcu”自带的“看门狗”,那么就在“产品的硬件抽象”层添加“看门狗模块”,该模块调用mcu的“看门狗”。(当然这也是分层软件的弊端之一,前期的工作量会很大,不过分层的效益是随时间增加的,而这一弊端是一个初期的静态弊端,长期来看,利大于弊的)。

<think> 嗯,用户这次想了解嵌入式软件分层架构的介绍。从对话历史看,用户之前已经提供了三个相关引用资料,虽然标注了"引用内容仅供参考",但核心要点很清晰:分层设计的关键在于模块化、硬件抽象和资源优化。 用户可能是嵌入式领域的初学者或中级开发者。ta没有直接提问具体技术细节,而是要求"介绍",说明需要基础性但体系化的解释。考虑到嵌入式领域的特性,应该强调分层架构如何解决实际工程问题(比如移植困难、耦合度高),而不是单纯罗列理论。 从引用材料看,有几个关键点必须覆盖: 1)分层架构的核心设计原则(硬件无关性、单向依赖等) 2)典型分层结构(推荐用五层模型,因为引用[2]提到且行业通用) 3)具体案例(引用[3]的STM32工程很典型) 需要特别注意避免术语堆砌。比如解释"单向依赖"时,应该像引用[2]那样用HAL库的例子说明——上层调用抽象接口,底层实现寄存器操作,这样业务代码就不需要知道具体硬件寄存器。 另外用户提供的引用[1]提到资源效率,这点在总结分层优势时需要单独强调。嵌入式系统内存往往只有几十KB,分层设计虽然增加函数调用开销,但通过避免冗余代码反而节省空间,这个辩证关系要说清楚。 最后生成的问题要引导用户深入:ta现在问架构介绍,下一步可能关心具体实现(如怎么定义接口)或优化方向(如平衡性能和分层深度),所以问题列表里要包含这些维度。 </think> 嵌入式软件分层架构是一种将系统划分为多个独立层次的设计方法,旨在提升代码的可维护性、可移植性和可扩展性。以下是核心要点及设计原则: --- ### **分层架构的核心设计原则** 1. **模块化与解耦** 每层职责明确且相互隔离,仅通过标准接口通信。修改硬件(如更换MCU型号)只需调整底层驱动,无需改动上层业务逻辑[^1][^3]。 **示例**:STM32的HAL库将寄存器操作抽象为`HAL_UART_Transmit()`等接口,应用层无需关心具体寄存器地址[^2]。 2. **硬件无关性** 上层代码(应用层、服务层)禁止直接操作硬件,必须通过**硬件抽象层(HAL)**访问设备。例如: ```c // 应用层调用抽象接口 display_show("Hello"); // 驱动层实现具体硬件操作 void display_show(char* text) { HAL_LCD_WriteString(text); // 调用HAL库 } ``` 当更换LCD屏时,仅需重写`HAL_LCD_WriteString()`,应用层代码不变[^1][^3]。 3. **资源效率优化** 在资源受限的嵌入式系统中(如有限RAM/ROM),分层需避免过度抽象。通常采用**编译时配置**(如宏定义开关外设驱动)而非运行时动态加载,减少内存开销[^1][^2]。 --- ### **典型五层架构模型** | **层级** | **职责** | **依赖关系** | |---------------|---------------------------------------|-----------------------| | **应用层** | 业务逻辑(如数据处理、用户交互) | 依赖服务层 | | **服务层** | 通用功能(协议解析、文件系统) | 依赖中间件层 | | **中间件层** | 系统服务(RTOS、网络栈) | 依赖驱动层 | | **驱动层** | 封装芯片外设操作(SPI/I²C/USB驱动) | 依赖硬件抽象层 | | **硬件抽象层**| 屏蔽硬件差异(提供统一寄存器访问接口) | 直接操作硬件 | > **依赖规则**:严格单向依赖,禁止跨层调用(如应用层不可直接访问驱动层)[^2]。 --- ### **分层架构的优势与挑战** - **优势** ✅ **可移植性**:同一应用层代码可移植到不同硬件平台(如STM32F4→STM32H7)[^3]。 ✅ **协作效率**:团队可并行开发各层(硬件工程师实现驱动,软件工程师开发业务逻辑)。 ✅ **维护成本低**:硬件迭代仅需更新底层,避免全系统重构[^1]。 - **挑战** ️ **性能平衡**:函数调用链增长可能增加开销,需避免过度分层(如实时性要求高的中断服务应简短)。 ️ **接口设计**:层间接口需稳定且通用,否则易导致重构成本上升[^2]。 --- ### **实战案例:STM32工程分层** ```plaintext Project/ ├── App/ // 应用层:main.c实现业务逻辑 ├── Service/ // 服务层:通信协议处理 ├── Middleware/ // 中间件层:FreeRTOS适配 ├── Driver/ // 驱动层:SPI_FLASH驱动 └── HAL/ // 硬件抽象层:stm32h7xx_hal_spi.c ``` 当从STM32F4迁移到H7系列时,仅需替换`HAL/`和`Driver/`目录,上层代码无需修改[^3]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值