2、链路训练与速度协商:Polling状态详解、速度协商的握手过程、我遇到过的协商失败案例

2.1 Polling状态——链路训练的“起跑线”

LTSSM状态机里,Polling状态是个很有意思的环节。说白了,它就是链路两端互相“打招呼”的阶段。我刚开始接触USB时,总觉得这步很简单——不就是发个信号嘛。后来踩了坑才明白,这里面的门道多着呢。

Polling状态的核心任务就两个:

  • 检测对端是否存在——看看对面有没有设备接着
  • 确定初始速度——大家商量好用多快跑

你想想看,两根线刚插上,谁都不知道对方是什么水平。这时候就得靠Polling状态来“破冰”。

关键点:Polling状态必须在100ms内完成。超时了?LTSSM会直接跳回Detect状态重新来。我见过不少板子就是因为这个超时设得太紧,导致兼容性问题。

2.2 速度协商的握手过程——谁先说话?

速度协商的握手,其实有点像两个人见面握手——你先伸手,我回应,然后大家确认力度合适。

具体流程是这样的:

  1. Host先发TS1序列——相当于说“喂,有人吗?”
  2. Device收到后回TS2序列——“我在呢,你什么速度?”
  3. 双方交换速度能力——通过TS1/TS2里的Speed Change字段
  4. 达成一致——选一个双方都支持的最高速度

嗯,这里要注意。TS1和TS2序列里有个叫“Speed Change”的bit,它决定了这次协商是继续还是结束。我记得有一次调试,发现Device老是回NACK,抓了波形一看——Speed Change bit没置对。这种问题,光看代码是看不出来的。

我的习惯:每次做速度协商调试,我都会先抓一下TS1/TS2序列的波形。看看Speed Change bit是不是按预期翻转。这招帮我省了不少排查时间。

2.3 我遇到过的协商失败案例

做USB验证这些年,协商失败的案例我见过不少。挑两个典型的说说。

案例一:信号质量问题导致Polling超时

有一次,客户反馈说他们的USB 3.0设备在特定主板上老是枚举失败。我排查了半天,发现Polling状态总是超时。抓了眼图一看——信号质量太差了,抖动大得离谱。

原因是什么?PCB走线没做阻抗匹配。Host端发出的TS1序列,到了Device那边已经变形了。Device根本认不出来,自然没法回应。

解决办法:调整PCB走线,加了一对AC耦合电容,问题就解决了。说白了,很多协商失败的问题,根源都在物理层。

案例二:固件逻辑Bug导致速度降级

另一个案例更有意思。设备能正常枚举,但速度始终跑在5Gbps,上不了10Gbps。我一开始以为是信号问题,查了一圈发现眼图挺好的。

后来仔细看了固件里的速度协商逻辑——原来Device在收到Host的TS1后,判断速度的算法写错了。它总是把自己降级到5Gbps,哪怕Host支持10Gbps。

避坑指南:我曾经因为一个if-else的顺序问题,让整个团队多花了两周时间排查。速度协商的代码,一定要仔细检查优先级逻辑。别让低级错误浪费大家的时间。

2.4 知识体系图:Polling与速度协商的核心逻辑

下面这张图,是我自己总结的Polling状态与速度协商的完整流程。你可以把它当作调试时的参考地图。

Polling状态与速度协商核心流程 Polling状态进入 检测到对端? 超时 → 跳回Detect状态 Host发送TS1序列 (含Speed Change bit) Device回应TS2 (确认速度能力) 速度协商完成 (选择双方支持的最高速度) 进入Configuration状态 状态 决策 Host动作 Device动作 完成 异常处理

2.5 调试建议

最后,分享几个我自己的调试习惯:

  • 先看物理层——眼图、抖动、信号幅度。很多协商问题都是信号质量引起的。
  • 抓TS1/TS2序列——用逻辑分析仪或示波器抓一下,看看Speed Change bit是不是对的。
  • 检查超时配置——Polling超时时间别设得太紧,留点余量。
  • 固件代码逐行审查——特别是速度判断的if-else逻辑,别让顺序坑了你。

一个小技巧:我习惯在固件里加个调试打印,把每次协商的速度值打出来。这样不用抓波形,就能快速定位是Host还是Device的问题。省时省力。

好了,Polling状态和速度协商就聊到这儿。下一节我们聊聊Configuration状态——链路训练里最容易被忽视的环节。


公众号:蓝海资料掘金营,微信deep3321