3、OTA升级流程拆解:固件包下载、完整性校验、固件解压、固件刷写、系统重启
好,咱们进入正题。OTA升级听起来高大上,拆开来看,其实就是五个步骤走一遍。我做了这么多年OTA,说句实话,90%的升级失败都出在这五个环节中的某一个。你把这五个环节吃透了,基本上就能应付绝大多数场景了。
3.1 固件包下载——第一道坎
下载这一步,看起来最简单,其实最容易翻车。我见过太多项目,前面都好好的,一到下载就卡死。为什么?说白了,嵌入式设备的网络环境太复杂了。
我个人习惯把下载策略分成三种:
- 全量下载:整个固件包一次性拉下来。适合网络稳定、存储空间充裕的场景。
- 断点续传:下载中断后从断点继续。我在做车机OTA时遇到过,用户开车进隧道信号断了,出来接着下,这个功能救了不少升级任务。
- 差分下载:只下载变化的部分。嗯,这个后面会细讲,这里先提一嘴。
下载过程中,我建议你重点关注三个指标:
| 指标 | 说明 | 我的经验值 |
|---|---|---|
| 下载速度 | 每秒接收的字节数 | 低于10KB/s就要报警了 |
| 重试次数 | TCP重连次数 | 超过3次建议暂停等待 |
| 校验失败率 | 分片校验失败比例 | 超过5%说明信道质量差 |
3.2 完整性校验——别让坏数据混进来
下载完了,你以为就安全了?天真。数据在传输过程中可能被篡改,也可能因为存储介质坏块导致数据损坏。完整性校验就是干这个的。
常用的校验方式有这么几种:
- MD5/SHA256:对整个固件包做哈希。我建议用SHA256,虽然计算慢一点,但安全性高很多。
- CRC32:每个分片单独校验。适合流式处理,不用等全部下载完。
- 签名验证:用公钥验证固件包的数字签名。这个能防篡改,但需要硬件安全模块支持。
我曾经在一个物联网项目中踩过坑。当时只做了MD5校验,结果攻击者替换了固件包,连MD5值一起改了。从那以后,我坚持签名验证+哈希校验双重保险。
3.3 固件解压——空间换时间
固件包为了传输效率,一般都是压缩的。解压这一步,考验的是设备的计算能力和内存管理。
常见的压缩格式:
- gzip:压缩率高,但解压慢。适合存储空间紧张、CPU性能强的设备。
- lzma:比gzip压缩率更高,但解压更慢。我一般只在服务器端用。
- lz4:压缩率一般,但解压极快。适合实时性要求高的场景。
我个人习惯的做法是:先解压到临时分区,校验解压后的文件结构,再开始刷写。为什么?因为解压过程中可能出错,比如内存不足、文件损坏。提前发现总比刷到一半才发现好。
关键点:解压时一定要监控内存使用量。我建议预留至少2倍于压缩包大小的内存空间。否则解压到一半OOM(内存溢出),整个升级流程就废了。
3.4 固件刷写——最危险的一步
刷写,就是把固件数据写入存储介质。这一步出问题,设备基本就废了。所以,我把它叫做「鬼门关」。
刷写方式主要有两种:
- 全量刷写:擦除整个分区,写入新固件。简单粗暴,但风险高——万一写到一半断电,分区就空了。
- 增量刷写:只更新变化的部分。需要差分算法支持,但风险小很多。
我建议你采用「双备份」策略:保留一个可启动的旧固件,刷写新固件到另一个分区。这样即使新固件刷坏了,还能回滚到旧版本。
3.5 系统重启——最后一哆嗦
刷写完成,重启系统。这一步看似简单,其实暗藏玄机。
重启后系统会做几件事:
- 引导加载程序(Bootloader)检查:验证新固件的签名和完整性。
- 文件系统挂载:确保新固件的文件系统没问题。
- 关键服务启动:网络、日志、安全模块等。
- 应用层自检:运行自检程序,确认功能正常。
我习惯在重启后加一个「观察期」。设备启动后,先不切换主服务,运行5分钟自检。如果自检通过,再正式切换到新固件。如果自检失败,自动回滚到旧版本。
好了,五个步骤讲完了。你发现没有?每一步都有坑,每一步都需要日志来监控和定位问题。下一章,我会详细讲怎么用日志来追踪这五个步骤的执行情况。到时候咱们再细聊。