为什么需要 OTA
设备卖到用户手里,不可能再拆壳烧录。固件有 bug、要加功能、要补安全漏洞,都得远程升级。OTA(Over-The-Air)就是干这个的:通过 Wi-Fi/蜂窝把新固件推到设备,设备自己更新。做不好的话,升级中断电直接变砖,用户投诉爆炸。
OTA 的核心不是"怎么下载固件",是"升级失败怎么救回来"。不变砖比升级快更重要。
这篇讲 OTA 的完整工程化方案。
单分区 vs 双分区
Flash 分区方案:
分区方案
- 单分区固件直接覆盖,升级中断电就砖。
- 双分区 A/B两个 slot,跑 A 写 B,切过来跑 B。
- Recovery 分区独立恢复分区,救砖用。
A/B 升级流程
A/B 升级标准流程:
// 1. 当前运行 slot A
// 2. 下载新固件到 slot B(后台写 Flash)
// 3. 校验 B 的 CRC/签名
// 4. 设置 boot flag:下次启动从 B 跑
// 5. 重启,从 B 启动
// 6. B 启动成功 -> 标记 B 为 good slot
// 7. B 启动失败 -> bootloader 自动切回 A
固件校验与签名
下载的固件不能直接跑,必须验证来源和完整性:
// 1. CRC32 校验完整性
// 2. RSA/ECDSA 签名校验来源
// 3. 版本号检查:不能降级到旧版本防回滚攻击
// bootloader 在跳转应用前先验签,验不过不跳
这和之前讲的 Secure Boot 是一套东西。
回滚机制
新固件跑起来发现崩溃怎么办?watchdog 救你。
// 机制:
// 1. 新固件第一次启动 -> 标记"未确认"
// 2. 应用启动后 N 分钟内必须调 "confirm_boot()"
// 3. 如果没调到 -> watchdog 超时复位
// 4. bootloader 看到"未确认"标记 -> 自动切回旧 slot
// 这就是 rollback
断电保护
写 Flash 中断电怎么办?
断电保护
- 写备份区新固件写到 B slot,不影响 A。
- 双 bankFlash 支持双 bank,边写边跑。
- 掉电检测VDD 跌了立刻停写。
- Bootloader 兜底怎么都能进 bootloader。
实战踩坑
// 1. 固件大小别超 slot 容量,留够余量
// 2. 下载断点续传:Wi-Fi 断了别从头来
// 3. 升级时电池电压要够,低电量拒升
// 4. 版本号语义化:major.minor.patch
// 5. 灰度推送:先推 1% 用户观察
OTA 是产品级工程,不是写个下载器就完了。不变砖、可回滚、可灰度,这三件事做扎实,OTA 才算上线。
把 OTA 做稳,设备才有持续生命力。