“无法识别的 USB 设备”,系统是如何识别的?
你可以看看我这篇文章,通过USB分析仪抓到的数据,可以很直观的看到USB设备插入之后发生的一系列动作。
利用USB分析仪排查HID故障记录(1)——设备无法识别
- 问题:无法识别
我在使用一个新开发的USB HID设备时,发现设备接入主机后无法识别,在设备管理器中显示“未知设备”。

我重新插拔了设备、更换了端口、重启电脑以及更换电脑还是无法识别到设备。设备固件中的调试日志只能输出“设备描述符请求失败”的模糊信息,没有办法指明故障点。因此,我想到了之前购入的USB分析仪,想通过分析仪来查看一下设备枚举过程。
- 理论基础:USB枚举与设备描述符
USB枚举是主机识别并配置设备的核心过程。在此过程中,主机通过控制传输,逐步请求设备的一系列描述符,包括设备描述符,配置描述符(包括接口描述符与端点描述符)与字符串描述符。以下是一个正常的USB设备在USB分析仪中显示的枚举流程:

对于HID类设备,主机还将发送HID请求如Set Idle等,并继续获取报告描述符。

USB分析仪还提供了对HID报告描述符的解析,点击HID请求“Get Report Desc”即可进行查看对应解析。

枚举过程中,第一个关键请求是获取设备描述符(Get Device Descriptor)。设备描述符是设备的身份摘要,其bLength字段明确规定了该描述符的总长度。USB协议规定,全速/高速设备的设备描述符长度固定为18字节(0x12)。若此长度值错误,主机将无法正确解析后续字段,导致枚举流程在初始阶段即告中断。此外,设备描述符还包含VID、PID等重要信息,若这些信息错误,可能导致加载错误的驱动,引发设备异常。若端点0支持的最大数据包长度错误,获取后续描述符时将发生通信超时或数据错误,导致枚举过程中断。
| 字段名 | 长度/字节 | 地址偏移 | 说明 |
|---|---|---|---|
| bLength | 1 | 0 | 设备描述符长度,固定为18(0x12) |
| bDescriptorType | 1 | 1 | 描述符类型,0x01 |
| bcdUSB | 2 | 2 | USB规范版本号(BCD码) |
| bDeviceClass | 1 | 4 | 类代码 |
| bDeviceSubClass | 1 | 5 | 子类代码 |
| bDeviceProtocol | 1 | 6 | 协议代码 |
| bMaxPacketSize | 1 | 7 | 端点0支持的最大数据包长度 |
| idVendor | 2 | 8 | 供应商ID |
| idProduct | 2 | 10 | 产品ID |
| bcdDevice | 2 | 12 | 设备版本号 |
| iManufacturer | 1 | 14 | 供应商字符串描述符索引 |
| iProduct | 1 | 15 | 产品字符串描述符索引 |
| iSerialNumber | 1 | 16 | 设备序列号描述符索引 |
| bNumConfigurations | 1 | 17 | 可能的配置数 |
- 问题排查
3.1 连接分析仪,捕捉枚举流程

先将USB分析仪连接主机,打开分析仪的配套软件,选择“只显示新插入设备”,然后,将设备接入分析仪。此时,分析仪只会捕捉该设备与主机的通信数据。

3.2 枚举卡顿:描述符长度无效
查看枚举流程时,发现枚举卡在获取设备描述符这一步骤。点击最后一个获取设备描述符的标准请求,我发现分析仪软件解码视图中高亮显示了设备回复的描述符bLength字段,其值为16(0x10),并被明确标记“Invalid”。

根据USB协议,高速设备的设备描述符长度固定为18字节(0x12),因此我查找到了问题所在。
- 修正问题
根据分析仪的定位,我审查了设备固件中设备描述符数组的定义。发现代码中确实将设备描述符的bLength错误地定义为16(0x10)。修正为18(0x12)后,重新烧录固件,设备枚举成功,被正确识别并恢复正常通信。
