012、显性位与隐性位竞争时的边沿竞争问题
一个让我半夜爬起来改板子的现场
几年前做一个多节点采集系统,主控和几个从节点挂在同一条差分总线上,速率不高,线也不长,实验室里跑了一整天都稳。小批量装到现场后,白天没事,到了晚上某个时段,主控就开始间歇性报"总线错误",概率大概几百分之一帧。更邪门的是,把示波器探头往总线上一搭,故障率立刻下降。探头一撤,又回来了。
那几天我一直在查软件:中断延迟、收发切换时序、FIFO水位。后来实在没辙,用一台带长存储的示波器,设了触发条件盯了一整夜,终于抓到一帧:在仲裁阶段,某一位的边沿位置上,总线电平出现了一个很窄的毛刺,宽度只有几十纳秒,刚好卡在采样点附近。主控采到了隐性,从节点采到了显性,双方对"谁赢了仲裁"的判断出现了分歧。主控以为自己输了、退出了发送,从节点以为自己还在跟别人竞争,结果两边对总线的后续状态理解完全错位。
那次之后我才真正把"显性位和隐性位竞争"这件事从"逻辑上谁优先"的层面,下沉到"物理边沿上到底发生了什么"的层面。逻辑层面人人都懂:显性会盖住隐性,谁发隐性谁就退出。但物理层面,边沿不是理想的阶跃,它有时间、有斜率、有反射、有延迟,而采样点就落在这段不确定的窗口里。这就是边沿竞争问题的本质。
逻辑上的确定性,物理上的不确定性
先把逻辑模型摆清楚,因为后面所有坑都是从这个模型的"理想假设"里漏出来的。
总线是线与结构:一个节点发显性、另一个发隐性,总线呈现显性。所有节点在每个位时间的采样点读回总线,如果自己发的是隐性却读回显性,说明自己输了仲裁,主动退出。这套机制在逻辑上无懈可击,前提是——所有节