4. 设备端升级流程:下载、校验、备份、执行与回滚

设备端升级,说白了就是一场“空中换心脏”的手术。我在早期做物联网项目时,最怕的就是升级到一半断电,设备变砖。后来慢慢摸索出一套标准流程,今天跟你聊聊这五个关键步骤。

4.1 下载升级包:别让网络拖后腿

下载是第一步,也是最容易出幺蛾子的环节。我建议分片下载,别指望一口气吃成胖子。

  • 断点续传:网络不稳定时,从断点接着下,别从头来。
  • 校验分片哈希:每下载一片,算一次 SHA256,防止中间人篡改。
  • 限速与重试:别把带宽占满,影响业务。重试次数设 3 次,间隔指数退避。
我的经验:有一次在偏远地区部署,下载速度只有 10KB/s。我加了分片并行下载,速度提升 3 倍。但要注意,并发数别超过 4,否则设备内存扛不住。

4.2 校验完整性:信任但验证

下载完,别急着解压。先做两件事:哈希校验和签名验证。

校验类型 目的 常用算法
哈希校验 确保文件没损坏 SHA256
签名验证 确保来源可信 RSA2048 / ECDSA

我习惯先算哈希,再验签名。顺序不能反——签名验的是哈希值,不是原始文件。

// 伪代码示例:校验流程
uint8_t hash[32];
sha256(update_pkg, pkg_size, hash);
if (memcmp(hash, expected_hash, 32) != 0) {
    return ERROR_HASH_MISMATCH;
}
if (rsa_verify(hash, signature, pub_key) != 0) {
    return ERROR_SIGNATURE_INVALID;
}
注意:公钥要固化在 BootROM 或安全存储区。我曾经见过有人把公钥放文件系统里,结果被替换,整批设备被刷入恶意固件。

4.3 备份当前系统:给自己留条后路

升级前,必须备份当前运行的系统。我推荐双分区方案(A/B 分区),但如果你只有单分区,那就老老实实做全量备份。

  • 双分区(A/B):升级时写 B 区,失败直接切回 A 区。零风险。
  • 单分区 + 备份:把当前固件压缩存到另一个存储区域。注意空间要够。
  • 关键配置备份:网络参数、设备证书等,单独备份到 NVRAM。

嗯,这里要注意:备份过程不能中断。我建议加一个“备份中”标志位,重启后检测到标志位,自动恢复。

4.4 执行升级:最紧张的时刻

升级执行阶段,设备会短暂“失联”。我的原则是:越快越好,越稳越好。

  1. 解压升级包:用 LZMA 或 zstd,解压速度要快。
  2. 写入目标分区:按块写入,每写一块校验一次。
  3. 更新启动参数:告诉 Bootloader 下次从新分区启动。
  4. 触发重启:延迟 1-2 秒,让看门狗有机会喂狗。
关键指标:升级耗时 < 30 秒(不含下载),成功率 > 99.5%。如果达不到,说明你的写入策略或校验逻辑有问题。

4.5 回滚机制:最后的救命稻草

升级后如果设备起不来,或者业务异常,必须能自动回滚。我见过太多设备因为回滚没做好,变成“高级砖头”。

回滚触发条件一般有三种:

  • 启动超时:新系统 3 分钟内没上报心跳,自动切回旧系统。
  • 业务检测失败:核心服务没启动,或者关键接口返回错误。
  • 手动触发:运维人员远程下发回滚指令。

回滚流程其实很简单:把启动分区指针指回旧分区,重启。但要注意,回滚次数要有限制——我一般设 3 次,超过后锁定,防止反复回滚死循环。

避坑指南:我曾经遇到一个案例,回滚后旧系统因为配置不兼容,照样起不来。从那以后,我坚持备份时连配置文件一起备份,回滚时一并恢复。

4.6 整体流程一览

下面这张图,把五个步骤串起来了。你可以把它贴在工位上,每次做升级方案时对照着看。

设备端升级流程 设备端升级流程 ① 下载升级包 ② 校验完整性 ③ 备份当前系统 ④ 执行升级 ⑤ 回滚机制 回滚触发 关键原则 • 每一步都要有状态记录 • 失败后必须能回滚 • 回滚次数限制 3 次 常见失败原因 • 下载中断 / 哈希不匹配 • 写入时掉电 / 存储损坏

4.7 总结一下

这五个步骤,环环相扣。下载要稳,校验要严,备份要全,执行要快,回滚要可靠。你想想看,任何一个环节出问题,设备都可能变砖。我在项目中吃过不少亏,后来总结出三条铁律:

  • 永远假设网络会断——所以要有断点续传和重试。
  • 永远假设文件会坏——所以要有哈希和签名双重校验。
  • 永远假设升级会失败——所以要有备份和回滚。

做到这三点,你的 OTA 升级流程就算及格了。剩下的,就是在实际项目中不断打磨细节。