4. 控制传输基础:USB控制传输的四个阶段与控制管道特性

控制传输是USB通信中最基础、最可靠的传输类型,也是所有USB设备必须支持的“默认通道”。在OHCI驱动开发中,控制传输的调试往往是最先遇到的挑战——它既是设备枚举的起点,也是中断处理正确性的试金石。本节将深入剖析控制传输的四个阶段(Setup、Data、Status)以及控制管道的核心特性,为后续的协同调试打下理论基础。

4.1 控制传输的四个阶段

控制传输采用“请求-应答”的握手模式,由USB主机发起,设备响应。一次完整的控制传输包含Setup阶段、Data阶段(可选)和Status阶段。Data阶段的方向由Setup阶段的bmRequestType中的方向位决定。

关键概念:控制传输是唯一支持双向数据传输的传输类型,但Data阶段的数据流方向是单向的。Status阶段的方向总是与Data阶段相反,用于确认传输结果。

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表示请求不支持或出错。

调试提示:在OHCI驱动中,Status阶段的完成中断是判断控制传输是否成功的关键信号。如果驱动在Status阶段收到STALL握手,应立即终止当前URB并返回错误码,避免挂起后续传输。

4.2 控制传输的SVG流程图

下图展示了控制传输的完整流程,包括Setup、Data(可选)和Status三个阶段的事务序列。图中以“主机到设备OUT”的Data阶段为例,实际方向由请求决定。

USB控制传输四个阶段流程图 USB控制传输四个阶段流程图 Setup阶段 8字节SETUP事务 Data阶段 数据事务(可选) Status阶段 零长度确认 Setup事务细节 • Token包(SETUP) • Data包(8字节请求) • 握手包(ACK/STALL) Data事务细节 • Token包(IN/OUT) • Data包(DATA0/DATA1) • 握手包(ACK/NAK/STALL) Status事务细节 • Token包(方向相反) • Data包(零长度) • 握手包(ACK/STALL) 说明:Data阶段方向由bmRequestType的D7位决定。本图以OUT方向为例。 Status阶段方向始终与Data阶段相反。无Data阶段时,Status为IN。

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的方向位区分。

常见陷阱:部分OHCI实现要求控制管道的IN和OUT使用独立的ED。如果驱动错误地将IN和OUT TD挂载到同一个ED上,可能导致传输方向混乱,中断处理无法正确匹配完成状态。调试时务必检查ED的F(方向)位配置。

4.4 控制传输在OHCI中的调度机制

OHCI使用周期性列表(Periodic List)和非周期性列表(Non-periodic List)来调度传输。控制传输属于非周期性传输,被挂载到控制列表(Control List)上。OHCI的主机控制器通信区(HCCA)中保存了控制列表的头指针。

OHCI控制管道调度架构图 OHCI控制管道调度架构图 HCCA 控制列表头指针 ED 0 (OUT) 控制OUT管道 ED 1 (IN) 控制IN管道 NULL 链表结束 TD链 (Setup) TD链 (Data/Status) 调度规则:OHCI在每个帧(1ms)内,优先处理周期性列表(中断/同步), 剩余时间处理控制列表。控制列表采用轮询方式,每个ED最多处理一个TD后切换到下一个ED。

4.5 控制传输与中断处理的协同要点

在OHCI驱动中,控制传输的完成依赖于中断处理机制。以下是两者协同调试时需要关注的核心要点:

  1. 完成中断的触发时机:OHCI在控制传输的Status阶段完成后,会触发“写回完成”(Writeback Done)中断。驱动中断服务程序(ISR)需要扫描HCCA的Done Queue,找到对应的TD并检查其完成状态。
  2. NAK与重试处理:如果设备返回NAK,OHCI会自动重试控制传输,不会触发中断。驱动需要设置合理的超时机制,防止无限重试。
  3. STALL处理:当设备返回STALL时,OHCI会终止当前传输并设置TD的错误标志。中断处理中必须识别STALL并清除端点停止状态(通过发送CLEAR_FEATURE请求)。
  4. URB生命周期管理:控制传输的URB从Setup阶段开始,到Status阶段完成结束。中断处理中需要维护URB的状态机,确保每个阶段正确推进。
调试经验:在OHCI控制传输调试中,最常见的错误是中断处理中遗漏了Status阶段的完成检查。建议在ISR中打印每个TD的完成码(CC)和当前阶段,通过对比USB分析仪抓包数据,快速定位问题。

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