USB 控制传输 Status Stage 调试:零长度包、端点 0、SETUP/DATA/STATUS 与 STALL

USB 控制传输 Status Stage 问题、零长度包、端点 0 STALL、SETUP/DATA/STATUS 顺序、描述符请求、厂商命令失败的排查。

USB 控制传输, Status Stage, 零长度包, 端点 0, Setup Packet, USB STALL, USB 诊断

USB 控制传输看着很简单,直到设备在 Status Stage 挂了。用户搜 "USB control transfer status stage"、"zero length packet USB"、"endpoint zero stall"、"SETUP DATA STATUS USB"、"control transfer timeout"、"vendor request fails" 的时候,描述符能工作但某条命令 STALL 或者超时。

Bus Scope 在这个场景下有用,因为 Control Transfer 的失败要求看到所有阶段放在一起。光看 Setup Packet 不够,Data Stage 和 Status Stage 才能证明主机和设备是不是完成了这笔事务。

控制传输的阶段

一个 Control Transfer 通常有:

  • SETUP 阶段
  • 可选的 DATA 阶段
  • STATUS 阶段

Status Stage 通常用和 Data Stage 相反方向的一个零长度包,作为完成确认。

如果 Status Stage 失败,主机可能报超时,即便设备其实已经交换过数据。

零长度包的误解

零长度包在应用层并不自动等同于"没数据"。在 Control Transfer 里,它可能就是必须的 Status 握手。

常见错误:

  • 固件没 ACK Status Stage
  • 主机期望零长度 Status 包,收到了 STALL
  • 设备在应该空的 Status 上发了数据
  • 厂商命令完成了 Data Stage,但最后握手失败
  • 固件状态机忘了 Arm 端点 0

这些 bug 在自定义厂商命令和 Bootloader 里很常见。

端点 0 很特殊

端点 0 负责枚举和控制请求。如果端点 0 的状态被搞坏,整台设备都可能变得不稳。

症状:

  • 枚举开始但在后面的描述符上挂
  • 厂商请求能成功一次然后 STALL
  • Control Transfer 之后需要重新插拔
  • SET_ADDRESS 或 SET_CONFIGURATION 不稳
  • 走 Control Path 的 HID Feature Report 失败
  • DFU Detach 请求回了,但设备不切模式

Bus Scope 应该能看出端点 0 在 STALL 之后是否恢复,还是一直坏的。

IN 和 OUT 控制传输

控制方向会改变 Status Stage 的方向。

对 IN 请求:

  • 主机发 SETUP
  • 设备发 DATA
  • 主机发 Status OUT 零长度包

对 OUT 请求:

  • 主机发 SETUP
  • 主机发 DATA(如有)
  • 设备发 Status IN 零长度包

固件 bug 常常出在一个方向测得比另一个多的时候。

描述符 vs 厂商命令失败

标准描述符请求可能能工作,因为它们走的是经过充分测试的固件路径。厂商自定义请求可能挂,因为自定义 Handler 没处理好长度、方向、或 Status Stage。

证据:

  • bmRequestType
  • bRequest
  • wValue
  • wIndex
  • wLength
  • 实际数据长度
  • Status Stage 结果
  • STALL、NAK、超时或 Reset

Setup Packet 的字段必须和实际观测到的阶段行为一起解读。

排查清单

按这个流程:

  1. 抓完整的 Control Transfer
  2. 解码 SETUP 字段
  3. 识别传输方向
  4. 检查期望的数据长度
  5. 校验 Data Stage 字节
  6. 校验 Status Stage 方向
  7. 看零长度包
  8. 看 STALL 或超时
  9. 对比标准和厂商请求
  10. 保留端点 0 的恢复行为

最终诊断

USB Control Transfer 失败常常是 Status Stage 失败,不只是 Setup Packet 的问题。零长度包、端点 0 状态、方向、最后握手都很关键。

Bus Scope 让工程师能证明设备到底是死在 SETUP、DATA、STATUS、ZLP 处理、端点 0 恢复、还是厂商命令处理上。