2. OTA基础概念
做OTA升级,说白了就是让设备能自己给自己“换脑子”。
但这个过程没那么简单。你得先搞清楚几个核心概念。我刚开始接触OTA时,也踩过不少坑。今天咱们就把这些概念掰开揉碎了讲清楚。
2.1 固件(Firmware)——设备的灵魂
固件是什么?就是跑在MCU里的程序。它决定了设备能做什么、怎么做。
在OTA场景下,固件通常指的就是那个待升级的二进制文件。比如一个.bin文件,或者.hex文件。
关键点:固件不是一成不变的。它会被编译、打包、签名,然后通过OTA通道下发到设备上。
我个人习惯把固件分成两类:
- 基础固件:出厂时烧录的版本,包含最核心的功能。
- 升级固件:后续通过OTA推送的新版本,修复bug或增加功能。
嗯,这里要注意:固件的大小直接影响升级速度和成功率。我在项目中遇到过,一个固件包太大,导致下载超时,设备变砖。后来我们强制要求固件压缩,并且做了断点续传。
2.2 Bootloader——升级的总指挥
Bootloader,直译就是“引导加载程序”。它是一段特殊的代码,在MCU上电后最先运行。
它的任务很简单:决定接下来跑哪个固件。
你可以把它想象成一个“看门大爷”。设备一启动,Bootloader先检查:
- 有没有新固件要升级?
- 现有固件是否完整?
- 该跳转到哪个分区执行?
我的经验:Bootloader必须足够小、足够稳定。它不能依赖任何应用层的功能。我曾经见过有人把Wi-Fi驱动写在Bootloader里,结果升级时Wi-Fi模块挂了,Bootloader也跟着卡死。这是大忌。
Bootloader的典型工作流程:
- 上电,初始化时钟和基本外设。
- 检查升级标志(比如某个GPIO电平,或者Flash里的标记位)。
- 如果有升级请求,进入升级模式,接收新固件并写入Flash。
- 如果没有升级请求,验证当前固件的完整性(CRC校验)。
- 跳转到应用程序分区执行。
2.3 应用程序分区——固件的“家”
MCU的Flash空间是有限的。我们需要把它划分成不同的区域,每个区域叫一个“分区”。
应用程序分区,就是存放固件代码的地方。
常见的分区布局:
| 分区名称 | 起始地址 | 大小 | 用途 |
|---|---|---|---|
| Bootloader | 0x08000000 | 32KB | 引导和升级管理 |
| App_A(主分区) | 0x08008000 | 256KB | 当前运行的固件 |
| App_B(备份分区) | 0x08048000 | 256KB | 新固件下载或备份 |
| 参数区 | 0x08088000 | 16KB | 存储配置、升级标志等 |
你想想看,如果没有分区,新固件直接覆盖旧固件,万一写到一半断电了,设备就彻底废了。这就是为什么我们需要分区。
2.4 双区备份——OTA的“安全气囊”
双区备份,也叫A/B分区升级。这是目前最可靠的OTA方案之一。
它的核心思想:永远保留一个可正常运行的固件副本。
具体做法:
- App_A:当前正在运行的分区。
- App_B:备用分区,用于下载新固件。
升级流程:
- 设备在App_A中正常运行。
- 收到升级通知,开始下载新固件到App_B。
- 下载完成后,校验App_B的完整性。
- 设置升级标志,重启。
- Bootloader检测到升级标志,跳转到App_B执行。
- 如果App_B运行正常,标记为“已确认”,下次启动继续用App_B。
- 如果App_B启动失败,Bootloader自动回退到App_A。
注意:双区备份需要Flash空间翻倍。对于资源受限的MCU,这可能是个挑战。我曾经在一个只有512KB Flash的芯片上做双区备份,最后不得不把固件压缩到200KB以内,才勉强塞下两个分区。
下面这张图展示了双区备份的核心逻辑:
2.5 回滚机制——最后的救命稻草
回滚机制,就是当新固件出问题时,能自动退回到上一个稳定版本。
这是双区备份的天然优势。但回滚不是简单的“切回去”,它需要一套完整的策略。
我总结了几种常见的回滚触发条件:
- 启动超时:新固件在规定时间内没有完成初始化。
- 看门狗复位:新固件导致系统反复重启。
- 用户主动触发:比如长按某个按键,强制回滚。
- 通信失败:新固件上线后无法连接服务器。
避坑指南:我曾经做过一个项目,回滚逻辑写得太“激进”。新固件刚启动3秒,还没来得及连网,就被判定为“通信失败”,触发了回滚。后来我们加了一个“延迟确认”机制:新固件必须正常运行至少5分钟,并且成功上报一次数据,才算“确认通过”。
回滚的执行过程:
- Bootloader检测到新固件异常(比如CRC校验失败,或者启动标志未清除)。
- 将启动标志指向旧分区(App_A)。
- 跳转到App_A执行。
- App_A启动后,可以尝试重新下载新固件,或者保持当前版本。
2.6 总结一下这些概念的关系
你想想看,这些概念其实是一个完整的链条:
- 固件是目标。
- Bootloader是执行者。
- 分区是场地。
- 双区备份是策略。
- 回滚是兜底。
缺了任何一个,OTA升级都可能出大问题。我记得有一次,一个同事只做了单分区升级,结果升级过程中断电,设备直接变砖。后来我们花了整整两天才用JTAG把固件救回来。从那以后,双区备份就成了我们团队的硬性要求。
最后提醒:不要为了省Flash空间而放弃双区备份。除非你的设备允许现场拆机烧录,否则,省下的那点空间,迟早会变成你加班的时间。