超时定义与分类:协议层、物理层、应用层
讲PD协商超时之前,咱们得先把“超时”这个事说清楚。你想想看,PD通信就像是两个人打电话——你说一句,我等一句。如果对方迟迟没回音,你总得有个等待上限吧?这个上限,就是超时。
但在实际项目中,超时远不止“等太久”那么简单。我记得刚做PD协议栈那会儿,有一次产品死活进不了供电模式,日志里全是超时错误。我一查,发现是物理层信号抖动导致计时器误触发。嗯,从那以后,我把超时分了三个层次来对待,问题就好定位多了。
什么是PD协商超时?
PD协商超时,说白了就是CC线上的消息传输没在规定时间内完成。USB PD 3.0规范里对每个消息的收发间隔、重试次数、硬复位条件都有明确的时间要求。一旦超时,双方就会进入错误恢复流程,比如降级、断开或复位。
超时的三层分类
我个人习惯把超时按协议栈的层级切一刀。这样做的好处是:出了故障,先看日志里超时报文在哪个层触发,直接定位到对应模块。下面这张图可以帮大家建立整体印象——
物理层超时
物理层是PD通信的“地基”。它负责BMC编码、数据传输速率、电压摆幅这些东西。物理层超时通常发生在微秒级别,比如PLL锁定超时、BMC接收码元长度超出范围。
我在项目中遇到过一种坑:CC线缆太长,寄生电容太大,导致BMC码元边缘变缓,接收端采到的位宽漂移,然后触发码元超时。你查上层报文全是“NoResponse”,实际根源在物理层。所以啊,定位超时第一件事,先拿示波器看CC线上的波形。
| 超时名称 | 标称值 | 触发条件 |
|---|---|---|
| BMC_Symbol_Sync_Loss_Timer | 10 μs | BMC位宽超出 6.67% 容差 |
| PLL_Lock_Timer | 500 μs | PLL未能在指定时间内锁定 |
| TX_SOP_Timeout | 35 μs | 发送SOP序列后未收到SOP反馈 |
协议层超时
协议层处理的是消息格式、重试机制和状态转换。这一层的超时一般在百微秒到毫秒级别。USB PD规范里定义了很多专有计时器,比如HardResetTimer(24~30 ms)、BISTWaitTimer等。
我建议把协议层超时想象成“对话规则”:发一个请求,必须在T时间内收到回应。没收到?重试。重试n次还没收到?直接硬复位。我曾经在对接某款充电器时发现,它回复消息总比标准慢10毫秒,刚好卡在我们的重试窗口外。嗯,这就是协议层超时的典型场景——对方实现不标准。
应用层超时
应用层超时是最高层,对应PD的状态机。比如Source给Sink发了一个Source_Cap,Sink必须在SenderResponseTimer(500~1000 ms)内回复。如果Sink没回,Source就会认为超时,进入错误恢复流程。
另一个典型是PSTransitionTimer(现在叫空载超时?规范版本不同名字有差异)。想象一下:你刚协商好20V/3A,负载却还没启动,这时候若超过若干毫秒没有电流,Source就会认为负载掉了,自动切回5V。
三层超时如何联调排查?
说了这么多,你可能想问:现场出问题了,我怎么知道是哪一层?
- 先看日志时间戳:微秒级突变 → 物理层;百微秒到毫秒 → 协议层;秒级 → 应用层。
- 别信应用层错误包:有一次日志报“SoftReset”,我一查是物理层CRC错误导致协议重发,重发超时又触发软复位。要追根溯源,必须从最底层日志逆推。
- 用示波器抓CC线:物理层问题没有比这更直接的方法。你可能会看到高电平长时间不变——那就是死锁了。
- 对照规范计时器表:拿出USB PD spec,找到对应计时器的标称范围,确认你的固件是否设置正确。我遇到过供应商库把计时器值写死成1/10标准值的情况。
好了,超时的三层分类就聊到这儿。这玩意就像给病人分科——内科、外科、五官科。你分对了科,才可能对症下药。下次遇到PD超时问题,别急着改代码,先在脑子里过一遍:物理层波形正常吗?协议层重试窗口对吗?应用层状态机跑顺了吗?嗯,思路清楚,动手才快。