一个让人抓狂的\”随机死机\”
前年做一款便携式数据采集终端,主控和一颗前端传感器通过串行总线通信,整机要求待机功耗低于50微安。主控大部分时间处于深度休眠,靠传感器的事件中断引脚把主控唤醒,醒来后再发起一次总线读取。
样机阶段一切正常,小批量试产时出现了一个诡异现象:大约每十几台里有一台,在待机几分钟到几十分钟后彻底\”睡死\”,按键无响应,只能拔电池。更让人头疼的是,把出问题的板子拿回实验室,接上调试器、打开串口打印,它又一切正常,连续跑几天都不出问题。一断开调试器,过一阵子又死。
这种\”一测就好、一放就坏\”的故障最消耗耐心。我们一开始怀疑是焊接虚焊、电池接触不良、晶振起振余量不够,把能换的都换了,问题依旧。直到有天晚上,同事无意中用示波器长时盯着唤醒中断线和总线两根线,才抓到关键画面:死机前,唤醒中断线上出现了一个极窄的脉冲,宽度只有几十纳秒,而就在这个脉冲出现的同一时刻,总线两根线正被前端器件拉低——也就是说,主控被这个毛刺唤醒的瞬间,恰好撞上了前端器件正在占用总线。
主控醒来后第一件事就是去读传感器,可这时候总线还被对方占着,主控发出的起始时序被对方当成噪声,双方各说各话,总线进入一种\”谁都不肯松手\”的僵持状态。主控的通信外设等不到应答,固件里又没有超时退出机制,于是卡在等待循环里,再也回不到休眠,功耗从几十微安飙到几毫安,电池很快被抽干。用户看到的就是\”睡死\”。
这个坑让我彻底改变了对\”唤醒\”这件事的理解:唤醒不是一个瞬间动作,而是一段和外部世界状态赛跑的过程。你永远不知道醒来那一刻,总线上正在发生什么。
为什么\”总线空闲\”和\”低功耗唤醒\”天生打架
要理解这个冲突,得先把两件事拆开看。


