4. USB枚举过程详解:复位、获取描述符、地址分配、配置选择
USB枚举是主机(Host)识别并配置新接入设备的核心协议过程。枚举由主机软件(USB驱动程序栈)发起,设备被动响应。整个过程涉及总线状态变化、控制传输(默认管道)以及设备固件的正确描述符返回。本章深入解析枚举的四个关键阶段:总线复位、获取描述符、地址分配和配置选择。
4.1 枚举全流程概览
从设备插入根集线器端口到设备就绪,主机侧依次执行以下步骤。下表总结了各阶段的核心动作与协议特征:
| 阶段 | 触发条件 | 主机动作 | 设备响应 | 传输类型 |
|---|---|---|---|---|
| 1. 复位 | 集线器检测到端口状态变化(D+/D-信号) | 发送复位信号(SE0状态持续≥10ms) | 复位内部状态机,默认地址0就绪 | 总线状态(非数据包) |
| 2. 获取描述符 | 复位完成后主机收到设备连接确认 | 发送Get_Descriptor(Device)请求 | 返回设备描述符(前8字节或完整18字节) | 控制传输(默认管道) |
| 3. 地址分配 | 主机解析设备描述符后 | 发送Set_Address请求 | 保存新地址,返回ACK后切换地址 | 控制传输(默认管道) |
| 4. 配置选择 | 地址分配完成,主机获取完整配置信息 | 发送Set_Configuration请求 | 按配置值初始化功能单元 | 控制传输(默认管道) |
4.2 总线复位:枚举的起点
当根集线器检测到新设备插入(D+线被拉高,全速/高速设备)或D-线被拉高(低速设备)时,主机首先通过集线器端口发送复位信号。复位信号将D+和D-同时拉低(SE0状态)并维持至少10ms。设备检测到SE0后,执行以下内部操作:
- 清空所有端点状态和缓冲区。
- 将USB设备地址重置为0x00。
- 将端点0(默认控制端点)配置为最大包长度(全速设备为64字节,低速设备为8字节)。
- 进入默认状态(Default State),等待主机发送Setup包。
复位完成后,主机通过读取集线器端口状态寄存器确认设备已处于“已连接且复位完成”状态,随后开始第一次控制传输。
4.3 获取描述符:主机识别设备身份
复位完成后,主机通过默认地址0x00向设备的端点0发送Get_Descriptor(Device)请求。这是一个标准控制传输,包含Setup阶段、数据阶段(可选)和状态阶段。主机通常先请求设备描述符的前8个字节,以获取端点0的最大包长度(bMaxPacketSize0),然后根据该长度重新调整后续传输的包大小。
设备描述符的关键字段如下:
| 偏移 | 字段 | 大小 | 说明 |
|---|---|---|---|
| 0 | bLength | 1字节 | 描述符长度(固定为18) |
| 1 | bDescriptorType | 1字节 | 设备描述符类型码(0x01) |
| 2-3 | bcdUSB | 2字节 | USB规范版本号(BCD码,如0x0200表示USB 2.0) |
| 4 | bDeviceClass | 1字节 | 设备类代码(0x00表示在接口描述符中定义) |
| 7 | bMaxPacketSize0 | 1字节 | 端点0最大包长度(8/16/32/64) |
| 8-9 | idVendor | 2字节 | 厂商ID(由USB-IF分配) |
| 10-11 | idProduct | 2字节 | 产品ID(厂商自定义) |
4.4 地址分配:设备获得唯一身份
主机解析设备描述符后,通过Set_Address请求为设备分配一个唯一的USB地址(范围1~127)。该请求同样通过默认地址0x00发送。设备收到请求后,必须:
- 立即返回ACK(在控制传输的状态阶段)。
- 在状态阶段完成后,在2ms内切换到新地址。
- 切换完成后,所有后续通信使用新地址。
主机在发送Set_Address后,会等待至少2ms(USB规范要求),然后使用新地址发送下一个请求。如果主机过早使用新地址,设备可能尚未完成切换,导致传输超时。
4.5 配置选择:设备功能激活
地址分配完成后,主机继续获取设备的配置描述符、接口描述符和端点描述符。主机通过多次Get_Descriptor请求获取完整配置信息(配置描述符的总长度由wTotalLength字段指示)。
获取所有描述符后,主机根据设备类、接口数量和端点能力,选择一个合适的配置值(bConfigurationValue),发送Set_Configuration请求。设备收到该请求后:
- 根据配置值初始化对应的功能单元(如启用端点、分配缓冲区)。
- 将设备状态从“地址状态”(Address State)切换到“配置状态”(Configured State)。
- 此时设备可以开始正常的数据传输(中断、批量、同步)。
如果主机发送的配置值等于0,设备将进入“未配置”状态,所有非控制端点被禁用。
4.6 枚举过程中的DMA协同策略
在枚举的每个阶段,DMA引擎的行为需要与USB控制器的状态机同步。以下是各阶段的DMA协同建议:
| 枚举阶段 | DMA状态 | 操作建议 |
|---|---|---|
| 复位 | 暂停 | 清空所有与USB相关的DMA描述符链,等待复位完成中断 |
| 获取描述符 | 仅允许控制传输DMA | DMA通道0(控制)预置描述符接收缓冲区,其他通道禁用 |
| 地址分配 | 暂停(2ms窗口) | Set_Address状态阶段后,DMA插入2ms等待,不发起新传输 |
| 配置选择 | 重配置 | 根据Set_Configuration的值,动态分配DMA通道到对应端点 |