为什么我不再在生产环境使用厂商 HAL 库

Evek Golden Lv4

(注:本文仅代表作者个人观点,不针对特定厂商,也不否认 HAL 对初学者的价值)

最近做 Code Review,看到一段代码我血压升高了:

1
2
// 简单的翻转 GPIO
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);

你可能会说:“这不是很标准吗?”
是的,标准。但你点开这个函数的定义看过吗?为了兼容各种奇形怪状的 MCU 系列,里面充满了用来判断 Instance 的 assert,充满了各种 if-else

对于一个只需 2 个时钟周期的寄存器操作(GPIOA->ODR ^= ...),HAL 库硬生生跑了几十个周期。

1. 抽象的代价 (Abstractions leak)

计算机科学有一句名言:“所有非平凡的抽象,在某种程度上都是有漏洞的。”

HAL 库试图把底层硬件屏蔽掉,这是美好的愿景。但现实是,硬件的差异性太大,根本屏蔽不掉。
比如 STM32F1 和 F4 的 DMA 控制器完全不同,HAL 库为了统一接口,搞出了极为复杂的结构体。结果是你即便用了 HAL,依然得去查 Reference Manual 搞清楚 DMA 请求映射。

既然都要查手册,我为什么不直接写寄存器呢?

2. 隐藏的 Bug

我是从一次 SPI DMA 传输死机事故中彻底对 HAL 库祛魅的。
官方提供的 HAL 库在处理 SPI 错误中断时,有一处逻辑错误,导致状态机卡死在 HAL_SPI_STATE_BUSY_RX。如果你不深入读它的源码,你根本不知道为什么 HAL_SPI_Transmit 突然就永远返回 BUSY 了。

代码是你自己写的,出了 Bug 也是你自己的。用了别人的库,Bug 就是不可控的黑盒。

3. 代码体积膨胀 (Bloatware)

现在的 MCU 动辄 1MB Flash,大家似乎不在乎代码大小了。
但在 OTA 场景下,代码越小,传输越快,升级失败风险越低。
我曾重构过一个 Bootloader,把 HAL 库全部换成 LL (Low Layer) 库和手写寄存器,固件大小从 32KB 缩减到 8KB。

4. 并非全盘否定

我反对的是在对性能、稳定性要求极高的量产代码中盲目依赖 HAL
对于以下场景,HAL 依然是神器:

  • **验证原型 (Prototyping)**:老板说明天就要演示,你赶紧用 CubeMX 拖拖拽拽搞定。
  • 复杂的 IP 核:如 USB、以太网。手写这些驱动太痛苦,且易出错,用官方库是明智的。

总结

作为工程师,我们追求掌控力。HAL 库像是自动挡车,方便;寄存器像是手动挡,虽累,但你能感受到引擎的每一次轰鸣。

  • Title: 为什么我不再在生产环境使用厂商 HAL 库
  • Author: Evek Golden
  • Created at : 2025-06-05 23:21:00
  • Updated at : 2026-06-12 08:57:02
  • Link: https://blog.cocodemo.uno/posts/hal9x0q/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments