4. 双分区机制核心概念
双分区机制是 ECU 在 OTA 升级与故障恢复场景下最常用的可靠性设计。它的核心思想并不复杂:在 Flash 中预留两块可独立运行、可独立擦写的应用镜像区域,让“正在运行的程序”和“正在写入的程序”物理隔离。这样即使升级过程中断电、通信中断或新镜像校验失败,ECU 仍能回到一个已知可用的版本继续工作。理解双分区,关键要抓住 A/B 分区、主备分区、镜像槽、分区状态标志、启动标志、回滚策略与冗余设计思想这几个概念之间的关系。
一、A/B 分区与主备分区:两种常见组织方式
A/B 分区通常指两块容量相同、地位对等的应用分区,例如 Slot A 与 Slot B。当前运行在 A,则把新固件写入 B;升级成功后通过启动标志切换到 B,A 则成为下一次升级的备用区。主备分区则更强调角色差异:主分区是默认启动区,备分区是恢复区或候选区。两者在物理布局上可能相似,但语义不同——A/B 更强调“轮换”,主备更强调“优先级与兜底”。
镜像槽(Image Slot)是对可存放完整应用镜像的物理区域的抽象描述。一个镜像槽通常包含头部信息、版本号、长度、校验值、签名以及实际代码段。Bootloader 不直接关心“A 还是 B”,而是关心“哪个槽的镜像有效、哪个槽被标记为待启动”。因此,镜像槽是双分区机制中最基础的存储单元。
二、分区状态标志与启动标志
仅有分区还不够,Bootloader 必须知道每个分区的状态。常见做法是在 Flash 中维护一块元数据区,记录每个槽的状态标志。典型状态包括:
- VALID:镜像完整且校验通过,可被启动。
- INVALID:镜像损坏或校验失败,不可启动。
- TESTING:新镜像已写入,等待首次试运行确认。
- CONFIRMED:新镜像已成功运行并被正式确认。
- ROLLBACK:需要回退到旧版本。
启动标志(Boot Flag)则决定下一次复位后 Bootloader 跳转到哪个槽。它通常是一个独立的小字段,例如 active_slot 与 pending_slot。升级时先写 pending_slot,重启后 Bootloader 根据 pending_slot 跳转,并在试运行成功后把 active_slot 更新为新槽。这样即使写入过程中断电,也不会破坏当前可运行镜像。
三、回滚策略与冗余设计思想
回滚策略是双分区机制的安全阀。常见回滚触发条件包括:新镜像启动后看门狗复位次数超限、应用层自检失败、CAN 通信超时、关键外设初始化失败等。一旦满足回滚条件,Bootloader 将启动标志指回旧槽,并把新槽标记为 INVALID 或 ROLLBACK,等待下一次重新升级。
冗余设计思想不仅体现在“有两个分区”,还体现在元数据的冗余。若状态标志只存一份,擦写时断电可能导致标志丢失。工程上常采用双份元数据加 CRC 校验,或使用“主元数据 + 备份元数据”的方式,确保启动决策本身也是可靠的。
四、典型升级与回滚流程
下面给出一个简化的双分区升级流程,便于理解各标志的时序关系:
1. 当前 active_slot = A,A 状态 VALID,B 状态 INVALID
2. 收到新固件,写入 Slot B,写入完成后校验
3. 校验通过:B 状态 = TESTING,pending_slot = B
4. 复位,Bootloader 读取 pending_slot = B,跳转 B
5. B 试运行成功,应用调用 confirm 接口
6. Bootloader 更新:active_slot = B,B 状态 = CONFIRMED
7. A 状态保留为 VALID,作为下次升级的备用槽
8. 若第 5 步失败或超时,则 pending_slot = A,B 状态 = ROLLBACK
这个流程中,第 3 步和第 6 步是仅有的两次“写启动标志”操作,且都发生在镜像写入完成或试运行成功之后,因此断电风险窗口很小。
五、案例与常见误区
某车身控制器在 OTA 升级中曾出现“升级后无法启动”的问题。排查发现,Bootloader 在写入新镜像前就先把启动标志改成了新槽,结果写入中途断电,新槽不完整,旧槽又不再被启动,导致 ECU 变砖。修正方案是严格遵循“先写镜像、后改标志”的顺序,并在启动时增加镜像完整性校验。
另一个误区是忽略元数据寿命。状态标志频繁擦写会导致 Flash 扇区磨损,工程上应把元数据放在独立扇区,并采用追加写或磨损均衡策略。
六、关键概念对照清单
| 概念 | 作用 | 典型取值/形式 |
|---|---|---|
| A/B 分区 | 两块对等应用区,轮换升级 | Slot A / Slot B |
| 主备分区 | 主区默认启动,备区兜底 | Primary / Backup |
| 镜像槽 | 存放完整镜像的物理单元 | 头部 + 代码 + 校验 |
| 分区状态标志 | 描述镜像是否可用 | VALID / INVALID / TESTING / CONFIRMED |
| 启动标志 | 决定下次启动跳转槽 | active_slot / pending_slot |
| 回滚策略 | 失败时恢复旧版本 | 看门狗计数、自检失败触发 |
| 冗余设计 | 保证元数据与镜像可靠 | 双份元数据 + CRC |
总结来看,双分区机制的核心不是“多一块 Flash”,而是围绕镜像槽建立一套可验证、可切换、可回滚的状态机。A/B 分区提供物理冗余,状态标志提供判断依据,启动标志提供切换入口,回滚策略提供失败兜底,元数据冗余则保证这套机制自身不会成为单点故障。只有这些概念协同工作,ECU 才能在 OTA 升级中真正做到“升级失败不丢功能”。