3. OTA升级架构设计:三种主流方案对比

做OTA升级,第一个要拍板的问题就是:选哪种存储架构?

我这些年经手过的蓝牙项目,从智能手环到工业传感器,基本都逃不开这三种方案——双区架构、单区架构、混合架构。说白了,没有绝对的好坏,只有合不合适的区别。

今天咱们就把这三兄弟拉出来遛遛,看看它们各自的本事和软肋。

3.1 双区架构(Bank0/Bank1)

这是最经典、也是最稳妥的方案。我在2018年做一款医疗级体温贴时,就用的这个架构。当时客户要求「升级失败不能变砖」,双区架构是唯一的选择。

工作原理

Flash被分成两个大小相等的区域——Bank0和Bank1。平时程序在Bank0里跑,升级时把新固件下载到Bank1。下载完成后,通过一个标志位切换启动区,下次重启就从Bank1启动了。

核心优势

  • 绝对安全:升级过程中哪怕断电、断连,Bank0里的老程序纹丝不动。重启后还能回滚。
  • 回滚方便:我有个项目,新固件有个隐藏bug,上线两天才发现。双区架构让我一键切回老版本,用户完全无感。
  • 升级流程简单:不需要擦除当前运行区,直接写另一个区就行。

注意

  • Flash占用翻倍:你的程序如果占256KB,那就得准备512KB的Flash。成本直接翻倍。
  • 启动逻辑复杂:需要处理启动标志、校验、回滚计数等。我见过一个团队,启动标志位没处理好,每次重启都在两个区之间来回跳,跟蹦迪似的。

适用场景

  • 医疗设备、工业控制等对可靠性要求极高的场景
  • 产品生命周期长,需要多次OTA升级
  • Flash容量充裕,不差那点成本

3.2 单区架构

单区架构,说白了就是「破釜沉舟」。整个Flash只有一个程序区,升级时直接覆盖自己。

我第一次用单区架构是在一个成本敏感的智能灯泡上。一颗Flash才128KB,双区根本塞不下。没办法,只能硬着头皮上单区。

工作原理

程序运行在Flash的某个区域,升级时先把新固件下载到RAM或者Flash的末尾空闲区,校验通过后,擦除整个程序区,再把新固件写回去。

优点

  • Flash利用率最高:同样的Flash容量,单区能装更大的程序。
  • 成本最低:选小容量的Flash就行,BOM成本能省几毛到几块钱。

致命缺点

  • 升级过程极其脆弱:擦除旧固件到写入新固件之间,有一段「真空期」。这时候断电,设备就变砖了。
  • 需要额外存储空间:要么RAM够大能装下整个固件,要么Flash末尾留一块缓冲区。我做过一个项目,RAM只有64KB,固件却有200KB,只能分块下载、分块写入,流程复杂得要命。

适用场景

  • 成本极度敏感的产品(如一次性设备、玩具)
  • Flash容量非常有限(128KB以下)
  • 升级频率低,且能接受一定变砖风险

3.3 混合架构

混合架构,是我个人最喜欢的一种方案。它试图在安全性和成本之间找个平衡点。

嗯,这里要注意:混合架构不是简单的「一半双区一半单区」,而是把Flash分成三部分——一个小的Bootloader区、一个大的App区、一个小的备份区。

工作原理

Bootloader区是只读的,负责启动和升级管理。App区存放主程序,备份区存放新固件或者旧固件的压缩包。

优点

  • 比双区省Flash:备份区不需要和App区一样大,可以小很多。比如App区256KB,备份区128KB就够了。
  • 比单区安全:Bootloader区不会被擦除,至少保证设备能进入恢复模式。
  • 支持增量升级:备份区可以只存差异部分,进一步节省空间。

缺点

  • 设计复杂度最高:需要处理Bootloader、App、备份区三者的交互逻辑。我有个项目,Bootloader和App的通信协议没对齐,升级时数据传着传着就乱了。
  • 回滚能力有限:备份区如果只存了增量数据,回滚时需要重新计算,过程比双区慢。

适用场景

  • Flash容量中等(256KB-1MB)
  • 需要一定安全性,但成本也有要求
  • 产品功能复杂,App区需要较大空间

3.4 三种架构对比一览

对比维度 双区架构 单区架构 混合架构
安全性 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐
Flash利用率 50% 接近100% 70%-80%
实现复杂度 中等
回滚能力 中等
成本 中等
典型Flash需求 2x App大小 App大小 + 少量缓冲区 App大小 + 0.5x App大小

3.5 我的选择建议

说实话,没有万能方案。但我可以分享几个经验:

  • 如果你做的是消费级产品,比如智能灯、插座,Flash在512KB以上,我建议用双区架构。多花几毛钱,省去售后维修的麻烦,值。
  • 如果你做的是工业或医疗产品,别犹豫,直接上双区。我曾经因为省Flash选了混合架构,结果客户现场升级失败,我连夜飞过去救砖,机票钱够买几百颗Flash了。
  • 如果你做的是超低成本产品,比如一次性电子标签,Flash只有64KB,那只能选单区。但记得加一个「强制恢复模式」——按住某个按键再上电,从UART或者SPI重新烧录。

避坑指南

我曾经在一个双区架构的项目里,把启动标志位放在Flash的最后一个扇区。结果那个扇区磨损太快,设备用了半年就启动不了了。后来我改成把标志位分散存储,并且加了磨损均衡算法,问题才解决。

所以,不管你选哪种架构,Flash的寿命管理一定要提前考虑。尤其是频繁升级的产品,别等到量产了才发现问题。

好了,三种架构的对比就聊到这儿。下一章咱们深入讲讲升级流程的具体实现,包括怎么处理断点续传、怎么校验固件完整性。到时候我会拿一个实际项目的代码来拆解,保证干货满满。