USB协议栈分层:物理层、设备层、配置层、接口层、端点层
USB枚举过程并非由单一模块完成,而是由协议栈中不同层级分工协作、逐层推进的结果。理解各层在枚举中的职责,是移植适配设备描述符与地址分配逻辑的前提。USB协议栈从底向上分为五层:物理层、设备层、配置层、接口层、端点层。每一层对应一组特定的描述符与状态机,在枚举中承担不同的角色。
2.1 五层协议栈总览
下表总结了各层在枚举中的核心职责、关键描述符以及典型交互阶段:
| 协议层 | 枚举职责 | 关键描述符 | 交互阶段 |
|---|---|---|---|
| 物理层 | 检测设备连接、复位、建立信号通路 | — | 连接检测、总线复位 |
| 设备层 | 分配默认地址、获取设备基本属性 | 设备描述符 | 地址分配前/后 |
| 配置层 | 选择配置、获取整体功耗与接口数量 | 配置描述符 | 获取配置描述符 |
| 接口层 | 声明功能接口、关联端点集合 | 接口描述符 | 获取配置描述符集 |
| 端点层 | 定义数据传输通道属性 | 端点描述符 | 获取配置描述符集 |
2.2 物理层:连接检测与总线复位
物理层位于协议栈最底层,负责处理USB总线的电气特性与信号时序。在枚举启动前,物理层完成以下关键动作:
- 设备连接检测:主机通过检测D+或D-线上的上拉电阻(全速/高速上拉D+,低速上拉D-)判断设备插入。
- 总线复位:主机将D+和D-同时拉低至少10ms,设备检测到复位信号后,将地址重置为默认地址0,并准备接收第一个控制传输。
- 速度协商:对于高速设备,在复位期间会进行chirp握手,确定最终工作速度。
物理层不涉及描述符解析,但它是枚举能够启动的物理前提。移植时需关注MCU的USB PHY配置、时钟稳定时间以及复位中断处理。
2.3 设备层:地址分配与设备描述符
设备层是枚举中软件栈最先介入的层级。主机通过默认地址0与设备通信,完成以下两个关键步骤:
- 获取设备描述符:主机发送请求
GET_DESCRIPTOR(DEVICE),设备返回18字节的设备描述符,包含USB规范版本、设备类、子类、协议、最大包长度(bMaxPacketSize0)、厂商ID(idVendor)、产品ID(idProduct)等信息。 - 分配唯一地址:主机发送
SET_ADDRESS请求,设备收到后必须在状态阶段完成后切换到新地址。此后所有通信使用新地址。
设备描述符中 bMaxPacketSize0 字段直接影响后续控制传输的包长,移植时需确保该值与硬件端点FIFO大小匹配。常见值为8、16、32、64字节。
2.4 配置层:选择配置与功耗声明
地址分配完成后,主机进入配置层交互。配置层描述符定义了设备的整体功耗需求以及包含的接口数量。主机通过 GET_DESCRIPTOR(CONFIGURATION) 获取配置描述符,其结构如下:
| 字段 | 偏移 | 大小 | 说明 |
|---|---|---|---|
| bLength | 0 | 1 | 描述符长度(9字节) |
| bDescriptorType | 1 | 1 | 配置描述符类型(0x02) |
| wTotalLength | 2 | 2 | 配置描述符集总长度(含接口、端点) |
| bNumInterfaces | 4 | 1 | 该配置支持的接口数量 |
| bConfigurationValue | 5 | 1 | 用于 SET_CONFIGURATION 的索引值 |
| bMaxPower | 8 | 1 | 最大功耗(单位2mA) |
主机在获取完整配置描述符集后,发送 SET_CONFIGURATION 请求激活该配置。设备层收到后,必须使能所有属于该配置的端点。
wTotalLength 必须精确计算,包含所有接口描述符、端点描述符以及可能的类特定描述符。长度错误会导致主机解析失败。
2.5 接口层:功能声明与端点分组
接口层位于配置层之下,每个配置可以包含多个接口。接口描述符将端点组织成逻辑功能单元,例如一个音频设备可能包含一个音频控制接口和一个音频流接口。
接口描述符关键字段:
- bInterfaceNumber:接口编号,从0开始递增。
- bAlternateSetting:备用设置,用于切换接口的带宽或格式。
- bNumEndpoints:该接口使用的端点数量(不包括端点0)。
- bInterfaceClass/SubClass/Protocol:定义接口的功能类型,如HID、Mass Storage、CDC等。
在枚举过程中,主机通过接口描述符识别设备功能,并加载对应的驱动程序。移植时需确保接口描述符中的类代码与主机驱动匹配。
2.6 端点层:传输通道属性定义
端点层是协议栈最底层的数据传输单元。端点描述符定义了每个端点的传输类型、方向、最大包长和轮询间隔。主机根据端点描述符配置主机控制器,建立数据传输通道。
端点描述符关键字段:
| 字段 | 说明 | 典型值 |
|---|---|---|
| bEndpointAddress | 端点号+方向(bit7=1 IN, 0 OUT) | 0x81(端点1 IN) |
| bmAttributes | 传输类型:0=控制, 1=等时, 2=批量, 3=中断 | 0x02(批量) |
| wMaxPacketSize | 最大包长(等时模式含附加位) | 64(全速批量) |
| bInterval | 轮询间隔(单位:帧/微帧) | 10(中断端点) |
wMaxPacketSize 必须与MCU硬件端点的FIFO深度匹配。例如,全速批量端点最大包长只能为8、16、32、64字节,高速批量端点可达512字节。设置错误会导致数据溢出或传输失败。
2.7 各层协作:枚举完整流程
将五层职责串联起来,USB枚举的完整流程如下:
- 物理层:设备插入 → 主机检测到上拉电阻 → 发起总线复位。
- 设备层:主机通过地址0获取设备描述符 → 分配唯一地址。
- 设备层→配置层:主机使用新地址获取配置描述符(含总长度)。
- 配置层→接口层→端点层:主机获取完整配置描述符集(含接口描述符和端点描述符)。
- 配置层:主机发送
SET_CONFIGURATION激活配置,设备使能所有端点。