3. USB 包结构与传输类型

USB 通信的最小数据单元是 包(Packet),多个包按照特定顺序组合成一次 传输(Transaction),而多个传输再构成更高层级的 传输类型(Transfer Type)。理解包结构与传输类型是分析 USB 枚举过程中复位、地址分配、描述符请求等环节的基础。

3.1 USB 包结构

USB 总线上的所有通信都以包为单位进行。每个包由固定的字段序列组成,并以同步序列(SYNC)开始、包结束(EOP)终止。根据功能不同,USB 包分为三大类:令牌包(Token Packet)、数据包(Data Packet) 和 握手包(Handshake Packet)。

3.1.1 令牌包(Token Packet)

令牌包由主机发出,用于标识一次传输的方向、类型和目标端点。它是每次传输的起始包。令牌包格式如下:

字段 PID(8位) ADDR(7位) ENDP(4位) CRC5(5位)
说明 包标识符,指示令牌类型(IN、OUT、SETUP、SOF) 目标设备地址(0~127) 目标端点号(0~15) 对 ADDR+ENDP 的校验
关键点:枚举初期设备地址为 0(默认地址),主机通过 SETUP 令牌包发送请求,设备通过 IN 令牌包返回数据。
常见令牌 PID:
· 0x69(IN):主机请求从设备读取数据
· 0xE1(OUT):主机向设备发送数据
· 0x2D(SETUP):主机向设备发送控制请求(仅用于控制传输)
· 0xA5(SOF):帧起始包,用于同步和帧计数

3.1.2 数据包(Data Packet)

数据包紧跟在令牌包之后,承载实际传输的数据。数据包格式如下:

字段 PID(8位) DATA(0~1023字节) CRC16(16位)
说明 标识数据包类型(DATA0、DATA1、DATA2、MDATA) 有效数据负载 对 DATA 字段的循环冗余校验
数据切换(Data Toggle):DATA0 和 DATA1 交替使用,用于保证数据完整性。每次成功传输后切换,接收方通过 PID 判断是否为预期数据包。

3.1.3 握手包(Handshake Packet)

握手包由接收方(设备或主机)发出,用于报告传输状态。握手包仅包含 8 位 PID,无数据字段。

PID 名称 含义
0x4B ACK 数据正确接收,传输成功
0x5A NAK 设备忙,暂时无法处理(非错误)
0x1E STALL 端点被暂停或不支持该请求(错误条件)
0x2E NYET (高速模式)设备尚未准备好接收下一数据
调试提示:在枚举过程中,如果主机收到 STALL 握手包,通常表示设备不支持该请求(如无效的描述符类型)。NAK 是正常状态,表示设备正在处理中,主机会重试。

3.1.4 包结构关系图

USB 包结构分类与关系 令牌包 (Token) PID + ADDR + ENDP + CRC5 由主机发出,启动传输 类型:IN / OUT / SETUP / SOF 数据包 (Data) PID + DATA + CRC16 承载有效数据负载 类型:DATA0 / DATA1 握手包 (Handshake) 仅 PID(8位) 报告传输状态 类型:ACK / NAK / STALL / NYET 一次典型传输的包序列 令牌包(主机→设备) → 数据包(主机/设备→对方) → 握手包(接收方→发送方) 例如:OUT 令牌 + DATA0 数据 + ACK 握手

3.2 USB 传输类型

USB 规范定义了四种传输类型,每种类型对应不同的应用场景和性能要求。在枚举过程中,主要使用控制传输,但理解其他传输类型有助于全面掌握 USB 通信机制。

3.2.1 控制传输(Control Transfer)

控制传输是 USB 枚举的核心传输类型,用于主机与设备之间的配置、状态查询和命令发送。它由两个或三个阶段组成:

  • 建立阶段(Setup Stage):主机发送 SETUP 令牌包 + DATA0 数据包(8 字节标准请求),设备必须 ACK。
  • 数据阶段(Data Stage):可选,根据请求方向传输数据(IN 或 OUT),使用 DATA0/DATA1 交替。
  • 状态阶段(Status Stage):报告整个控制传输的完成状态,方向与数据阶段相反。
阶段 令牌包 数据包 握手包 说明
建立 SETUP DATA0(8字节) ACK 主机发送标准请求(如 Get_Descriptor)
数据(IN) IN DATA1/DATA0 ACK 设备返回描述符数据
数据(OUT) OUT DATA1/DATA0 ACK 主机发送配置数据
状态 IN 或 OUT 无数据(零长度包) ACK 确认传输完成
枚举中的应用:获取设备描述符、设置地址、获取配置描述符、设置配置等所有标准请求都通过控制传输完成。控制传输使用端点 0(默认控制端点)。

3.2.2 批量传输(Bulk Transfer)

批量传输用于传输大量数据,没有带宽保证,但通过 CRC 和重试机制保证数据可靠性。适用于打印机、扫描仪、存储设备等。

  • 特点:非实时、高可靠性、带宽占用灵活(空闲时全速传输)
  • 包序列:令牌包(IN/OUT) + 数据包(DATA0/DATA1) + 握手包(ACK/NAK/STALL)
  • 端点类型:批量端点(Bulk Endpoint)

3.2.3 中断传输(Interrupt Transfer)

中断传输用于传输小量数据,具有保证的轮询间隔(bInterval),适用于人机交互设备(HID)如键盘、鼠标。

  • 特点:低延迟、保证轮询频率、数据量小(全速最大 64 字节,高速最大 1024 字节)
  • 包序列:与批量传输相同,但主机保证在 bInterval 时间内轮询一次
  • 端点类型:中断端点(Interrupt Endpoint)
枚举中的中断端点:HID 设备在配置描述符中声明中断 IN 端点,主机枚举完成后通过中断传输读取键盘/鼠标输入报告。

3.2.4 同步传输(Isochronous Transfer)

同步传输用于传输实时数据流,如音频、视频。它保证带宽和传输时间,但不保证数据可靠性(无重试、无握手包)。

  • 特点:实时性优先、固定带宽、无握手/重试、允许少量数据丢失
  • 包序列:令牌包(IN/OUT) + 数据包(DATA0/DATA1/DATA2/MDATA) — 无握手包
  • 端点类型:同步端点(Isochronous Endpoint)
注意:同步传输不发送握手包,因此接收方无法报告错误。如果数据损坏,只能丢弃。在枚举过程中不会使用同步传输,因为枚举需要可靠的数据交换。

3.2.5 四种传输类型对比

传输类型 可靠性 带宽保证 延迟 典型应用 枚举中使用
控制传输 高(重试+CRC) 10%(全速) 中等 枚举、配置、命令 是(端点0)
批量传输 高(重试+CRC) 无 可变 存储、打印 否
中断传输 高(重试+CRC) 有(轮询间隔) 低(保证) 键盘、鼠标 否(枚举后)
同步传输 低(无重试) 有(固定带宽) 低(固定) 音频、视频 否

3.2.6 传输类型与包结构组合图

四种传输类型的包序列对比 控制传输 SETUP + DATA0 + ACK → IN/OUT + DATAx + ACK → 状态阶段 批量传输 IN/OUT + DATAx + ACK (可NAK重试) 无带宽保证 中断传输 IN/OUT + DATAx + ACK 保证轮询间隔 低延迟 同步传输 IN/OUT + DATAx 无握手包 固定带宽 枚举过程中的传输类型使用 复位后 → 控制传输(端点0):获取描述符、设置地址、设置配置 枚举完成后 → 中断/批量/同步传输(非端点0):数据通信 端点0:所有设备必须支持控制传输 枚举的核心通信通道

3.3 包结构与传输类型在枚举中的实际应用

在 USB 枚举过程中,主机和设备通过控制传输在端点 0 上交换数据。以下是一个典型的枚举请求包序列示例(获取设备描述符):

// 主机发送:SETUP 令牌包 + DATA0 数据包(8字节标准请求)
// 令牌包:PID=0x2D (SETUP), ADDR=0x00, ENDP=0x00
// 数据包:PID=0xC3 (DATA0), DATA=80 06 00 01 00 00 12 00
//          (bmRequestType=0x80, bRequest=0x06, wValue=0x0100, wIndex=0x0000, wLength=0x0012)
// 设备回复:ACK 握手包

// 主机发送:IN 令牌包
// 令牌包:PID=0x69 (IN), ADDR=0x00, ENDP=0x00
// 设备回复:DATA1 数据包(18字节设备描述符)+ ACK 握手包
// 数据包:PID=0x4B (DATA1), DATA=12 01 00 02 00 00 00 40 ...
// 主机回复:ACK 握手包

// 状态阶段:主机发送 OUT 令牌包 + 零长度数据包
// 令牌包:PID=0xE1 (OUT), ADDR=0x00, ENDP=0x00
// 数据包:PID=0xC3 (DATA0), DATA=空
// 设备回复:ACK 握手包
分析要点:
· 地址 0 是枚举初期的默认地址,设备在收到 Set_Address 请求后才分配到唯一地址。
· DATA0 和 DATA1 交替使用,确保数据包不被重复处理。
· 每个控制传输都以状态阶段结束,用于确认整个传输的完整性。

3.4 本章小结

  • USB 包分为令牌包、数据包、握手包三类,分别承担传输启动、数据承载和状态报告功能。
  • 控制传输是枚举的核心,由建立、数据(可选)、状态三个阶段组成,使用端点 0。
  • 批量传输保证可靠性,中断传输保证低延迟,同步传输保证实时性但不可靠。
  • 枚举过程中主机通过控制传输发送标准请求(如 Get_Descriptor、Set_Address),设备通过 DATA0/DATA1 切换和 ACK/NAK/STALL 握手包进行响应。
  • 理解包结构和传输类型是分析 USB 总线流量、调试枚举失败问题(如地址分配超时、描述符请求无响应)的基础。