4. 设备端升级代理(Agent)设计
设备端升级代理(Agent)是OTA体系中真正“落地执行”的软件实体。云端下发什么、主控业务进程何时让路、Flash如何写入、失败后如何恢复,全部由Agent协调。设计不当的Agent往往表现为:升级时业务中断时间过长、断电后设备变砖、校验通过但启动失败、回滚不彻底导致反复重启。本节围绕Agent的启动流程、任务接收、下载校验、写Flash与分区切换、回滚机制以及与主控业务进程的协同,给出一套可落地的状态机设计。
一、Agent的启动流程与运行位置
Agent通常位于Bootloader与主控应用之间的独立分区,或作为主控系统中的一个高优先级守护进程。以常见的MCU+外部Flash架构为例,上电后Bootloader先运行,读取升级标志区(Flag区)判断是否存在待验证的新固件:若标志为“待验证”,则跳转到新分区启动并启动看门狗计时;若标志为“正常”,则跳转当前有效分区。Agent本身在应用启动后拉起,负责与云端通信、下载、校验和写Flash。
启动流程的关键是先判断状态、再决定跳转,而不是先启动业务再检查升级。建议在Flag区中保存三元组:active_slot(当前有效分区)、pending_slot(待验证分区)、boot_attempts(启动尝试计数)。Bootloader每次启动时对boot_attempts做上限判断,超过阈值即触发回滚,这样即使新固件在启动早期就崩溃,也能被硬件级逻辑拉回。
二、Agent状态机设计
Agent的核心是一个有限状态机,建议至少包含以下状态:IDLE(空闲)、CHECKING(检查任务)、DOWNLOADING(下载中)、VERIFYING(校验中)、WRITING(写Flash)、SWITCHING(切换分区)、TRIAL(试运行验证)、ROLLBACK(回滚)、ERROR(故障锁定)。状态迁移必须由明确事件驱动,例如收到升级指令、下载完成、CRC比对失败、写Flash超时、试运行心跳丢失等。
三、升级任务接收与下载校验
任务接收阶段,Agent通过MQTT或HTTPS获取升级清单,清单中应包含固件版本号、文件大小、分片大小、SHA-256摘要、签名值、下载地址和最低电量/信号门限。Agent在进入DOWNLOADING前先做前置条件检查:电量是否高于阈值(例如20%)、可用存储是否大于固件大小的1.2倍、当前是否处于业务低峰窗口。任一条件不满足则保持IDLE并上报原因,避免下载到一半因断电或空间不足失败。
下载建议采用分片+断点续传。每片写入临时区后记录偏移量,网络中断后从上次偏移继续。全部下载完成后进入VERIFYING,先做长度比对,再计算SHA-256与清单摘要比对,最后用设备内置公钥验证签名。只有三项全部通过才允许进入WRITING;任何一项失败都删除临时文件并回到IDLE,同时上报错误码,防止把损坏固件写入分区。
四、写Flash与分区切换
写Flash阶段要遵循“先擦后写、按扇区对齐、写后回读”的原则。以STM32+W25Q128为例,扇区大小为4KB,Agent按扇区擦除目标分区(非当前运行分区),再逐页写入,每写一页回读比对。写入过程中若检测到电压跌落中断,Flag区中的write_offset可帮助下次启动时判断目标分区是否完整,不完整则直接丢弃,不影响当前运行分区。
分区切换不是复制固件,而是修改Flag区的pending_slot与boot_attempts=0,然后软复位。Bootloader读到待验证标志后跳转新分区。这里的关键设计是:旧分区在试运行确认前绝不擦除,它是回滚的唯一物理基础。
五、回滚机制与试运行判定
新固件启动后进入TRIAL状态,主控业务进程需在规定时间内(例如连续运行60秒且完成一次自检)向Agent上报心跳。Agent收到心跳后将Flag置为CONFIRMED,清除pending标志,试运行结束。若在超时窗口内心跳缺失,或Bootloader发现boot_attempts超过3次,则触发ROLLBACK:将active_slot改回旧分区、清除pending标志、复位。回滚成功后Agent上报回滚事件;若回滚后仍无法启动,则进入ERROR锁定,仅保留串口/本地恢复通道,等待人工介入。
六、与主控业务进程的协同
Agent与业务进程之间需要明确的“让路”协议。推荐使用共享内存或消息队列传递三类信号:UPGRADE_PREPARE(请业务保存现场并停止写Flash)、UPGRADE_READY(业务已就绪,可复位)、UPGRADE_ABORT(取消升级)。业务进程收到PREPARE后应在限定时间内完成数据落盘、关闭外设、停止看门狗喂狗以外的非必要任务,然后回复READY。Agent只有在收到READY后才执行分区切换,避免业务正在写参数区时被复位导致数据损坏。
综上,Agent状态机的设计要点可归纳为:启动先判状态、下载必校验、写入不碰运行区、切换只改标志、试运行有超时、回滚有物理基础、与业务有握手协议。把这七点落实到代码与Flag区布局中,OTA的可靠性才有工程保障。