3. USB 设备状态机:状态定义与转换条件

USB 协议定义了一套严谨的设备状态机,用于管理设备从物理连接到正常工作的完整生命周期。理解这六个状态及其转换条件,是分析枚举日志、定位故障的根本前提。任何枚举失败,最终都可以归结为设备未能正确进入或停留在某个预期状态。

3.1 六种核心状态定义

USB 2.0 规范明确定义了以下六种设备状态,设备在任何时刻只能处于其中一种状态:

状态名称 状态标识 核心特征 电源要求
Attached 连接态 设备物理连接到主机或 Hub 端口,VBUS 供电生效 VBUS (4.75V-5.25V)
Powered 供电态 设备检测到 VBUS,内部上电复位完成,可响应总线事件 VBUS + 内部稳压
Default 默认态 设备接收到复位信号(SE0),默认地址为 0,可接收控制传输 VBUS + 100mA 最大
Address 地址态 主机分配唯一非零地址,设备以新地址通信 VBUS + 100mA 最大
Configured 配置态 主机发送 Set Configuration 请求,设备加载描述符并进入功能模式 VBUS + 配置所需电流
Suspended 挂起态 总线空闲超过 3ms,设备进入低功耗模式 VBUS + 2.5mA 最大
故障排查要点: 在枚举日志中,如果看到设备反复在 Default 和 Address 之间跳转,通常意味着地址分配失败或设备未能正确响应 Set Address 请求。这是最常见的枚举故障模式之一。

3.2 状态转换条件与流程图

状态转换由主机和设备的交互事件驱动。下图展示了完整的六状态转换关系,每个箭头代表一个明确的触发条件:

USB 设备状态机转换图 USB 设备状态机转换图 Attached (连接态) Powered (供电态) Default (默认态) Address (地址态) Configured (配置态) Suspended (挂起态) VBUS 检测到 总线复位 (SE0 ≥ 10ms) Set Address 成功 Set Configuration 成功 Set Configuration 总线空闲 ≥ 3ms 总线空闲 ≥ 3ms 总线空闲 ≥ 3ms 唤醒信号 (Resume) 说明:实线箭头为正向转换,虚线箭头为唤醒恢复路径。所有状态均可进入 Suspended,但仅 Powered 可被唤醒。

3.3 状态转换条件详解

每个状态转换都有明确的触发条件,这些条件在枚举日志中表现为特定的事件序列:

3.3.1 Attached → Powered

  • 触发条件:设备检测到 VBUS 电压稳定在 4.75V 以上,且内部上电复位(POR)完成。
  • 日志特征:Hub 检测到端口状态变化(Port Change),主机读取端口状态寄存器。
  • 故障点:VBUS 电压不足、设备内部电源管理 IC 故障、去耦电容短路。

3.3.2 Powered → Default

  • 触发条件:主机通过 Hub 向端口发送复位信号(SE0,即 D+ 和 D- 同时拉低),持续时间至少 10ms。
  • 日志特征:主机发送 SetPortFeature(PORT_RESET),随后检测到复位完成位。
  • 故障点:复位信号被 Hub 或线缆衰减、设备 D+/D- 线路短路、设备未正确识别复位。
关键指标:复位信号持续时间必须在 10ms 到 20ms 之间。过短(<10ms)设备可能不响应,过长(>20ms)可能导致设备误判为挂起。

3.3.3 Default → Address

  • 触发条件:主机通过默认地址 0 发送 Set Address 请求,设备在收到后返回 ACK,并立即切换到新地址。
  • 日志特征:主机发送 SETUP(Set Address, addr=0x02),设备回复 ACK。
  • 故障点:设备未正确解析 Set Address 请求、地址冲突、设备固件未实现地址切换。

3.3.4 Default/Address → Configured

  • 触发条件:主机发送 Set Configuration 请求,携带配置描述符中的 bConfigurationValue。
  • 日志特征:主机发送 SETUP(Set Configuration, value=0x01),设备回复 ACK 并加载功能驱动。
  • 故障点:设备不支持所选配置、配置描述符解析错误、设备内部功能模块初始化失败。

3.3.5 任意状态 → Suspended

  • 触发条件:总线空闲(无 SOF 帧或数据活动)持续超过 3ms。
  • 日志特征:主机停止发送 SOF,设备进入低功耗模式。
  • 故障点:主机进入系统挂起、Hub 端口电源被切断、设备未正确进入低功耗导致电流超标。

3.3.6 Suspended → Powered

  • 触发条件:设备检测到 Resume 信号(K 状态,即 D+ 高、D- 低)持续 20ms,或主机主动恢复总线活动。
  • 日志特征:主机发送 ClearPortFeature(PORT_SUSPEND),设备退出低功耗模式。
  • 故障点:设备无法被唤醒、唤醒信号被 Hub 过滤、设备固件唤醒逻辑异常。

3.4 状态转换与枚举流程的对应关系

将状态机映射到实际的枚举流程中,可以更直观地理解每个阶段:

枚举阶段 设备状态 主机操作 关键请求
物理连接 Attached → Powered 检测端口状态变化 GetPortStatus
复位 Powered → Default 发送复位信号 SetPortFeature(PORT_RESET)
获取设备描述符 Default 读取前 8 字节 GetDescriptor(DEVICE, 0)
分配地址 Default → Address 分配非零地址 Set Address
获取完整描述符 Address 读取全部描述符 GetDescriptor(DEVICE/CONFIG)
配置设备 Address → Configured 选择配置 Set Configuration
常见陷阱: 有些设备在 Default 状态下会错误地响应非零地址的请求,这通常是因为固件未正确实现地址过滤。在枚举日志中,如果看到设备在 Set Address 之前就回复了非默认地址的请求,说明设备状态机实现有缺陷。

3.5 状态机故障排查速查表

当枚举失败时,根据设备卡住的状态可以快速定位问题范围:

卡住状态 典型日志特征 可能原因 排查方向
Powered 端口状态显示连接,但无复位事件 Hub 未检测到设备、复位信号未发出 检查 Hub 驱动、端口电源、线缆完整性
Default 复位完成,但 GetDescriptor 超时 设备未响应控制传输、地址 0 冲突 检查设备端点 0 实现、USB 时钟、D+/D- 上拉电阻
Address Set Address 成功,但后续请求无响应 设备未切换到新地址、地址被占用 验证设备地址切换逻辑、检查地址池
Configured Set Configuration 成功,但功能异常 配置值不匹配、内部初始化失败 检查配置描述符、设备功能模块
Suspended 总线空闲后设备无法恢复 唤醒信号未识别、低功耗模式锁死 检查 Resume 信号、设备唤醒逻辑