设备可能遇到任务死锁、总线卡住、低压、写入中断和新固件启动失败。可靠性设计要回答四件事:怎样发现异常、怎样进入可接受状态、怎样恢复、怎样留下足够证据定位原因。

看门狗检查进展

看门狗超时后触发预定恢复动作。若每个 tick 都无条件喂狗,业务死锁时 tick 还在运行,故障可能永远不会被发现。更有意义的做法是各关键任务在完成规定工作后更新进展,由监督逻辑检查后喂狗;观察期限要包含正常的最坏处理与等待。

启动后记录复位原因、软件版本和必要状态;持续重启时设置有界重试或恢复模式。喂狗窗口、暂停调试行为和复位范围均按芯片手册设置。看门狗提高故障恢复能力,并不代替系统安全分析。

Flash 和断电边界

Flash 擦除粒度、写入粒度、擦写寿命和断电行为取决于具体器件。频繁把每个采样点写入同一扇区会快速消耗寿命。先做写入频率与寿命预算,再考虑缓存、批量写、磨损均衡或外部存储。

持久记录可采用带版本、长度、序号和校验的追加日志;更新元数据时保留旧的可用副本,启动后选择最后一个完整提交。CRC 检查意外损坏,不证明内容来自可信发布者;SHA-256 也只有在期望摘要可信时才有相应意义。固件认证需要签名和受保护的信任根。

A/B 更新是一个事务

下载到非活动槽,验证镜像,然后标记待尝试;新固件首次启动通过必要自检后才确认。下载一半断电应继续使用旧版本;新版本无法确认时应回退。Bootloader、分区表或数据迁移有不同失败边界,不能把应用槽的 A/B 能力推广为“任何更新都不怕断电”。

下载 A/B 状态模型,执行 python ota_model.py。模型检查损坏镜像、选择前重启、首次试运行未确认、成功确认四条路径。它不模拟真实 Flash 原子写、签名或 ESP-IDF Bootloader,不能据此声称已完成设备 OTA 验证。

安全回滚还要考虑版本降级:修复漏洞后,恢复旧版本可能重新引入风险。反回滚机制与应急恢复需要共同设计;eFuse 等不可逆设置应通过具体芯片官方流程理解和验证,不作为随手试验步骤。

低功耗也要算完整周期

假设活动电流 30 mA、持续 20 ms,每秒一次,其余时间 0.02 mA,理想平均电流为 30×0.02+0.02×0.98=0.6196 mA。这里的数字是算例,未测量任何开发板。稳压损耗、无线重连、唤醒、传感器预热和电池容量随温度变化都会改变结果。

降低时钟或睡眠可能增加响应延迟,也可能影响外设时钟。测功耗时同时记录采样期限与丢包,避免以功能丢失换来一个较小电流数值。

验证故障恢复

用本地模型先穷举状态转移,再在受控目标上设置明确断电点、掉网、锁死任务和损坏记录。每个测试说明预期启动槽、数据损失上限和恢复时间。保留旧镜像与调试恢复通道,先验证能够恢复,再做破坏性条件测试。

练习:为配置结构增加一版字段,设计新旧固件都能处理的数据迁移;给 A/B 模型加入最低允许版本,并解释最低版本提高后何种回退会被拒绝。

面试自查:为什么循环喂狗可能掩盖故障?CRC 与数字签名有什么区别?A/B 更新为什么还需要确认?开发板待机电流能否代表最终产品?

参考:ESP-IDF 看门狗、ESP-IDF OTA 与回滚、ESP-IDF 电源管理。