近期,ST推出了全新的STM32CubeMX2工具,其配套的硬件抽象层也同步升级至2.0版本,官方称之为HAL2。
HAL,即硬件抽象层,位于操作系统内核与硬件电路之间,其核心目的是将硬件操作抽象化,方便开发者进行跨平台移植。

起初,笔者在体验STM32CubeMX2并生成初始化代码时,粗略地查看了生成的API(例如 HAL_GPIO_Init、HAL_GPIO_WritePin 等),感觉与旧版HAL库的API名称一致,并未深究源码细节,便以为HAL库的变化不大。
直到近期仔细阅读了官方文档并对比了源码,才发现两者存在显著差异。仅以STM32 C系列中的C0与C5的HAL库为例进行对比,就能发现许多不同。

其中,一个最明显的区别是:新的HAL2库(如STM32C5的库)直接调用了底层LL(Low-Layer)库的代码。
官方对此的描述是:HAL2(V2.0.0版本)带来了多项增强功能,包括运行性能和Flash空间占用方面的显著改进,并且与新的STM32CubeMX2完全兼容。这给人的感觉是,HAL2试图融合旧版HAL易于移植的特性与LL库高性能、低占用的优点。
API接口:名称相同,参数与实现不同
HAL2与旧版HAL的许多API函数名称相同,但参数列表和内部实现却截然不同。以 HAL_GPIO_Init 函数为例,通过对比可以发现,HAL2版本增加了状态返回值(类型为 hal_status_t),同时传入参数的方式也发生了变化。

因此,虽然API名称熟悉,但最新的HAL2库与旧版HAL库在源码层面并不兼容。


通过对相同外设的源码进行对比,差异几乎“一片红”,可谓千差万别。甚至一些代码对比工具都无法准确匹配同名API的代码块。为此,笔者不得不将特定的API接口(如 HAL_USART_Init)单独提取到其他文件中进行人工对比。
当然,源码的差异部分源于底层硬件的不同。为了更公平地进行比较,笔者特意选取了C系列(架构相近或同源)的库进行对比,重点仍是观察同名API的差异。

此外,笔者也跨系列对比了HAL库,发现C0和F4系列的旧版HAL在很多地方是相同的。这进一步印证了,HAL2并非基于旧版HAL的简单迭代,而是一次架构上的重大更新。
综合来看,结论非常明确:全新的STM32 HAL2库,在API接口和底层实现上与之前的HAL库完全不兼容。 这对于广大嵌入式开发者,尤其是长期使用STM32 C/C++ 生态的工程师而言,意味着在迁移到新工具链时需要仔细评估代码的适配工作。
对于这类底层驱动库的变更,你有何看法?是追求极致的性能与空间优化更重要,还是保持API的长期稳定性和向后兼容性更关键?欢迎在云栈社区参与讨论,分享你的实践经验。
|