【编程之美】嵌入式项目分层 - 图1

嵌入式项目分层

(**1)硬件抽象层(HAL)  **实现对片内资源 (如定时器、ADC、中断、I/O等) 的通用配置,隐藏具体的SFR操作细节,为上层提供简单清晰的调用接口。嵌入式开发的核心就是芯片,它提供固定的片内资源(常用的有I/O,ISR,TIMER等,稍微好点的还有ADC,SPI等硬件资源,不需要芯片外围ADC采集芯片或模拟SPI)共开发者使用。而且它具有一个很重要的特点就是,不随项目的新增需求变动而变动。所以应将其作为最底层,为上层提供基础支持。

(2)硬件驱动层(HDL)
嵌入式开发基本都会使用片外资源,如AT24C02,W25Q128等常见的外围EEPROM芯片,需要SPI通信(硬件SPI或I/O模拟的SPI)发送相应指令驱动该芯片,实现该芯片能正常工作。因此驱动这部分的API函数实现程序即为硬件驱动层。即使换了MCU,也只需将调用过硬件抽象层的API函数替换即可。

(3)功能模块层(FML)  
通过调用 HAL,实现项目中所涉及到的各片外功能模块,隐藏具体的模块操作细节,并为上层提供简单清晰的调用接口。硬件抽象层和驱动层主要就是为功能模块层提供的,实现该项目需要的功能,比如KEY、LED和EEPROM等功能,其中LEY、LED基本调用硬件抽象层的API函数(更复杂的可能通过片外芯片获取/控制等,因此可能也需要使用硬件驱动层),EEPROM调用硬件驱动层的API函数,即使EEPROM芯片更换(AT24C02或W25Q128等),也不影响EEPROM之前编写含的功能代码程序(前提是AT24C02,W25Q128提供的API函数提供的是统一标准)。

(4)应用程序层(APL)  
通过调用 HAL 与 FML,实现最终的应用功能。
负责的就是功能模块的使用和之间的逻辑关系处理等等,比如用户交互界面应用程序可能需要KEY、LED、LCD等。
【编程之美】嵌入式项目分层 - 图2

硬件抽象层和硬件驱动层的主要区别

**
硬件抽象层使用的芯片内本身的资源(芯片手册都有介绍),而硬件驱动层使用的是芯片本身不存在的资源,而且需要编写相应代码才能实现的资源。

比如正点原子STM32中CAN使用的TJA1050芯片,CAN属于STM32的片内资源,TJA1050属于片外资源,但由于TJA1050不需要额外的代码就能通过STM32中CAN本身提供API函数正常 工作;因此可以认为TJA1050不属于硬件驱动层,而若使用TJA1041,则需要编写额外代码才能使正常工作才能使STM32中CAN本身提供API函数正常工作,因此可以将TJA1041归为硬件驱动层。

若不要分这么细,可以将硬件抽象层和硬件驱动层统一归为硬件抽象层。

功能模块层和硬件抽象层、硬件驱动层的主要区别


功能模块层是按照项目需求提取出来的功能,需要硬件抽象层和硬件驱动层的硬件支持才能实现,功能模块层根据项目的功能需求改变而改变,而硬件抽象层和硬件驱动层则是项目需求书中的功耗等硬件相关的需求变动而改变,当然,若子功能的增加而硬件不支持,则也需更换硬件驱动。

比如项目中的数据储存功能,硬件支持有AT24C02、W25Q128和芯片本身的FLASH,都可以支持数据储存功能,即使后期因为功耗或节约成本等问题,硬件的更换也不影响数据储存功能的实现(前提规划好标准规范的API函数定义)且避免了重写该功能代码所带来的各种问题,保证了该功能的稳定性。