四、USB协议中的描述符

四、USB 协议中的描述符(Descriptor)详解

USB 协议学习目录

点击标题可跳转到对应的网络文章

目录

  • 一、概述
    • [1.1 描述符的作用](#1.1 描述符的作用)
    • [1.2 描述符的级联结构](#1.2 描述符的级联结构)
    • [1.3 描述符通用格式](#1.3 描述符通用格式)
  • [二、设备描述符(Device Descriptor)](#二、设备描述符(Device Descriptor))
    • [2.1 结构详解](#2.1 结构详解)
    • [2.2 关键字段解析](#2.2 关键字段解析)
  • [三、配置描述符(Configuration Descriptor)](#三、配置描述符(Configuration Descriptor))
    • [3.1 结构详解](#3.1 结构详解)
    • [3.2 配置属性解析](#3.2 配置属性解析)
  • [四、接口描述符(Interface Descriptor)](#四、接口描述符(Interface Descriptor))
    • [4.1 结构详解](#4.1 结构详解)
    • [4.2 接口类速查](#4.2 接口类速查)
  • [五、端点描述符(Endpoint Descriptor)](#五、端点描述符(Endpoint Descriptor))
    • [5.1 结构详解](#5.1 结构详解)
    • [5.2 端点地址解析](#5.2 端点地址解析)
    • [5.3 端点属性解析](#5.3 端点属性解析)
  • [六、字符串描述符(String Descriptor)](#六、字符串描述符(String Descriptor))
    • [6.1 语言 ID 描述符](#6.1 语言 ID 描述符)
    • [6.2 Unicode 字符串描述符](#6.2 Unicode 字符串描述符)
  • [七、接口关联描述符 IAD](#七、接口关联描述符 IAD)
  • 八、类特定描述符
    • [8.1 HID 描述符](#8.1 HID 描述符)
    • [8.2 CDC 功能描述符](#8.2 CDC 功能描述符)
    • [8.3 Hub 描述符](#8.3 Hub 描述符)
  • 九、描述符获取流程
  • 十、描述符实例分析
  • 十一、总结

一、概述

1.1 描述符的作用

USB 设备通过描述符(Descriptor)向主机自描述自身的能力。描述符是一种层次化的数据结构,Host 在枚举阶段通过控制传输读取这些描述符,从而了解设备的一切信息。
自描述
读取
解析
USB Device
描述符集
USB Host
加载驱动

配置端点

描述符回答的核心问题

  • 这是什么设备?(VID/PID/设备类)
  • 支持什么 USB 版本?(bcdUSB)
  • 有多少种配置?(bNumConfigurations)
  • 每个配置有哪些接口?(bNumInterfaces)
  • 每个接口有哪些端点?(bNumEndpoints)
  • 端点支持什么传输类型?(bmAttributes)
  • 设备叫什么名字?(字符串描述符)

1.2 描述符的级联结构

Device Descriptor

设备描述符

18字节
Configuration Descriptor 1

配置描述符

9字节 + 子描述符
Configuration Descriptor 2

(可选)
Interface Descriptor 0

接口描述符

9字节
Interface Descriptor 1

(可选)
HID Descriptor

HID描述符

(如为HID设备)
Endpoint Descriptor 0-1

端点描述符

7字节
Endpoint Descriptor 0-2

(可选)
CDC Functional Descriptor

CDC功能描述符

(如为CDC设备)
Endpoint Descriptor 1-1

描述符层级关系

  • 1 个设备描述符 → 包含 bNumConfigurations 个配置描述符
  • 每个配置描述符 → 包含 bNumInterfaces 个接口描述符
  • 每个接口描述符 → 包含 bNumEndpoints 个端点描述符
  • 接口描述符 → 可能附带类特定描述符(HID、CDC 等)

1.3 描述符通用格式

所有 USB 描述符都以相同的 2 字节头部开始:

偏移 大小 字段 说明
0 1 bLength 描述符长度(字节)
1 1 bDescriptorType 描述符类型

标准描述符类型值

类型值 名称 长度
0x01 Device Descriptor 18
0x02 Configuration Descriptor 9
0x03 String Descriptor 可变
0x04 Interface Descriptor 9
0x05 Endpoint Descriptor 7
0x0B Interface Association Descriptor (IAD) 8
0x21 HID Descriptor 9+
0x29 Hub Descriptor 9+
0x2A SuperSpeed Hub Descriptor 12

二、设备描述符(Device Descriptor)

设备描述符是根描述符,位于描述符树的顶层,Host 首先获取的就是它。

2.1 结构详解

c 复制代码
typedef struct {
    uint8_t  bLength;            // 描述符长度 (18)
    uint8_t  bDescriptorType;    // 描述符类型 (0x01)
    uint16_t bcdUSB;             // USB 规范版本号 (如 0x0200 = USB 2.0)
    uint8_t  bDeviceClass;       // 设备类代码
    uint8_t  bDeviceSubClass;    // 设备子类代码
    uint8_t  bDeviceProtocol;    // 设备协议代码
    uint8_t  bMaxPacketSize0;    // 端点 0 最大包大小
    uint16_t idVendor;           // 厂商 ID (VID)
    uint16_t idProduct;          // 产品 ID (PID)
    uint16_t bcdDevice;          // 设备版本号 (BCD)
    uint8_t  iManufacturer;      // 厂商字符串索引
    uint8_t  iProduct;           // 产品字符串索引
    uint8_t  iSerialNumber;      // 序列号字符串索引
    uint8_t  bNumConfigurations; // 配置描述符数量
} USB_DeviceDescriptor;

2.2 关键字段解析

bcdUSB - USB 版本号(BCD 编码)

USB 版本
0x0100 USB 1.0
0x0110 USB 1.1
0x0200 USB 2.0
0x0250 USB 2.1 (LPM)
0x0300 USB 3.0
0x0310 USB 3.1
0x0320 USB 3.2

bDeviceClass - 设备类

含义
0x00 每接口定义类(复合设备)
0x02 CDC 通信设备
0x03 HID 人机接口设备
0x08 Mass Storage 大容量存储
0x09 Hub 集线器
0x0E Video 视频设备
0xE0 Wireless 无线控制器
0xEF Miscellaneous 杂项
0xFF Vendor Specific 厂商自定义

bMaxPacketSize0 - 端点 0 最大包大小

速度 有效值
Low Speed 8
Full Speed 8, 16, 32, 64
High Speed 64

idVendor / idProduct

  • VID 由 USB-IF 统一分配(如 0x046D = Logitech)
  • PID 由厂商自行定义
  • Host 通过 VID/PID 匹配特定驱动

字符串索引字段

  • iManufacturer:厂商名称字符串索引(0 = 无字符串)
  • iProduct:产品名称字符串索引
  • iSerialNumber:序列号字符串索引

三、配置描述符(Configuration Descriptor)

配置描述符定义了设备的一种工作模式。一个设备可以有多个配置(如"总线供电模式"和"自供电模式"),但同一时间只能激活一个配置。

3.1 结构详解

c 复制代码
typedef struct {
    uint8_t  bLength;             // 描述符长度 (9)
    uint8_t  bDescriptorType;     // 描述符类型 (0x02)
    uint16_t wTotalLength;        // 配置总长度(含所有子描述符)
    uint8_t  bNumInterfaces;      // 接口数量
    uint8_t  bConfigurationValue; // 配置值(SET_CONFIGURATION 参数)
    uint8_t  iConfiguration;      // 配置描述字符串索引
    uint8_t  bmAttributes;        // 配置属性
    uint8_t  bMaxPower;           // 最大功耗(单位:2mA)
} USB_ConfigurationDescriptor;

3.2 配置属性解析

bmAttributes 字段

名称 说明
Bit7 保留 1 必须置 1(历史兼容)
Bit6 自供电 1 设备支持自供电
0 设备仅总线供电
Bit5 远程唤醒 1 支持远程唤醒
0 不支持远程唤醒
Bit4~0 保留 0 必须置 0

bMaxPower

  • 单位 = 2mA
  • 例如:值 = 50,表示最大功耗 = 50 × 2mA = 100mA
  • USB 2.0 最大值为 250(500mA)
  • USB 3.0 最大值为 250(500mA),但 SuperSpeed 设备可支持 900mA

wTotalLength

  • 这是整个配置描述符集的总长度
  • 包含:配置描述符 + 所有接口描述符 + 所有端点描述符 + 所有类特定描述符
  • Host 通过此值一次性获取完整配置信息

四、接口描述符(Interface Descriptor)

接口描述符定义了设备的一个逻辑功能。一个配置可包含多个接口,每个接口对应一个独立功能(如键盘 + 鼠标复合设备)。

4.1 结构详解

c 复制代码
typedef struct {
    uint8_t bLength;             // 描述符长度 (9)
    uint8_t bDescriptorType;     // 描述符类型 (0x04)
    uint8_t bInterfaceNumber;    // 接口编号(从 0 开始)
    uint8_t bAlternateSetting;   // 备用设置编号
    uint8_t bNumEndpoints;       // 端点数量(不含 EP0)
    uint8_t bInterfaceClass;     // 接口类代码
    uint8_t bInterfaceSubClass;  // 接口子类代码
    uint8_t bInterfaceProtocol;  // 接口协议代码
    uint8_t iInterface;          // 接口描述字符串索引
} USB_InterfaceDescriptor;

bInterfaceNumber

  • 接口在配置中的唯一编号,从 0 开始递增
  • 复合设备中,每个功能对应一个独立的接口编号

bAlternateSetting

  • 同一接口的不同设置(Alternate Setting)
  • 用于动态切换接口配置(如 USB 音频中切换采样率)
  • 默认设置 = 0,通过 SET_INTERFACE 请求切换

bNumEndpoints

  • 该接口使用的非零端点数量
  • 控制端点 EP0 是所有接口共用的,不计入此值

4.2 接口类速查

类代码 名称 典型应用 子类示例
0x00 保留 - -
0x02 CDC-Control 串口/调制解调器 ACM=0x02
0x03 HID 键盘/鼠标/手柄 Boot=0x01
0x08 Mass Storage U盘/读卡器 SCSI=0x06, BOT=0x50
0x0A CDC-Data CDC 数据接口 -
0x0B Smart Card 读卡器 CCID=0x00
0x0E Video 摄像头 UVC=0x01
0x01 Audio 声卡/耳机 UAC
0x09 Hub 集线器 -
0xE0 Wireless 蓝牙/WiFi Bluetooth=0x01
0xFF Vendor Specific 自定义 -

五、端点描述符(Endpoint Descriptor)

端点描述符定义了数据传输的通道属性,包括方向、传输类型、最大包大小和轮询间隔。

5.1 结构详解

c 复制代码
typedef struct {
    uint8_t  bLength;            // 描述符长度 (7)
    uint8_t  bDescriptorType;    // 描述符类型 (0x05)
    uint8_t  bEndpointAddress;   // 端点地址
    uint8_t  bmAttributes;       // 端点属性
    uint16_t wMaxPacketSize;     // 最大包大小
    uint8_t  bInterval;          // 轮询间隔
} USB_EndpointDescriptor;

5.2 端点地址解析

bEndpointAddress

复制代码
Bit7    Bit6~4    Bit3~0
方向    保留       端点编号
0=OUT   000       0~15
1=IN
含义
0x00 控制端点 0 (OUT)
0x80 控制端点 0 (IN)
0x01 端点 1 (OUT)
0x81 端点 1 (IN)
0x02 端点 2 (OUT)
0x82 端点 2 (IN)

5.3 端点属性解析

bmAttributes

复制代码
Bit1~0: 传输类型
  00 = Control    控制传输
  01 = Isochronous 同步传输
  10 = Bulk       批量传输
  11 = Interrupt  中断传输

Bit3~2: 同步类型 (仅同步传输)
  00 = None       无同步
  01 = Asynchronous 异步
  10 = Adaptive   自适应
  11 = Synchronous 同步

Bit5~4: 用法类型 (仅同步传输)
  00 = Data Endpoint
  01 = Feedback Endpoint
  10 = Implicit Feedback
  11 = Reserved

wMaxPacketSize

速度 控制 批量 中断 同步
Low Speed 8 - 8 -
Full Speed 8/16/32/64 8/16/32/64 64 1023
High Speed 64 512 1024 1024
SuperSpeed 512 1024 1024 1024

bInterval

速度 含义 典型值
Full Speed 中断 轮询间隔(ms) 1~255 ms
High Speed 中断 轮询间隔(125μs × 2^(bInterval-1)) 1~16
Full Speed 同步 轮询间隔(ms) 1 ms
High Speed 同步 轮询间隔(125μs × 2^(bInterval-1)) 1~16
批量/控制 忽略 -

六、字符串描述符(String Descriptor)

字符串描述符提供设备的可读文本信息 (厂商名、产品名、序列号),采用 UTF-16LE 编码。

6.1 语言 ID 描述符

字符串描述符 0 是特殊的,它返回设备支持的语言 ID 列表

c 复制代码
// 字符串描述符 0 结构
uint8_t bLength;           // 描述符长度 (2 + 2*N)
uint8_t bDescriptorType;   // 0x03
uint16_t wLANGID[0];       // 语言 ID 数组
// ...
uint16_t wLANGID[N-1];

常用语言 ID

语言 LANGID
英语(美国) 0x0409
简体中文 0x0804
繁体中文 0x0404
日语 0x0411
韩语 0x0412

6.2 Unicode 字符串描述符

c 复制代码
// 字符串描述符 N (N >= 1)
uint8_t  bLength;          // 描述符长度 (2 + 字符串字节数)
uint8_t  bDescriptorType;  // 0x03
uint16_t bString[];        // UTF-16LE 编码字符串 (不含结尾 \0)

示例:字符串 "Kimi USB Device"

复制代码
bLength       = 0x22        // 2 + 16×2 = 34 字节
bDescriptorType = 0x03
bString[0]    = 'K' = 0x004B (小端: 4B 00)
bString[1]    = 'i' = 0x0069 (小端: 69 00)
...

七、接口关联描述符 IAD

多个接口组成一个复合功能时,需要使用 IAD(Interface Association Descriptor)进行关联声明。

c 复制代码
typedef struct {
    uint8_t  bLength;           // 描述符长度 (8)
    uint8_t  bDescriptorType;   // 描述符类型 (0x0B)
    uint8_t  bFirstInterface;   // 第一个接口编号
    uint8_t  bInterfaceCount;   // 关联的接口数量
    uint8_t  bFunctionClass;    // 功能类
    uint8_t  bFunctionSubClass; // 功能子类
    uint8_t  bFunctionProtocol; // 功能协议
    uint8_t  iFunction;         // 功能描述字符串索引
} USB_IADDescriptor;

典型应用 - CDC 设备
IAD

bFirstInterface=0

bInterfaceCount=2

FunctionClass=0x02 CDC
Interface 0

CDC-Control

bInterfaceClass=0x02
Interface 1

CDC-Data

bInterfaceClass=0x0A
中断端点

通知端点
CDC Functional Descriptors

Header/ACM/Union/CallMgmt
批量端点 IN

数据接收
批量端点 OUT

数据发送


八、类特定描述符

8.1 HID 描述符

HID 接口必须附带 HID 描述符,定义 HID 规范版本和报告描述符信息。

c 复制代码
typedef struct {
    uint8_t  bLength;           // 描述符长度 (9)
    uint8_t  bDescriptorType;   // 0x21 = HID
    uint16_t bcdHID;            // HID 规范版本 (如 0x0111 = 1.11)
    uint8_t  bCountryCode;      // 国家代码 (0=未本地化)
    uint8_t  bNumDescriptors;   // 附属描述符数量 (>=1)
    uint8_t  bDescriptorType2;  // 0x22 = Report Descriptor
    uint16_t wDescriptorLength; // 报告描述符长度
    // 可选:Physical Descriptor
    // uint8_t  bDescriptorType3;
    // uint16_t wDescriptorLength2;
} USB_HIDDescriptor;

8.2 CDC 功能描述符

CDC 接口附带一组功能描述符(Functional Descriptor),定义通信参数。

描述符子类型 说明
Header 0x00 CDC 版本信息
Call Management 0x01 呼叫管理
Abstract Control Management 0x02 ACM 管理
Direct Line Management 0x03 直路管理
Union 0x06 接口关联

Union Functional Descriptor

c 复制代码
typedef struct {
    uint8_t bLength;           // 4
    uint8_t bDescriptorType;   // 0x24 (CS_INTERFACE)
    uint8_t bDescriptorSubtype;// 0x06 (UNION)
    uint8_t bMasterInterface;  // 控制接口编号
    uint8_t bSlaveInterface0;  // 数据接口编号
} CDC_UnionFunctionalDescriptor;

8.3 Hub 描述符

Hub 设备特有的描述符,定义下行端口数量、电源特性等。

c 复制代码
typedef struct {
    uint8_t  bLength;           // 描述符长度 (9)
    uint8_t  bDescriptorType;   // 0x29 = Hub
    uint8_t  bNbrPorts;         // 下行端口数量
    uint16_t wHubCharacteristics; // Hub 特性
    uint8_t  bPwrOn2PwrGood;    // 端口上电到就绪时间 (2ms 单位)
    uint8_t  bHubContrCurrent;  // Hub 控制器最大电流 (mA)
    uint8_t  DeviceRemovable;   // 设备可移除位图
    uint8_t  PortPwrCtrlMask;   // 端口电源控制掩码
} USB_HubDescriptor;

wHubCharacteristics 字段

复制代码
Bit1~0: 逻辑电源切换模式
  00 = Ganged power switching (所有端口一起)
  01 = Individual port power switching (独立)
  1x = 无电源切换

Bit2: 复合设备标志
  0 = Hub 不是复合设备的一部分
  1 = Hub 是复合设备的一部分

Bit4~3: TT (Transaction Translator)  Think Time
  00 = <=8 FS bit times
  01 = <=16 FS bit times
  10 = <=24 FS bit times
  11 = <=32 FS bit times

Bit5: TT 端口指示器
  0 = 不支持端口指示器
  1 = 支持端口指示器

九、描述符获取流程

Host 在枚举阶段按以下顺序获取描述符:
USB Device USB Host USB Device USB Host 阶段1: 获取设备描述符 阶段2: 获取配置描述符 阶段3: 获取字符串描述符 阶段4: 设置配置 GET_DESCRIPTOR(Device, 8) 前 8 字节 (含 bMaxPacketSize0) SET_ADDRESS(addr) ACK GET_DESCRIPTOR(Device, 18) 完整设备描述符 GET_DESCRIPTOR(Config, 9) 配置描述符 (含 wTotalLength) GET_DESCRIPTOR(Config, wTotalLength) 完整配置描述符集 GET_DESCRIPTOR(String, 0) 语言 ID 列表 GET_DESCRIPTOR(String, iManufacturer) 厂商名称 GET_DESCRIPTOR(String, iProduct) 产品名称 SET_CONFIGURATION(value) ACK

GET_DESCRIPTOR 请求格式

复制代码
bmRequestType = 0x80  (Device→Host, Standard, Device)
bRequest      = 0x06  (GET_DESCRIPTOR)
wValue        = (描述符类型 << 8) | 描述符索引
                如: 设备描述符 = 0x0100
                    配置描述符 = 0x0200
                    字符串描述符(厂商) = 0x0301
wIndex        = 0 (设备/配置) 或语言 ID (字符串)
wLength       = 期望返回的字节数

十、描述符实例分析

以下是一个USB HID 键盘的完整描述符字节流实例:

设备描述符(18 字节)

复制代码
偏移  值      说明
----  ----    ----
00    0x12    bLength = 18
01    0x01    bDescriptorType = Device
02    0x00    bcdUSB = 0x0200 (USB 2.0)
03    0x02
04    0x00    bDeviceClass = 0 (每接口定义)
05    0x00    bDeviceSubClass = 0
06    0x00    bDeviceProtocol = 0
07    0x08    bMaxPacketSize0 = 8 (Full Speed)
08    0x83    idVendor = 0x0483 (ST Microelectronics)
09    0x04
10    0x10    idProduct = 0x5710
11    0x57
12    0x00    bcdDevice = 0x0100
13    0x01
14    0x01    iManufacturer = 1 (字符串1)
15    0x02    iProduct = 2 (字符串2)
16    0x00    iSerialNumber = 0 (无)
17    0x01    bNumConfigurations = 1

配置描述符及子描述符(34 字节)

复制代码
偏移  值      说明
----  ----    ----
00    0x09    bLength = 9 (Configuration)
01    0x02    bDescriptorType = Configuration
02    0x22    wTotalLength = 0x0022 = 34 字节
03    0x00
04    0x01    bNumInterfaces = 1
05    0x01    bConfigurationValue = 1
06    0x00    iConfiguration = 0 (无)
07    0xA0    bmAttributes = 10100000 (自供电, 远程唤醒)
08    0x32    bMaxPower = 50 × 2mA = 100mA

09    0x09    bLength = 9 (Interface)
10    0x04    bDescriptorType = Interface
11    0x00    bInterfaceNumber = 0
12    0x00    bAlternateSetting = 0
13    0x01    bNumEndpoints = 1
14    0x03    bInterfaceClass = 0x03 (HID)
15    0x01    bInterfaceSubClass = 0x01 (Boot)
16    0x01    bInterfaceProtocol = 0x01 (Keyboard)
17    0x00    iInterface = 0 (无)

18    0x09    bLength = 9 (HID)
19    0x21    bDescriptorType = HID
20    0x11    bcdHID = 0x0111 (HID 1.11)
21    0x01
22    0x00    bCountryCode = 0
23    0x01    bNumDescriptors = 1
24    0x22    bDescriptorType = Report
25    0x3F    wDescriptorLength = 0x003F = 63 字节
26    0x00

27    0x07    bLength = 7 (Endpoint)
28    0x05    bDescriptorType = Endpoint
29    0x81    bEndpointAddress = 0x81 (EP1 IN)
30    0x03    bmAttributes = 0x03 (Interrupt)
31    0x08    wMaxPacketSize = 8
32    0x00
33    0x0A    bInterval = 10 ms

字符串描述符

字符串 0(语言 ID)

复制代码
00    0x04    bLength = 4
01    0x03    bDescriptorType = String
02    0x09    wLANGID[0] = 0x0409 (英语-美国)
03    0x04

字符串 1(厂商名 "STMicroelectronics")

复制代码
00    0x26    bLength = 38 (2 + 18×2)
01    0x03    bDescriptorType = String
02~   ...     "STMicroelectronics" in UTF-16LE

十一、总结

Level 4
Level 3
Level 2
Level 1
Level 0
Device Descriptor

18字节

设备全局信息
Configuration Descriptor

9字节 + 子描述符

一种工作模式
Interface Descriptor

9字节

一个逻辑功能
IAD

8字节

接口关联
Endpoint Descriptor

7字节

数据传输通道
Class-Specific

HID/CDC/Hub...

类特定描述符
String Descriptor

可变

可读文本信息

描述符设计核心思想

  1. 自描述:设备通过描述符告知主机"我是谁、我能做什么"
  2. 分层级联:从设备 → 配置 → 接口 → 端点,层层细化
  3. 灵活扩展:通过类特定描述符支持各种设备类
  4. 动态配置:同一设备可有多套配置/接口,按需切换
相关推荐
Championship.23.244 天前
Linux 3.0 USB机制深度解析:USB 3.0支持与传统外设驱动架构
linux·运维·架构·usb
ZenasLDR10 天前
Type-C接口iPad键盘皮套
接口·芯片·usb
smallerxuan10 天前
九、CherryUSB 设计架构与工作逻辑分析
usb·cherryusb·cherryusb分析
smallerxuan11 天前
二、USB协议中的设备类
usb·usb协议·usb设备类
smallerxuan13 天前
三、USB协议通信过程
usb·usb协议·usb通信过程
smallerxuan13 天前
七、USB协议中的事务
usb·usb协议·usb事务
smallerxuan13 天前
五、USB协议中的请求
usb·usb协议·usb请求
smallerxuan13 天前
八、USB协议分析与调试实战
usb·usb协议分析·usb协议·usb协议调测
ZenasLDR16 天前
Type-C接口水冷散热器
接口·芯片·usb