2. 升级架构设计:Bootloader + App 双区架构、单区覆盖架构、A/B 系统架构
升级架构这东西,说白了就是决定「新固件往哪儿放、怎么替换老固件」。我见过不少团队一上来就写升级逻辑,结果做到一半发现 Flash 不够用,或者升级失败变砖了才回头改架构。嗯,咱们先把地基打牢。
目前主流的嵌入式升级架构就三种:Bootloader + App 双区、单区覆盖、A/B 系统。各有各的脾气,选错了后面全是坑。
2.1 Bootloader + App 双区架构
这是我最常用的方案,也是绝大多数 MCU 项目的默认选择。芯片上电先跑 Bootloader,Bootloader 检查有没有新固件,有就更新,没有就直接跳转到 App 分区执行。
分区结构很简单:
- Bootloader 区:只做一件事——引导和升级。代码量很小,一般 8KB~32KB 就够。
- App 分区:存放真正的业务逻辑。升级时新固件直接写入这个分区。
- 参数/标志区:存放升级标志、版本号、校验值。我习惯单独划一个扇区,防止被 App 误擦。
升级流程大致是这样:
- App 运行时收到升级包,下载到外部 Flash 或 RAM 缓冲区。
- 下载完成后,App 在参数区写入「待升级」标志,然后软复位。
- Bootloader 启动,读到标志,擦除 App 分区,把新固件从缓冲区搬过去。
- 校验通过后清除标志,跳转到新 App。
这个架构的优点是实现简单、Flash 占用适中。缺点嘛——升级过程中如果掉电,App 分区可能只写了一半,下次启动 Bootloader 发现 App 校验失败,只能干等着你重新传固件。
2.2 单区覆盖架构
说白了就是「原地换血」。整个 Flash 只有一个 App 分区,升级时直接擦掉老固件,写入新固件。没有 Bootloader,或者 Bootloader 小到可以忽略。
这种架构常见于 Flash 极其紧张的场景,比如 32KB 或 64KB 的芯片。你想想看,双区架构至少要多占一整个 App 的空间,A/B 系统更是翻倍,单区覆盖是唯一的选择。
但代价也很明显:
- 升级期间掉电 = 变砖。没有备份,没有回滚,擦到一半断电就彻底凉了。
- 必须保证升级包的完整性。我建议在传输阶段做完整校验,确认包没问题再开始擦写。
- 没有回退能力。新固件有 bug?只能再升一次。
我曾经在一个智能灯的项目里被迫用了单区覆盖——芯片只有 32KB Flash,双区根本塞不下。我的做法是:先把新固件下载到外部 EEPROM,校验通过后再一次性写入内部 Flash。虽然慢了点,但至少降低了变砖概率。
如果你不得不用单区覆盖,记住几条保命原则:
- 写入前做完整的 CRC 或 SHA 校验。
- 写入过程中不要喂狗,或者把喂狗放在写入循环里。
- 保留一小块「恢复标志区」,如果升级失败,下次上电还能进入一个最小引导模式。
2.3 A/B 系统架构
这是最安全、但也最奢侈的方案。Flash 里放两个完整的 App 分区(Slot A 和 Slot B),外加一个 Bootloader。系统在 Slot A 上运行,升级时把新固件下载到 Slot B,下载完成后切换启动 Slot B。如果 Slot B 启动失败,自动回滚到 Slot A。
你想想看,这相当于给系统买了一份「保险」。汽车 ECU、医疗设备、工业控制器这些不能停机的场合,A/B 系统几乎是标配。
分区布局:
| 分区 | 大小 | 作用 |
|---|---|---|
| Bootloader | 16KB~32KB | 引导、切换 Slot、管理升级标志 |
| Slot A | App 大小 | 当前运行版本 |
| Slot B | App 大小 | 备用/新版本 |
| 元数据区 | 1~2 个扇区 | 记录当前活跃 Slot、升级状态、尝试次数 |
升级流程:
- 系统在 Slot A 运行,后台下载新固件到 Slot B。
- 下载完成后,Bootloader 把元数据区的「活跃 Slot」从 A 改为 B。
- 系统重启,Bootloader 启动 Slot B。
- Slot B 运行后做自检,通过后提交「确认」标志。
- 如果 Slot B 启动失败或自检不通过,Bootloader 把活跃 Slot 切回 A,实现回滚。
A/B 系统的代价也很明显:Flash 容量翻倍。如果你的芯片只有 256KB,App 占了 120KB,那 A/B 系统直接吃掉 240KB,Bootloader 都没地方放了。所以选这个架构前,先确认 Flash 容量够不够。
2.4 如何选择?
我一般按这个思路来选:
- Flash 小于 128KB,升级频率低 → 单区覆盖。但一定要加外部存储或传输校验做保护。
- Flash 128KB~512KB,需要远程升级 → Bootloader + App 双区。这是最平衡的方案。
- Flash 大于 512KB,设备不允许停机 → A/B 系统。安全第一,成本第二。
- 产品要过功能安全认证 → 直接上 A/B 系统。认证机构看到单区覆盖会摇头的。
最后说一句:架构选型没有银弹。我见过有人用 1MB Flash 的芯片还坚持用单区覆盖,也见过 64KB 的芯片硬上 A/B 系统结果塞不下。搞清楚你的约束条件,再动手画分区图。