4. 控制传输基础:USB控制传输的四个阶段与控制管道特性
控制传输是USB通信中最基础、最可靠的传输类型,也是所有USB设备必须支持的“默认通道”。在OHCI驱动开发中,控制传输的调试往往是最先遇到的挑战——它既是设备枚举的起点,也是中断处理正确性的试金石。本节将深入剖析控制传输的四个阶段(Setup、Data、Status)以及控制管道的核心特性,为后续的协同调试打下理论基础。
4.1 控制传输的四个阶段
控制传输采用“请求-应答”的握手模式,由USB主机发起,设备响应。一次完整的控制传输包含Setup阶段、Data阶段(可选)和Status阶段。Data阶段的方向由Setup阶段的bmRequestType中的方向位决定。
4.1.1 Setup阶段
Setup阶段是控制传输的“命令头”。主机向设备发送一个8字节的USB请求块(USB Request Block, URB),包含请求类型、请求码、参数等信息。该阶段使用USB的SETUP事务,数据方向始终为主机到设备(OUT)。
| 字节偏移 | 字段 | 长度 | 说明 |
|---|---|---|---|
| 0 | bmRequestType | 1 | 请求特性:方向(D7)、类型(D6~D5)、接收者(D4~D0) |
| 1 | bRequest | 1 | 具体请求码(如GET_DESCRIPTOR = 0x06) |
| 2~3 | wValue | 2 | 请求参数(如描述符类型和索引) |
| 4~5 | wIndex | 2 | 索引或偏移(如接口号、端点号) |
| 6~7 | wLength | 2 | Data阶段期望传输的数据长度(0表示无Data阶段) |
4.1.2 Data阶段
Data阶段是可选的,由Setup阶段的wLength字段决定。如果wLength = 0,则跳过Data阶段,直接进入Status阶段。Data阶段可以包含多个数据事务,每个事务最大有效载荷为端点描述符中定义的wMaxPacketSize(控制端点通常为8、16、32或64字节)。
- 方向:由bmRequestType的D7位决定(0 = 主机到设备OUT,1 = 设备到主机IN)。
- 数据完整性:使用DATA0/DATA1交替翻转机制,确保数据包不丢失、不重复。
- 传输终止:当传输的数据量小于wMaxPacketSize或达到wLength时,Data阶段结束。
4.1.3 Status阶段
Status阶段是控制传输的“确认握手”。其数据方向与Data阶段相反:如果Data阶段是IN,则Status阶段为OUT;如果Data阶段是OUT或无Data阶段,则Status阶段为IN。Status阶段使用一个零长度的数据包,设备通过返回ACK表示成功,返回STALL表示请求不支持或出错。
4.2 控制传输的SVG流程图
下图展示了控制传输的完整流程,包括Setup、Data(可选)和Status三个阶段的事务序列。图中以“主机到设备OUT”的Data阶段为例,实际方向由请求决定。
4.3 控制管道特性
控制管道是USB设备默认的、双向的、消息型的通信通道。每个USB设备在枚举完成后,必须通过端点0(默认控制端点)提供控制管道。控制管道的特性直接影响驱动开发中的中断处理策略和传输调度。
4.3.1 控制管道的核心属性
| 属性 | 描述 | 驱动开发影响 |
|---|---|---|
| 双向性 | 控制管道使用端点0,支持主机到设备(OUT)和设备到主机(IN)两个方向 | OHCI的端点描述符(ED)需要同时配置IN和OUT方向,或使用单独的ED |
| 消息型 | 每次控制传输是一个完整的“请求-应答”消息,具有明确的开始和结束 | 中断处理中需要跟踪URB的完整生命周期,不能拆分处理 |
| 最大包长度 | 由设备描述符的bMaxPacketSize0字段定义(通常为8/16/32/64字节) | OHCI的HCCA和ED中必须正确设置MPS,否则传输会出错 |
| 默认使能 | 设备上电后端点0即处于可用状态,无需额外配置 | 驱动初始化时可直接通过控制管道发送标准请求 |
| 高可靠性 | 控制传输使用错误检测和重试机制,保证数据完整性 | 中断处理中需要处理NAK重试和超时逻辑 |
4.3.2 控制管道与OHCI的映射关系
在OHCI主机控制器中,控制管道通过端点描述符(Endpoint Descriptor, ED)和传输描述符(Transfer Descriptor, TD)实现。控制管道的双向性通常需要两个ED(一个用于IN,一个用于OUT),或者使用一个ED但通过TD的方向位区分。
4.4 控制传输在OHCI中的调度机制
OHCI使用周期性列表(Periodic List)和非周期性列表(Non-periodic List)来调度传输。控制传输属于非周期性传输,被挂载到控制列表(Control List)上。OHCI的主机控制器通信区(HCCA)中保存了控制列表的头指针。
4.5 控制传输与中断处理的协同要点
在OHCI驱动中,控制传输的完成依赖于中断处理机制。以下是两者协同调试时需要关注的核心要点:
- 完成中断的触发时机:OHCI在控制传输的Status阶段完成后,会触发“写回完成”(Writeback Done)中断。驱动中断服务程序(ISR)需要扫描HCCA的Done Queue,找到对应的TD并检查其完成状态。
- NAK与重试处理:如果设备返回NAK,OHCI会自动重试控制传输,不会触发中断。驱动需要设置合理的超时机制,防止无限重试。
- STALL处理:当设备返回STALL时,OHCI会终止当前传输并设置TD的错误标志。中断处理中必须识别STALL并清除端点停止状态(通过发送CLEAR_FEATURE请求)。
- URB生命周期管理:控制传输的URB从Setup阶段开始,到Status阶段完成结束。中断处理中需要维护URB的状态机,确保每个阶段正确推进。
4.6 控制传输的典型应用场景
控制传输在USB系统中无处不在,以下是驱动开发中最常见的应用场景:
| 场景 | 标准请求 | Data阶段方向 | 典型wLength |
|---|---|---|---|
| 获取设备描述符 | GET_DESCRIPTOR (0x06) | IN(设备→主机) | 18字节 |
| 设置地址 | SET_ADDRESS (0x05) | 无Data阶段 | 0 |
| 获取配置描述符 | GET_DESCRIPTOR (0x06) | IN(设备→主机) | 9字节(首次)/ 完整长度 |
| 设置配置 | SET_CONFIGURATION (0x09) | 无Data阶段 | 0 |
| 清除端点停止 | CLEAR_FEATURE (0x01) | 无Data阶段 | 0 |