1. 标准设备请求1.1 SETUP事务的数据格式1.2 标准设备请求1.3 设备/配置/接口/端点2. 描述符2.1 设备描述符(Device Descriptor)2.2 配置描述符(Configuration Descriptor)2.3 接口描述符(Interface Descriptor)2.4 端点描述符(Endpoint Descriptor)2.5 描述符示例3. 设备枚举示例
USB描述符的设计解决了USB通信中设备识别的问题。通过多个层次的描述符,系统能够在不同的层面上获取设备信息,确保设备能与主机正常工作。
设计模式一般采用层次结构,每个描述符包含指向下一个描述符的指针,从而形成一个链表结构,便于主机快速遍历和解析。
1. 标准设备请求
1.1 SETUP事务的数据格式
Host 使用控制传输来识别设备、设置设备地址、启动设备的某些特性,对于控制传输,它首先发出"setup事务"(参考2.5.6 控制传输 )
在"setup事务"中:
SETUP
令牌包:用来通知设备,"要开始传输了"
DATA0
数据包:Host通过DATA0
数据包发送8字节数据给设备,用来告诉设备"是读还是写"、"读什么"、"写什么"。它含有固定的格式,格式如下图所示:- 大小: 1 字节
- 类型: 位图 (Bitmap)
- 描述:
bmRequestType
描述请求的特性,包括数据传输方向、请求类型和目标设备。- 位定义:
- D7 (数据传输方向):
0
: 从主机到设备 (Host-to-device)1
: 从设备到主机 (Device-to-host)- D6...5 (请求类型):
0
: 标准请求 (Standard)1
: 类请求 (Class-specific)2
: 厂商自定义请求 (Vendor-specific)3
: 保留 (Reserved)- D4...0 (目标类型):
0
: 设备 (Device)1
: 接口 (Interface)2
: 端点 (Endpoint)3
: 其它 (Other)4~31
: 保留 (Reserved)- 大小: 1 字节
- 类型: 值 (Value)
- 描述:
bRequest
指定具体的请求类型,标识主机想对设备执行的操作。- 这部分字段的值依赖于请求类型,标准请求的值在 USB 规范 表 9-3 中有定义,例如:
0x06
: 获取描述符 (Get Descriptor)0x09
: 设置配置 (Set Configuration)- 大小: 2 字节
- 类型: 值 (Value)
- 描述:
wValue
是一个 16 位(2 字节)的字段,其意义取决于具体请求,通常用来提供请求所需的参数。例如:- 在获取描述符请求时(
Get Descriptor
),wValue
的高字节表示描述符类型(如设备、配置、字符串描述符等),低字节表示描述符索引。 - 在设置地址请求时(
Set Address
),wValue
的值表示分配给设备的地址。 - 大小: 2 字节
- 类型: 索引或偏移量 (Index or Offset)
- 描述:
wIndex
的值根据请求而变化,通常用来传递一个接口或者端点的索引。例如:- 如果目标是某个接点(Endpoint),
wIndex
表示端点号。 - 如果目标是某个接口(Interface),
wIndex
表示接口编号。 - 大小: 2 字节
- 类型: 计数器 (Count)
- 描述:
wLength
表示数据阶段 (Data Stage) 中要传输的数据字节数。- 当
wLength
为 0 时,这次传输没有数据阶段(仅包含Setup
阶段)。 - 通常由主机和设备协商具体的传输长度。

字段作用和含义
字段按字节偏移量(Offset)从 0 开始排序,总共 8 个字节,字段的作用与组成如下:
1.
bmRequestType
(偏移量 0)2.
bRequest
(偏移量 1)3.
wValue
(偏移量 2)4.
wIndex
(偏移量 4)5.
wLength
(偏移量 6)1.2 标准设备请求
控制传输的建立事务中,可以使用下列格式的数据:

上表中各个"宏"取值如下:

1.3 设备/配置/接口/端点
在
SETUP
事务的数据里,表示了要访问的是什么:Device?Interface?Endpoint?对于一个USB设备,它可以多种配置(
Configuration
)。比如4G上网卡就有2种配置:U盘、上网卡。第1次把4G上网卡插入电脑时,它是一个U盘,可以按照里面的程序。装好程序后,把它再次插入电脑,它就是一个上网卡。- 驱动程序可以选择让它工作于哪种配置,同一时间只能有一种配置。大多数的USB设备只有一种配置。
- 一个配置下,可以有多个接口(
Interface
),接口等同于功能(Function)。比如USB耳机有两个接口(功能):声音收发、按键控制。
- 一个接口,可能有多个设置(
Setting
),比如默认设置下它使用较低的带宽,可以选择其他设置以使用更高带宽。
- 一个接口,由一个或多个端点(
Endpoint
)组成。端点0属于整个设备的,端点0是双向的。接口还可以有其他端点,这些端点是单向的,要么是批量(Bulk)端点、要么是中断(Interrupt)端点、要么是同步(Isochronous)端点。
2. 描述符
怎么描述设备、配置、接口、端点?
USB描述符分为几种类型,主要包括:设备描述符、配置描述符、接口描述符、端点描述符。所谓描述符,就是一些格式化的数据,用来描述信息。
还有一些字符串描述符(String descriptors),它用可读的文字来描述设备,是可选的。

2.1 设备描述符(Device Descriptor)
每个 USB 设备有且仅有一个设备描述符,用于提供设备的基本信息,包括:

- 厂商 ID(VID)和产品 ID(PID)
- USB 协议版本支持
- 设备类型、子类和协议
- 端点 0 的最大数据包大小
- 设备拥有的配置数量
2.2 配置描述符(Configuration Descriptor)
一个设备可以有多个配置描述符,同一时间只能有一种配置,但通常只有一个。配置描述符定义:

- 该配置下的接口数量
- 供电方式(总线供电或自供电)
- 最大电流需求
- 配置属性(如是否支持远程唤醒)
2.3 接口描述符(Interface Descriptor)
每个配置下可以有多个接口描述符,代表设备的不同功能。接口描述符指定:

- 接口编号
- 接口的备用设置(Alternate Settings)数量
- 接口类型、子类和协议
- 该接口使用的端点数量
- 接口的功能说明
2.4 端点描述符(Endpoint Descriptor)
每个接口可以有多个端点描述符(不包括端点 0,它是默认的控制端点)。端点描述符定义:

- 端点地址和方向(IN 或 OUT)
- 传输类型(控制、批量、中断或等时)
- 端点的最大数据包大小
- 轮询间隔(对于中断和等时传输)
2.5 描述符示例
在Ubuntu中可以执行
lsusb -v
查看USB设备的描述符信息:3. 设备枚举示例
使用"usbprotocolsuite"打开,可以看到设备的枚举过程:
- 使用控制传输,读取设备信息(设备描述符):第一次读取时,它只需要得到8字节数据,因为第8个数据表示端点0能传输的最大数据长度。

第四行中,8个字节data数据格式见上文 。
数据包结构及通信流程图
setup stage 要求64个字节,但是data stage 只返回了18字节,这是因为设备描述符只有18个字节。
- Host分配地址给设备,然后把新地址发给设备:
没有data stage,涉及setup stage 和 status stage。

- 使用新地址,重新读取设备描述符,设备描述符长度是18:

- 通过设备描述符配置,获取配置描述符
- 设置配置 configuration