3. 固件升级系统架构

固件升级系统并不是“把新固件写进 Flash”这么简单。一个可量产、可回滚、可远程维护的升级系统,通常由五个基本部分组成:Bootloader、应用程序、升级代理、通信接口与存储分区。它们各自承担不同职责,又通过明确的接口和状态约定协同工作。理解这套架构,是后续设计升级协议、分区表、回滚策略和产测流程的基础。

固件升级系统基本组成与数据流 通信接口 UART / USB / BLE / CAN 以太网 / 4G 升级代理 接收 / 校验 / 暂存 触发重启与状态上报 存储分区 Boot / Slot A / Slot B 参数区 / 日志区 Bootloader 启动决策 / 镜像搬运 完整性校验 / 回滚 应用程序 业务逻辑 / 版本号 升级请求发起 数据帧 写入 读取 跳转执行 升级请求 状态 关键交互说明 通信接口负责物理链路与协议解析,将固件包交给升级代理。 升级代理完成分片接收、CRC/SHA 校验,并写入备用分区。 存储分区保存双镜像与元数据,Bootloader 依据标志位选择启动槽。 应用程序运行后上报版本,异常时由 Bootloader 回滚到旧镜像。

一、五个组成部分的职责边界

Bootloader 是上电后最先执行的代码,它不参与业务逻辑,只做三件事:判断从哪个分区启动、校验镜像完整性、必要时搬运或回滚镜像。它必须足够小、足够稳定,通常放在独立的只读区域,升级过程中不被覆盖。

应用程序 是业务主体,负责采集、控制、通信和用户交互。它需要暴露版本号、运行状态和升级入口,但不应直接操作 Flash 的底层擦写,而是通过升级代理完成。

升级代理 是升级流程的“调度中心”。它接收固件包、分片缓存、校验签名、写入备用分区、设置升级标志,最后触发重启。它既可以作为应用程序中的一个模块,也可以独立成一个小型服务。

通信接口 决定固件包如何进入设备。串口适合产线烧录,USB 适合本地维护,BLE/Wi-Fi 适合近场升级,4G/以太网适合远程 OTA。接口层只负责传输,不负责升级决策。

存储分区 是升级系统的物理基础。常见做法是划分 Boot 区、Slot A、Slot B、参数区和日志区。双槽设计让新固件写入备用槽,失败时仍可回到旧槽。

二、典型升级数据流

以“设备通过 4G 接收 OTA 包”为例,完整数据流如下:

  1. 应用程序检测到服务器有新版本,向升级代理发起升级请求。
  2. 升级代理通过通信接口建立连接,协商分片大小与校验方式。
  3. 固件包分片到达后,升级代理逐片写入 Slot B,并记录写入偏移。
  4. 全部写入完成后,升级代理计算整包 SHA-256,与服务器下发的摘要比对。
  5. 校验通过后,升级代理在参数区写入“待升级”标志和目标槽位。
  6. 设备重启,Bootloader 读取标志,校验 Slot B 镜像,跳转执行。
  7. 新应用启动成功后,升级代理清除标志,升级完成;若启动失败,Bootloader 回滚到 Slot A。

核心原则:升级过程中,当前运行镜像始终不被破坏;新镜像先写入备用槽,校验通过后才切换启动标志。这样即使断电、丢包或校验失败,设备仍能回到可用状态。

三、分区表与参数设计示例

下面是一个典型的 2MB Flash 分区配置,供参考:

分区名        起始地址      大小       用途
boot          0x08000000   32 KB      Bootloader,只读
slot_a        0x08008000   768 KB     当前运行镜像 A
slot_b        0x080C8000   768 KB     备用升级镜像 B
param         0x08188000   16 KB      升级标志、版本号、启动计数
log           0x0818C000   16 KB      升级日志与错误码

参数区中至少应保存以下字段:

  • active_slot:当前启动槽位,A 或 B。
  • pending_slot:待验证槽位,升级后置位。
  • boot_count:连续启动失败计数,超过阈值触发回滚。
  • fw_version:当前固件版本号,供服务器比对。
  • crc32:参数区自身校验,防止标志位被写坏。

四、案例场景:BLE 固件升级失败复盘

某智能手环通过 BLE 升级,用户反馈“升级到 80% 后断开,设备无法开机”。排查发现:升级代理在接收分片时直接擦写了 Slot A,而 Slot A 正是当前运行镜像。BLE 断开后,Slot A 已被部分擦除,Bootloader 校验失败,设备变砖。

修正方案:

  • 升级代理只允许写入非活动槽位,活动槽位在升级期间保持只读。
  • 增加断点续传能力,记录已写入偏移,重连后从断点继续。
  • Bootloader 增加“启动失败自动回滚”逻辑,连续 3 次启动失败即切回旧槽。
  • 参数区写入前后均做 CRC 校验,避免标志位半写导致状态不确定。

常见误区:把“升级成功”等同于“写入完成”。真正的成功标准是:新镜像校验通过、Bootloader 跳转成功、应用程序正常启动并上报新版本号。缺少任何一步,都应视为升级未完成。

五、架构检查清单

检查项 合格标准 常见问题
Bootloader 独立性 不被应用升级覆盖,具备校验与回滚能力 Bootloader 与应用混在同一分区
双槽设计 活动槽与备用槽物理隔离,可独立擦写 单槽升级,失败即变砖
升级代理职责 只负责接收、校验、写入、置标志 代理直接跳转或直接擦除活动槽
通信接口容错 支持超时重传、断点续传、分片校验 一次失败即放弃,无重试机制
参数区可靠性 带 CRC、双备份或日志式写入 标志位写坏导致启动槽位错乱

掌握这五个组成部分及其协作关系后,后续设计升级协议、分区布局和回滚策略时就有了清晰的边界。架构先行,细节才不会互相打架。