在嵌入式开发中,我们总被教导“从底层做起”。但随着生态的发展,真的每个人都需要写汇编、操寄存器吗?本文从实战角度出发,聊聊“造轮子”与“用轮子”的真实价值。
抽象分层:从应用到机器码
嵌入式开发可以分为多个抽象层级,从高到低依次是:
- 应用层:业务逻辑、控制策略、状态机,实现系统功能,关注模块划分与接口对接。
- HAL 层(硬件抽象层):由 MCU 厂商提供的驱动库,基于寄存器封装,实现跨平台可移植性和一致性。
- 标准外设库:控制更精细,可根据数据手册对寄存器逐位配置,兼具效率与灵活性。
- 寄存器级编程:对 MCU 寄存器直接操作,实现最高控制自由度,常用于性能敏感或资源受限场合。
- 汇编语言:适用于启动流程(如 Reset Handler)、上下文切换(RTOS 的 SVC/ PendSV)、中断入口等场景。
- 指令集层:对应 CPU 架构(如 ARM Cortex-M 的 Thumb 指令集),由编译器生成,一般不直接编写。
开发者在这些层级之间的选择,决定了系统的可维护性、效率与可靠性。
ST:用 HAL 库铺设自己的帝国
ST HAL 库与 CubeMX 工具链共同构成了一整套开发生态,它的优势并不只是代码,而是“一站式工程构建体系”:
自动代码生成:CubeMX 可根据外设配置自动生成初始化代码,减少配置错误。
平台统一抽象:不同系列(如 STM32F1 / F4 / H7)使用相似的 API,开发人员只需关注逻辑迁移。
稳定可靠:ST 官方 HAL 库经过广泛测试,包含典型应用场景,异常边界处理完善。
社区支持强:优快云、GitHub、STM32CubeIDE 论坛均有大量实战案例。
这些使得 ST 的 HAL 不只是“轮子”,更是“标准化道路”,加速了产品工程化的实现。
标准库开发者:其实也都在“封装轮子”
早期开发者使用 STM32F10x_StdPeriph_Lib 等标准外设库开发时,往往会自行封装 GPIO、USART、DMA 接口。
然而,标准库存在的问题在于:
缺乏平台抽象层:移植时需要重新配置宏定义、时钟结构等内容。
功能覆盖有限:许多新外设(如 FDCAN、LTDC)并未提供对应标准库支持。
风格多样化:团队成员封装习惯不同,降低可读性与协作效率。
虽然标准库更轻量,但在实际产品开发中,没有统一规范的封装往往比使用 HAL 更容易出错。
理解“轮胎”,不等于你要制造“轮胎工厂”
我们当然要理解底层:
- ARM Cortex-M 的异常模型(NVIC、HardFault、PendSV)
- SysTick 与中断优先级控制的细节(抢占/响应优先级)
- MMIO(Memory-Mapped IO)机制与总线结构
- 启动流程中的 _startup、堆栈初始化、链接脚本(Linker Script)
但这不是为了让你每天重写这些内容,而是为了:
- 出错时能快速定位问题源头
- 在 HAL 提供的抽象不满足需求时,能有手动补位的能力
- 能基于已有轮子构建更稳健的系统
专业人员研究轮胎是为了造更好的车,而非让每个人都从轮胎开始重新制造。
专业分工是工业化的标志,不是妥协
工业化软件开发强调模块解耦、团队协作、工程效率。不是每个人都要写启动代码,就像不是每个工程师都需要开发操作系统内核。
高效的嵌入式开发者,应该具备如下能力:
- 在 HAL 不能满足需求时,能深入寄存器级调试
- 能设计良好的任务划分与模块接口
- 熟悉 如FreeRTOS、lwIP、USB Stack 等基础组件使用
- 能结合 CubeMX 等工具 实现快速原型验证
- 能写出符合 MISRA-C、IEC 62304 等标准的高可靠性代码(特别是医疗、汽车、工控领域)
而这些能力的基础,是“理解底层 + 善用工具 + 系统思维”。
结语:不造轮子,才能跑得更远
掌握底层,是为了遇到问题能排查;用好抽象,是为了更高效开发。
如果说造轮子是一种技术实力的体现,那会用好轮子、选对轮子、在轮子之上造车造飞机,就是更高层次的智慧。
别让“技术洁癖”绑架了项目目标。
你该知道怎么造轮子,但你不需要天天造轮子。
作者:Jafi