本节摘要:现场没有调试器,故障却不会迟到:电磁干扰、电压跌落、软件缺陷、硬件老化,总有一款会来。可靠性工程的思路不是"消灭所有故障"(做不到),而是检测故障、限制损失、自动恢复、留下证据。本节讲看门狗的正确用法、故障检测的分层设计、降级与安全态的落地方法,并完整解剖一个"设备现场死机"的自愈体系案例。
看门狗(Watchdog)是一个倒计时定时器:启动后不断递减,减到零就强制复位芯片;程序必须周期性地"喂狗"(重置计数值),喂狗意味着"我还活着"。机制简单,但用法有高下之分。
错误用法:主循环末尾喂一次。 主循环转着就喂狗——问题是主循环转着不代表系统正常:某个任务死锁了,但主循环还在空转;通信断了,但循环还在跑。看门狗只证明了"CPU 在执行指令",没证明"系统在干正事"。这种用法防得住真死机(跑飞、死循环),防不住"活着的瘫痪"。
正确用法:分任务喂狗。 给系统的每个关键任务发一张"健康票",看门狗喂狗逻辑要求所有票据齐了才喂:通信任务收到有效报文投一票、采样任务拿到新数据投一票、自检任务通过投一票——任何一环瘫痪,票据不齐,看门狗到期复位。窗口看门狗(喂早了喂晚了都复位)进一步约束喂狗节奏,防"喂得太勤"变成变相空转。
/* 分任务喂狗:票据齐了才喂 */ uint8_t health_votes = 0; void feed_check(void) /* 主循环每 100ms 汇总一次 */ { if (comm_alive) health_votes |= BIT0; /* 通信有新报文 */ if (sample_alive) health_votes |= BIT1; /* 采样有新数据 */ if (selftest_pass) health_votes |= BIT2; /* 自检通过 */ if (health_votes == EXPECTED_MASK) { watchdog_reload(); /* 全员健康才喂 */ } health_votes = 0; /* 清零重新攒票 */ }
看门狗的道德风险要坦白:它可能掩盖问题。复位后系统"看起来好了",但根因还在,故障变成"每月重启一次"的慢性病。所以 7.3 节的诊断体系里,复位原因记录是看门狗的法定搭档——每次看门狗复位都留档(5.4 与 2.3 节的复位原因寄存器在此汇合),返修设备一查便知是慢性病还是意外。
可靠性设计先要回答"怎么知道出事了"。检测按层布防,每一层盯一类故障:
硬件层监控电源(欠压检测复位、电源良好信号)与温度(片内传感器做过热保护——4.4 节提过它测的是结温,正好适合这个用途)。时序层监控"该来的没来":通信超时、传感器无响应、任务执行超时——超时是嵌入式最万能的故障探针,一切"等待"都该带超时。数据层监控"来的不对":校验和、CRC、合理范围检查(温度读出 90 度,先怀疑传感器而不是气候)、状态机非法转移。逻辑层监控"程序还讲理吗":栈溢出检测(栈填充水位)、关键变量互锁校验(两个互斥的标志同时为真即为异常)。
| 层级 | 监控对象 | 典型手段 | 触发后的动作 |
|---|---|---|---|
| 硬件层 | 电源与温度 | 欠压复位、过热检测 | 保护性停机或复位 |
| 时序层 | 该来的没来 | 通信与任务超时 | 重试、重连、报错 |
| 数据层 | 来的不对 | CRC、范围检查 | 丢弃、重传、标记故障 |
| 逻辑层 | 程序失智 | 栈水位、状态互锁 | 看门狗复位、安全态 |
检测到故障后,系统要有"体面的姿势"。重试是对付瞬时故障(一次总线冲突、一位传输错误)的第一反应,但要带退避与上限——无限重试本身就是新故障。降级是功能损失的有序化:主传感器失效切备用通道;无线连不上改本地缓存;精度达不到就报"精度降级"而不是硬报数。安全态是最后防线:电机系统故障时所有输出关断(硬件层面保证,不依赖软件清醒)、加热设备故障时停止加热、门锁系统故障时明确"保持当前开闭态"并报警。安全态的定义要写进需求文档——"出问题时安全"这句话必须变成可验证的具体状态。

背景:一片区五十台户外数据采集器,无人值守运行,要求"设备异常后自愈并留下可分析的痕迹"。操作:按本节方法论搭三层体系。检测层——通信超时(连续三次上报失败)、供电电压监控(欠压即记录并降频)、采样值范围检查、栈水位巡检。响应层——通信失败按指数退避重试五次,失败后切备用 APN 再试一轮;仍失败则进入"离线模式",数据本地缓存(环形存储,空间按七天流量预留),每小时重试上线;栈水位超阈值或连续自检失败,主动软复位。证据层——每次复位原因(上电、看门狗、软件复位)与复位前的最后二十条事件(最后报文、最后采样、电压记录)存入由备份域保护的记录区;上线成功后优先上报。结果:三个月现场运行,五十台设备共发生十一次故障,其中八次靠重试与降级自动恢复、用户无感;两次看门狗复位,依据留档的事件记录定位为供电波动,加装滤波电容后消除;一次反复复位,事件记录指向固件缺陷,远程升级后修复。**自愈率百分之百存活,且每次异常都有迹可循。**解读:这套体系的精髓不在任何单点技术(都是前几章的常规操作),而在"检测、响应、证据"三层的系统性组装——可靠性是体系属性,不是特性开关。变式:若设备控制的是危险对象(加热器、阀门),安全态层必须前移为第一优先级,且由硬件电路保证——软件自愈体系再完善,也不能成为安全态的依赖。
个体层面的容错之外,批量产品还需要统计层面的可靠性视角。电子产品的失效率随时间呈典型的"浴盆曲线":早期失效期(焊接缺陷、器件先天不良,失效率高且快速下降)、偶然失效期(随机故障,失效率低而平稳)、耗损失效期(老化累积,失效率重新爬升)。这条曲线直接指导两个工程动作。其一,老化筛选:出厂前让设备在加温环境连续运行 24 到 72 小时,把早期失效期"烧"在厂内——活过筛选期的设备恰好进入低失效的平稳区再出货,这是牺牲少量成本换取现场故障率大降的经典买卖。其二,寿命件的预防性维护:电解电容、继电器、纽扣电池这些耗损件,按手册寿命的一半制定更换周期,别等浴盆曲线右壁爬上来。软件侧对应的一课是:现场故障统计要分桶记录(早期失效还是耗损失效的处理路径完全不同),返回修的机器别修完就完——每台返修设备都是一条免费的失效数据。
这是看门狗设计里最常被问错方向的数字题。正确推导顺序是:先量主循环的最坏一轮耗时(7.3 的时间账),再留出裕量——喂狗周期取最坏轮时的两到三倍。设太短,主循环偶发的重活(一轮大计算、一段 Flash 写入)错过喂狗点,系统被误杀重启,故障现象反而是"随机重启";设太长,真卡死后的恢复时间跟着变长,危害窗口拉大。两个工程细节常被忽略:其一,Flash 写入、射频发射这类"合法长任务"要单独评估,必要时在任务内部分段喂狗或临时延长窗口;其二,喂狗周期与低功耗唤醒周期的配合——深度睡眠时某些看门狗仍在计时,睡一觉醒来发现被咬了,是低功耗产品特有的"起床先挨打"现象,配置时要确认看门狗在目标睡眠模式下的行为。