USB Control Transfer STALL 调试:Setup Packet、端点 0 与设备请求失败排查

诊断 USB Control Transfer STALL 错误:Setup Packet 字段、端点 0 行为、类请求、厂商请求、描述符失败、固件请求处理。

USB Control Transfer STALL, Setup Packet, 端点 0, USB 描述符失败, 厂商请求, USB 诊断, Vendor Request

USB Control Transfer 是枚举和设备管理的基础。它们读描述符、设地址、选配置、切接口、发类请求、跑厂商自定义命令。Control Transfer 一旦 STALL,用户可能看到 "USB device not recognized"、"control transfer failed"、"libusb control transfer error"、"endpoint zero stalled",或者固件升级工具停在初始化。

搜 "USB control transfer STALL"、"USB setup packet debugging"、"endpoint zero stall"、"GET_DESCRIPTOR failed"、"vendor request stalled" 一般都意味着故障发生在 Bulk / Interrupt / Isochronous 正常流量之前。

Bus Scope 在这个场景下有用,因为 Setup Packet 解释了请求。没有它,STALL 只是一个通用错误。

Control Transfer 里有什么

USB Control Transfer 分阶段:

  1. Setup 阶段
  2. 可选的数据阶段
  3. Status 阶段

Setup Packet 包含:

  • bmRequestType
  • bRequest
  • wValue
  • wIndex
  • wLength

这些字段定义了方向、请求类型、Recipient、请求码、描述符类型、接口、端点、期望数据长度。

设备 STALL,先看 Setup Packet。

端点 0 很特殊

端点 0 对每个 USB 设备都存在。枚举和控制操作都走它。端点 0 行为不对,主机可能根本绑不上正常驱动。

端点 0 失败表现为:

  • Device Descriptor 请求失败
  • Configuration Descriptor 读失败
  • String Descriptor 请求 STALL
  • SET_CONFIGURATION 失败
  • 类特定请求失败
  • 厂商命令失败

对自定义固件来说,端点 0 的正确性没有商量。

STALL 可能是合法的

不是每个 STALL 都是 Bug。设备对不支持的请求合法 STALL 是可以的。问题是:主机是不是本来就期望支持?设备状态允不允许这次请求?

例子:

  • 不支持的厂商请求:STALL 可能是对的
  • 非法的描述符索引:STALL 可能是对的
  • 枚举期间必须的类请求:STALL 可能破坏驱动绑定
  • 错误状态下的 DFU 请求:STALL 可能意味着状态机不匹配

含义取决于请求类型和时序。

描述符请求失败

描述符 STALL 在自定义 USB 协议栈里很常见。重点看:

  • wValue 里描述符类型错
  • 不支持的 String Index
  • Configuration 总长度对不上
  • 设备错误地返回了比请求少的数据
  • 设备不处理短的初始描述符读
  • 固件只假设了一种主机的请求模式

不同操作系统要描述符的顺序不一样。一台设备在 Linux 上能用,可能 STALL 掉 Windows 枚举期间发的某条请求。

类和厂商请求

类请求由 USB 类来解释。HID、CDC、DFU、Audio、Video、大容量存储、厂商自定义设备都有请求预期。

常见的例子:

  • HID GET_REPORT
  • HID SET_REPORT
  • CDC SET_LINE_CODING
  • CDC SET_CONTROL_LINE_STATE
  • DFU GETSTATUS
  • UVC probe/commit controls
  • 厂商自定义 Bootloader 命令

类请求 STALL 的话,看 wIndex 里的接口号是不是和目标接口匹配。组合设备常常因为主机把请求发给一个接口、固件处理了另一个而挂。

排查清单

按这个流程:

  1. 从插入开始抓
  2. 找第一条 Control Transfer STALL
  3. 解码 Setup Packet 字段
  4. 判断请求是 Standard、Class 还是 Vendor
  5. 判断 Recipient:Device、Interface、Endpoint 还是 Other
  6. 检查 wValuewIndexwLength
  7. 和描述符及当前设备状态对比
  8. 判断 STALL 是预期还是致命
  9. 找恢复请求比如 Clear Feature 或 Reset
  10. 跨平台行为不一样时对比主机的请求顺序

最终诊断

光 USB Control Transfer STALL 这一个信息本身不够。Setup Packet 才是诊断锚点——它告诉你哪条请求失败、Recipient 是谁、期望多少数据、设备状态让这次请求合不合法。

Bus Scope 把端点 0 和 Setup Packet 的证据摆出来——固件、驱动、QA 团队可以精确地调试 Control Path 失败。