把一次难复现故障变成可重复实验
旧记录整理:这篇不是某个芯片的结论,而是一套处理“偶尔发生”问题的工作方法。
设备在现场偶尔把温度显示为 0,重启后又恢复。最初的描述只有“每天大概一次”,参与者分别怀疑传感器、线缆、固件和电磁干扰。四个猜测都可能成立,但同时追逐只会制造更多变量。我先把目标改成:不急着修,先让它在桌面上一小时内稳定出现。
建立事实表
每次异常记录固件版本、板号、供电、环境温度、运行时长、最后十次 I2C 返回码和任务水位。日志不再只打印最终数值,而是区分“读取失败”“校验失败”和“数值确实为零”。这一改动立即排除了业务层换算:零值来自失败分支的默认初始化,而不是传感器真的报告零度。
接着给每次总线事务分配序号,逻辑分析仪触发信号也带同一个序号。软件日志与波形可以一一对应。异常样本显示,从设备没有完成 ACK,但恢复代码只重试读操作,没有重新初始化总线。
缩短复现路径
现场一整天一次的概率太低。我逐项放大条件:把采样间隔从十秒缩到一百毫秒,周期性切换旁路负载,在读取前后插入可控延迟,并用继电器制造短暂接触波动。只有“负载切换发生在起始条件附近”显著提高故障率,十分钟即可出现。
这不是证明供电一定有问题,而是得到一个可重复入口。示波器随后看到传感器端电压短暂下降,总线的 SDA 保持低电平。驱动超时退出后,总线没有执行恢复时钟,因此之后每次读取都失败,直到整机重启。
修复分两层
硬件层增加去耦并调整供电路径,降低触发概率;软件层实现总线恢复:释放控制器、手动输出最多九个 SCL 脉冲、生成停止条件、重新初始化驱动,然后丢弃第一笔读数。恢复过程有独立计数器,超过阈值才上报设备故障。
正常读取 -> 超时 -> 总线恢复 -> 探测设备
├─ 成功:丢弃首样本并继续
└─ 失败:退避并上报
我没有用无限重试掩盖错误。每次恢复都会保留原因和耗时,维护端可以看见问题是否仍在增长。
反证与回归
- [x] 在原固件上用故障注入十分钟内复现
- [x] 仅改软件后可自动恢复且没有输出伪零值
- [x] 仅改硬件后触发率显著下降
- [x] 软硬件同时修改后持续运行四十八小时
- [x] 拔掉传感器时仍能进入明确的永久故障状态
- [x] 其他 I2C 设备在恢复时不会被错误复位
这套方法的核心
偶发故障需要的是概率工程:先精确定义失败,再寻找能提高发生率的变量,最后让修复接受同一套触发条件。日志必须能区分“没有数据”和“数据为零”,测量工具需要与软件事件对齐。只要故障能被主动制造,它就不再神秘;只要修复能在原触发器下通过,结论也就不再依赖运气。
评论区