知识卡片
硬件抽象层(HAL):让硬件成为实现细节,可以无限分层
内容
避开[[固件的重新定义由依赖关系与变更难度界定而非存储位置]]描述的目标硬件瓶颈(若没有清晰架构,代码只能在目标硬件平台上测试、严重拖慢开发),首先要把系统按硬件层、软件/固件层分开——硬件一定会随摩尔定律和技术进步而演进,嵌入式工程师不希望这种不可避免的硬件变动带来额外工作量;但软件与固件之间的分界线往往远不如代码与硬件之间的分界线清晰,需要专门定义得更清楚,这条分界线就是硬件抽象层(HAL,这个概念的历史甚至早于Windows)。HAL的存在是为上层软件提供服务,其API该按软件的实际需要量身定做而非照抄硬件寄存器:比如固件可以直接把字节存进闪存,但软件真正需要的只是保存和读取name/value对,不该关心这些信息到底存进了闪存、磁盘还是云端——HAL的作用正是把这类具体实现细节隐藏起来。更进一步的例子是一个接在GPIO位上的LED:固件可以直接操作GPIO位,HAL提供一个Led_TurnOn(5)这样偏低层的函数;但如果把抽象层次从硬件层提到软件/产品层,就要问这个LED到底代表什么——假如它代表电池电量不足,那么固件(或电路板支持包)负责提供Led_TurnOn(5),HAL则该提供Indicate_LowBattery()这样贴合应用语义的函数。这说明HAL该按应用程序的真实需要提供服务,系统的每一层内部还可以再嵌套许多层,与其说是固定的分层,不如说是一种无限分层模式——GPIO位的具体对应关系始终该是一个实现细节,与软件部分彻底隔离,依照整洁嵌入式架构构建的软件,应该能借助设计良好的HAL脱离目标硬件平台来测试。
参考来源
- 位置:《架构整洁之道》第29章《整洁的嵌入式架构》"分层""硬件是实现细节""不要向HAL的用户暴露硬件细节"(源文件:_epub-src/text/part0014_split_014.html)
- 结论依据:原文说明软件固件边界不如代码硬件边界清晰、需要HAL来划定,并用闪存存储name/value对、LED从GPIO位提升到Indicate_LowBattery两个例子说明HAL该按软件真实需要提供服务、可以无限分层,直接支撑本卡片结论。
- 原始内容:HAL的存在是为了给它上层的软件提供服务,HAL的API应该按照这些软件的需要来量身定做……而HAL则负责提供Indicate_LowBattery()函数。由此可见,HAL层是按照应用程序的需要来提供服务的……相对于之前的固定分层法,这里更像是一种无限分层模式。