Polling 状态概览:它在链路训练中的角色和常见问题
咱们先聊聊 Polling 状态。说白了,这是链路训练里最磨人的一个环节。我记得刚接手 PCIe 调试那会儿,十次卡死有七八次都卡在 Polling 上。为什么?因为它的工作模式决定了——它要反复试探对方,确认对方准备好了没有。
Polling 状态在链路训练状态机(LTSSM)里排第二位,在 Detect 之后。Detect 确认物理连接存在,Polling 就要开始握手了——发训练序列,收训练序列,看看能不能建立基本的速度协商。嗯,你可以把它想象成两个人初次握手:先把手伸出去,握一下,松一点,再握实。
这个过程本身不复杂,但坑特别多。我带你拆开看看。
Polling 干的活到底是什么?
Polling 阶段的目标就一个:让链路的发送端和接收端对齐基本的比特率和字符边界。它不涉及链路宽度协商或均衡,那些是后面的事。Polling 只关心——
- 发出 TS1 训练序列,周期性重复。
- 等待对方回复 TS1 或 TS2。
- 如果收到连续的、符合规范的 TS 序列,就认为链路质量达标。
- 然后跳转到 Configuration 状态,开始宽度的协商。
这是标准流程。但实际跑起来,卡在 Polling 几乎成了家常便饭。
| 子状态 | 动作 | 常见退出条件 |
|---|---|---|
| Polling.Active | 发送 TS1,等待接收 | 收到连续的 8-16 个 TS1 或 TS2 |
| Polling.Configuration | 发送 TS2,协商基本速度 | 完成速度协商后跳转 Configuration |
| Polling.Compliance | 进入兼容性测试模式 | 收到退出指令或超时(通常 2ms) |
| Polling.Loopback | 进入回环测试模式 | 收到回环退出序列 |
你可能会问:这么多子状态,哪个最容易卡?我个人经验,Polling.Active 排第一,Polling.Configuration 排第二。
为什么 Polling 容易卡?
原因归纳下来就几个:
- 信号质量差:接收端看到的 TS 序列全是噪声,没办法锁定比特边界。
- 时钟恢复失败:CDR(时钟数据恢复)没锁定,采样点偏移,收到的数据全是错的。
- 对方设备行为异常:比如对面在某个子状态超时后重复重试,或者根本没有发出正确的 TS 序列。
- 电气参数不匹配:驱动强度、去加重、接收端均衡系数没对准。
核心判断:Polling 卡顿的本质是“收发双方没对上眼”。只要有一方没收到有效的 TS 序列,链路就卡在原地不动。
我曾经在一个项目里遇到过特别奇葩的情况:两片 FPGA 直接对接,PCIe 链路死活过不了 Polling。示波器抓差分信号,波形看着没问题,但协议分析仪显示接收端一直在报“符号锁定失败”。查了三天,最后发现是参考时钟有 300ppm 的偏差——超出规范允许的 ±300ppm 上限。这叫“压线出界”,你说气不气人?
Polling 状态卡顿的表现
遇到卡顿,系统表现通常很一致:
- LTSSM 状态寄存器一直显示 0x01(Polling)。
- 数据链路层始终不跳转,链路未激活。
- 驱动或操作系统超时后报错:
PCIe link training timeout。 - 部分设备会触发链路复位,然后重试——但重试还是卡在同一个地方。
小技巧:用逻辑分析仪抓 LTSSM 状态跳转,如果看到 Polling→Polling→Polling 不变化,先检查物理层信号质量,别急着调软件参数。
Polling 阶段的调试切入点
我个人习惯按这个顺序排查:
- 查时钟:测量参考时钟频率和抖动,确保在 ±300ppm 以内。
- 看眼图:用示波器看接收端的眼图,张开度够不够,有没有 ISI 或噪声。
- 调均衡:如果眼图闭合,尝试调整接收端 CTLE/DFE 参数。
- 抓协议:用协议分析仪看 TS 序列是否正确,是不是连续 16 个相同的 TS1。
- 看寄存器:读 PCIe 配置空间的 Link Status 寄存器,确认当前速度、宽度、状态。
注意:不要一上来就改链路速率或强制跳转状态。跳过 Polling 可能会导致后续 Configuration 阶段失败得更隐蔽。
下面这张图总结了 Polling 状态在 LTSSM 中的位置以及常见的卡顿原因。
避坑指南:那些年我踩过的 Polling 坑
我曾经被一个低级问题坑了两天——两根 PCIe 差分线在 PCB 上不等长,差了一百多 mil。当时理论计算出来的时延差不到 0.1UI,觉得无所谓。结果实际跑起来,Polling 总是偶尔过、偶尔不过,概率大概 30% 丢包。后来板子改版拉平等长,问题直接消失。
经验教训:Polling 阶段对信号完整性的敏感度极高。不要光看仿真,实物调试时一定要测眼图。眼图过不了,什么配置都白搭。
再一个常见的坑是:芯片内部的 CDR 锁定时间太长,超过了 Polling 阶段的超时时间。PCIe 规范要求从 Reset 退出到进入 Configuration 必须在 2ms 内完成,但某些芯片的 CDR 需要 1.5ms 才能锁定。这意味着留给 Polling 的窗口只有 500μs,稍微有点干扰就超时。我建议你拿到新芯片,先读一下 CDR Lock Time 的参数,心里有个底。
工具推荐:用 PCIe 协议分析仪的 “Eye Monitor” 功能可以直观看到每个 Lane 的眼图质量。我经常挂机让它连续跑 1 万次训练,看成功率。
最后说一个软件层面的思路。有些系统允许在固件里强制设置 Polling 的重试次数或超时时间。如果硬件上信号质量没问题,只是偶尔因为干扰丢一个 TS 序列,可以适当放宽超时阈值(比如从 2ms 放宽到 5ms)。但这招不能乱用——放宽太多,后级的 Configuration 也可能跟着出问题。
好了,Polling 状态概览就讲这么多。记住一点:碰到卡顿,先看物理层,再谈协议层。顺序走对了,问题至少能解决一半。