设备能在实验室跑起来,只是第一步。真正部署到现场后,固件升级能力会变得非常关键。没有可靠 OTA,后续修 bug、加功能、修安全问题都会变成高风险操作。
一、OTA 要解决什么
OTA 不是简单下载一个文件然后覆盖系统。它至少要解决:
- 下载完整性。
- 版本校验。
- 断点或失败处理。
- 写入过程断电保护。
- 升级后启动验证。
- 失败回滚。
- 保留用户配置。
现场设备最怕升级后变砖,所以 OTA 设计的核心目标是:失败可以回到旧版本。
二、常见分区方案
简单方案:
1 | boot |
风险是升级 rootfs 时如果断电,系统可能无法启动。
更稳的方案是 A/B 双分区:
1 | boot |
当前从 A 启动时,升级写入 B。写完后修改启动标记,下次从 B 启动。如果 B 启动失败,再回滚到 A。
三、升级状态机
可以定义几个状态:
1 | idle |
升级状态要写入可持久化分区,例如:
1 | /data/ota/state.json |
不要只存在内存里。断电重启后,设备必须知道升级进行到哪一步。
四、镜像校验
下载后至少校验 sha256:
1 | sha256sum firmware.bin |
更完整的做法是:
- 固件包带 manifest。
- manifest 包含版本、目标型号、文件大小、sha256。
- manifest 用私钥签名。
- 设备用内置公钥验签。
这样可以避免下载损坏或被替换的固件。
五、启动确认和回滚
升级后第一次启动不能立刻认为成功。可以设置 pending 标记:
1 | boot_slot=B |
业务服务启动成功、网络连接成功、核心功能自检通过后,再执行 commit:
1 | upgrade_state=committed |
如果连续几次启动都没有 commit,Bootloader 或早期启动脚本应该回滚到旧分区。
六、data 分区要保留
OTA 通常不应该清空用户配置:
1 | /data/config |
但版本升级可能带来配置格式变化,所以应用要支持配置迁移:
1 | config_version: 1 -> 2 |
迁移失败要有默认值和日志,不要让服务直接崩溃。
七、最小验收清单
OTA 至少要测:
- 正常升级。
- 下载中断。
- 写入中断。
- 校验失败。
- 升级后应用启动失败。
- 回滚后旧版本可用。
- 用户配置仍然存在。
OTA 做到最后,拼的是异常路径。正常路径跑通不代表能上现场。
- 本文链接: https://blog.hansong.icu/2026/06/26/Embedded_Linux_Series_09_OTA_Rollback/
- 版权声明: 本博客所有文章除特别声明外,均默认采用 CC BY-NC-SA 4.0 许可协议。