五、USB 协议中的请求
USB 协议学习目录
点击标题可跳转到对应的网络文章
- 一、USB 协议结构详解
- 二、USB 协议中的设备类
- 三、USB 协议通信过程
- 四、USB 协议中的描述符
- 五、USB 协议中的请求
- 六、USB 协议中的接口与端点
- 七、USB 协议中的事务
- 八、USB 协议分析与调试实战
目录
- [USB 协议中的请求](#USB 协议中的请求)
- 一、概述
- [1.1 请求的分类体系](#1.1 请求的分类体系)
- [1.2 请求在通信中的位置](#1.2 请求在通信中的位置)
- [二、Setup 数据包格式](#二、Setup 数据包格式)
- [2.1 Setup 包结构](#2.1 Setup 包结构)
- [2.2 bmRequestType 详解](#2.2 bmRequestType 详解)
- [2.3 wValue / wIndex / wLength 解析](#2.3 wValue / wIndex / wLength 解析)
- 三、标准请求总览
- 四、标准请求详解
- [4.1 GET_STATUS](#4.1 GET_STATUS)
- [4.2 CLEAR_FEATURE / SET_FEATURE](#4.2 CLEAR_FEATURE / SET_FEATURE)
- [4.3 SET_ADDRESS](#4.3 SET_ADDRESS)
- [4.4 GET_DESCRIPTOR](#4.4 GET_DESCRIPTOR)
- [4.5 SET_DESCRIPTOR](#4.5 SET_DESCRIPTOR)
- [4.6 GET_CONFIGURATION](#4.6 GET_CONFIGURATION)
- [4.7 SET_CONFIGURATION](#4.7 SET_CONFIGURATION)
- [4.8 GET_INTERFACE](#4.8 GET_INTERFACE)
- [4.9 SET_INTERFACE](#4.9 SET_INTERFACE)
- [4.10 SYNCH_FRAME](#4.10 SYNCH_FRAME)
- [五、类特定请求(Class-Specific Requests)](#五、类特定请求(Class-Specific Requests))
- [5.1 HID 类请求](#5.1 HID 类请求)
- [5.2 CDC 类请求](#5.2 CDC 类请求)
- [5.3 Mass Storage 类请求](#5.3 Mass Storage 类请求)
- [六、厂商请求(Vendor Requests)](#六、厂商请求(Vendor Requests))
- 七、枚举过程请求序列实例
- [7.1 枚举请求全景图](#7.1 枚举请求全景图)
- [7.2 逐请求字节级解析](#7.2 逐请求字节级解析)
- [请求 1:获取设备描述符(8 字节)](#请求 1:获取设备描述符(8 字节))
- [请求 2:设置地址](#请求 2:设置地址)
- [请求 3:获取完整设备描述符(18 字节)](#请求 3:获取完整设备描述符(18 字节))
- [请求 4:获取配置描述符(9 字节)](#请求 4:获取配置描述符(9 字节))
- [请求 5:获取完整配置描述符集(wTotalLength = 34 字节)](#请求 5:获取完整配置描述符集(wTotalLength = 34 字节))
- [请求 6:设置配置](#请求 6:设置配置)
- 八、总结
- 一、概述
一、概述
1.1 请求的分类体系
USB 设备请求是 Host 控制 Device 行为的唯一手段。所有 USB 通信的控制面都建立在"请求-响应"模型之上。
USB 设备请求
标准请求
Standard Requests
bRequestType=0
类特定请求
Class-Specific Requests
bRequestType=1
厂商请求
Vendor Requests
bRequestType=2
GET_STATUS
SET_ADDRESS
GET/SET_DESCRIPTOR
GET/SET_CONFIGURATION
...共11个
HID: GET_REPORT
SET_REPORT
CDC: SET_LINE_CODING
Mass Storage:
Bulk-Only Reset
Video: SET_CUR
GET_CUR
厂商自定义
bRequest >= 0
三类请求的核心区别:
| 类型 | bmRequestType | 定义者 | 适用范围 |
|---|---|---|---|
| 标准请求 | Bit6~5 = 00 | USB-IF | 所有 USB 设备必须支持 |
| 类请求 | Bit6~5 = 01 | 设备类规范 | 特定类设备支持 |
| 厂商请求 | Bit6~5 = 10 | 厂商自定义 | 特定厂商设备支持 |
1.2 请求在通信中的位置
USB Device USB Host USB Device USB Host 控制传输的 Setup 阶段 请求解析与执行 alt [有数据阶段] Status 阶段 SETUP TOKEN DATA0: Setup Packet (8字节) ACK 解析 bmRequestType + bRequest 根据 wValue/wIndex 定位目标 执行请求操作 IN/OUT 事务 数据 / ACK ZLP (Zero Length Packet) ACK
关键规则:
- 所有请求都通过 控制端点 EP0 传输
- 请求本身封装在 Setup 数据包 中(8 字节固定长度)
- 数据阶段是否存在由
bmRequestType的方向位和wLength决定
二、Setup 数据包格式
2.1 Setup 包结构
bmRequestType (1B) 0 7 bRequest (1B) 8 15 wValue (2B) 16 31 wIndex (2B) 32 47 wLength (2B) 48 63 Setup 数据包结构(8 字节)
c
// Setup 数据包结构
typedef struct {
uint8_t bmRequestType; // 请求特征
uint8_t bRequest; // 请求码
uint16_t wValue; // 请求参数值
uint16_t wIndex; // 索引/偏移
uint16_t wLength; // 数据传输长度
} USB_SetupPacket; // 共 8 字节
2.2 bmRequestType 详解
bmRequestType 是整个 Setup 包的"控制字",定义了请求的方向、类型和接收者。
Bit7 | Bit6~5 | Bit4~0
方向 | 类型 | 接收者
Bit7 - 数据传输方向:
| 值 | 方向 | 含义 |
|---|---|---|
| 0 | Host → Device | OUT 方向(Host 向设备写数据) |
| 1 | Device → Host | IN 方向(Host 从设备读数据) |
Bit6~5 - 请求类型:
| 值 | 类型 | 说明 |
|---|---|---|
| 00 | Standard | 标准请求(所有设备必须支持) |
| 01 | Class | 类特定请求(由设备类规范定义) |
| 10 | Vendor | 厂商自定义请求 |
| 11 | Reserved | 保留 |
Bit4~0 - 接收者:
| 值 | 接收者 | 说明 |
|---|---|---|
| 00000 | Device | 请求针对整个设备 |
| 00001 | Interface | 请求针对特定接口 |
| 00010 | Endpoint | 请求针对特定端点 |
| 00011 | Other | 其他(Hub 端口等) |
| 其他 | Reserved | 保留 |
常见 bmRequestType 值速查:
| 请求 | bmRequestType | 二进制 |
|---|---|---|
| GET_DESCRIPTOR (Device) | 0x80 | 1 00 00000 |
| SET_ADDRESS | 0x00 | 0 00 00000 |
| SET_CONFIGURATION | 0x00 | 0 00 00000 |
| GET_STATUS (Interface) | 0x81 | 1 00 00001 |
| CLEAR_FEATURE (Endpoint) | 0x02 | 0 00 00010 |
| SET_FEATURE (Device) | 0x00 | 0 00 00000 |
| HID GET_REPORT | 0xA1 | 1 01 00001 |
| CDC SET_LINE_CODING | 0x21 | 0 01 00001 |
2.3 wValue / wIndex / wLength 解析
这三个字段的含义随请求不同而变化,需要结合具体请求来理解。
通用规则:
| 字段 | 大小 | 通用含义 | 具体含义取决于请求 |
|---|---|---|---|
| wValue | 2B | 请求参数 | 如:描述符类型+索引、特性选择器、配置值、接口值 |
| wIndex | 2B | 索引/偏移 | 如:接口号、端点号、字符串语言 ID |
| wLength | 2B | 数据长度 | Setup 之后的数据阶段期望传输的字节数 |
GET_DESCRIPTOR 请求中各字段的含义:
wValue = (描述符类型 << 8) | 描述符索引
如: 0x0100 = 设备描述符(0x01), 索引0
0x0200 = 配置描述符(0x02), 索引0
0x0301 = 字符串描述符(0x03), 索引1
wIndex = 0 (设备/配置描述符)
= 语言 ID (字符串描述符,如 0x0409)
wLength = 期望返回的字节数
如: 18 (完整设备描述符)
8 (设备描述符前8字节,用于获取 bMaxPacketSize0)
三、标准请求总览
USB 规范定义了 11 个标准请求,所有 USB 设备必须支持(Hub 还需支持额外请求)。
| bRequest | 请求名称 | 方向 | 接收者 | 数据阶段 | 主要用途 |
|---|---|---|---|---|---|
| 0x00 | GET_STATUS | IN | D/I/E | 有 | 读取设备/接口/端点状态 |
| 0x01 | CLEAR_FEATURE | - | D/I/E | 无 | 清除特性/禁用功能 |
| 0x03 | SET_FEATURE | - | D/I/E | 无 | 设置特性/启用功能 |
| 0x05 | SET_ADDRESS | - | Device | 无 | 分配设备地址 |
| 0x06 | GET_DESCRIPTOR | IN | Device | 有 | 获取描述符 |
| 0x07 | SET_DESCRIPTOR | OUT | Device | 有 | 设置描述符(很少用) |
| 0x08 | GET_CONFIGURATION | IN | Device | 有 | 获取当前配置值 |
| 0x09 | SET_CONFIGURATION | - | Device | 无 | 激活配置 |
| 0x0A | GET_INTERFACE | IN | Interface | 有 | 获取接口备用设置 |
| 0x0B | SET_INTERFACE | - | Interface | 无 | 切换接口备用设置 |
| 0x0C | SYNCH_FRAME | IN | Endpoint | 有 | 同步帧(同步传输用) |
注:bRequest = 0x02 和 0x04 为保留值,未使用。
四、标准请求详解
4.1 GET_STATUS
读取设备、接口或端点的当前状态。
USB Device USB Host USB Device USB Host SETUP: bmRequestType=0x80, bRequest=0x00, wValue=0, wIndex=0, wLength=2 ACK IN DATA: 2字节状态 ACK OUT: ZLP (Status) ACK
请求参数:
| 字段 | 设备状态 | 接口状态 | 端点状态 |
|---|---|---|---|
| bmRequestType | 0x80 | 0x81 | 0x82 |
| wValue | 0 | 0 | 0 |
| wIndex | 0 | 接口号 | 端点地址 |
| wLength | 2 | 2 | 2 |
返回的 2 字节状态:
设备状态(Device Status):
Bit0: Self-Powered 自供电 (1=是, 0=总线供电)
Bit1: Remote Wakeup 远程唤醒使能 (1=使能)
Bit2~15: Reserved 保留
接口状态(Interface Status):
所有位保留,返回 0x0000
端点状态(Endpoint Status):
Bit0: Halt 端点挂起 (1=STALL, 0=正常)
Bit1~15: Reserved 保留
4.2 CLEAR_FEATURE / SET_FEATURE
控制设备、接口或端点的特性开关。
特性选择器(Feature Selector):
| 值 | 名称 | 适用接收者 | 说明 |
|---|---|---|---|
| 0x00 | ENDPOINT_HALT | Endpoint | 端点挂起/恢复(批量/中断端点) |
| 0x01 | DEVICE_REMOTE_WAKEUP | Device | 远程唤醒使能/禁用 |
| 0x02 | TEST_MODE | Device | 测试模式(仅 High Speed) |
CLEAR_FEATURE 请求参数:
| 字段 | 端点挂起 | 远程唤醒 | 测试模式 |
|---|---|---|---|
| bmRequestType | 0x02 | 0x00 | 0x00 |
| bRequest | 0x01 | 0x01 | 0x01 |
| wValue | 0x0000 | 0x0001 | 0x0002 |
| wIndex | 端点地址 | 0 | 测试模式选择器 |
SET_FEATURE 请求参数(与 CLEAR_FEATURE 类似,仅 bRequest = 0x03):
USB Device USB Host USB Device USB Host 批量端点错误恢复 端点 STALL 状态清除 数据切换位复位为 DATA0 CLEAR_FEATURE(ENDPOINT_HALT, EP1) ACK
批量端点错误恢复 :当批量传输出现错误导致端点进入 STALL 状态时,Host 发送
CLEAR_FEATURE(ENDPOINT_HALT)清除挂起,同时端点的数据切换位(Data Toggle)被复位为 DATA0。
4.3 SET_ADDRESS
为设备分配一个唯一的 USB 地址(1~127)。这是枚举过程中最关键的状态切换点。
USB Device USB Host USB Device USB Host SET_ADDRESS (无数据阶段) Status 阶段 设备在 Status 阶段完成后 切换为新地址 SETUP: bmRequestType=0x00, bRequest=0x05, wValue=addr, wIndex=0, wLength=0 ACK IN: 请求 ZLP DATA0: ZLP ACK
请求参数:
| 字段 | 值 |
|---|---|
| bmRequestType | 0x00 (Host→Device, Standard, Device) |
| bRequest | 0x05 |
| wValue | 新地址 (1 ~ 127) |
| wIndex | 0 |
| wLength | 0 |
关键规则:
- 设备在 Status 阶段完成后 才切换为新地址
- 如果地址 = 0,设备回到 Default State
- 如果地址非 0,设备进入 Address State
- SET_ADDRESS 请求本身使用旧地址(通常是地址 0)发送
4.4 GET_DESCRIPTOR
Host 获取设备描述符,是枚举阶段使用频率最高的请求。
USB Device USB Host USB Device USB Host GET_DESCRIPTOR(Device, 18字节) SETUP: 0x80, 0x06, 0x0100, 0x0000, 0x0012 ACK IN DATA1: 18字节设备描述符 ACK OUT: ZLP ACK
wValue 编码:
wValue = (bDescriptorType << 8) | bDescriptorIndex
| bDescriptorType | 名称 | wValue (Index=0) |
|---|---|---|
| 0x01 | Device | 0x0100 |
| 0x02 | Configuration | 0x0200 |
| 0x03 | String | 0x0300 ~ 0x03FF |
| 0x04 | Interface | 0x0400 |
| 0x05 | Endpoint | 0x0500 |
| 0x06 | Device Qualifier | 0x0600 |
| 0x07 | Other Speed Configuration | 0x0700 |
| 0x08 | Interface Power | 0x0800 |
| 0x09 | OTG | 0x0900 |
| 0x0A | Debug | 0x0A00 |
| 0x0B | Interface Association | 0x0B00 |
wIndex 的用途:
- 设备/配置/接口/端点描述符:wIndex = 0
- 字符串描述符:wIndex = 语言 ID(如 0x0409 = 英语-美国)
wLength 的技巧:
- Host 可能请求比描述符实际长度更短的数据(如先请求 8 字节获取 bMaxPacketSize0)
- 设备返回的数据量 = min(wLength, 描述符实际长度)
- 如果 wLength 大于描述符长度,设备只返回实际长度
4.5 SET_DESCRIPTOR
用于更新或添加描述符。在大多数设备中很少使用,因为描述符通常是固件中固定的。
| 字段 | 值 |
|---|---|
| bmRequestType | 0x00 (OUT) |
| bRequest | 0x07 |
| wValue | (描述符类型 << 8) | 索引 |
| wIndex | 语言 ID 或 0 |
| wLength | 描述符长度 |
4.6 GET_CONFIGURATION
获取设备当前激活的配置值。
| 字段 | 值 |
|---|---|
| bmRequestType | 0x80 (IN, Standard, Device) |
| bRequest | 0x08 |
| wValue | 0 |
| wIndex | 0 |
| wLength | 1 |
返回数据 :1 字节,当前配置值(即 Configuration Descriptor 中的 bConfigurationValue)
- 0 = 未配置(Default/Address State)
- 非 0 = 当前激活的配置编号
4.7 SET_CONFIGURATION
激活设备的某个配置,是枚举过程最后一个状态切换点。
USB Device USB Host USB Device USB Host SET_CONFIGURATION (无数据阶段) 设备进入 Configured State 非零端点全部激活 SETUP: 0x00, 0x09, wValue=configValue, wIndex=0, wLength=0 ACK IN: 请求 ZLP DATA0: ZLP ACK
请求参数:
| 字段 | 值 |
|---|---|
| bmRequestType | 0x00 |
| bRequest | 0x09 |
| wValue | 配置值 (bConfigurationValue) |
| wIndex | 0 |
| wLength | 0 |
设备状态变化:
| wValue | 设备状态变化 |
|---|---|
| 0 | Configured → Address(去激活) |
| 非 0 | Address → Configured(激活配置) |
配置激活后,接口描述符中定义的所有非零端点被使能,可以开始正常数据传输。
4.8 GET_INTERFACE
获取指定接口当前使用的**备用设置(Alternate Setting)**编号。
| 字段 | 值 |
|---|---|
| bmRequestType | 0x81 (IN, Standard, Interface) |
| bRequest | 0x0A |
| wValue | 0 |
| wIndex | 接口编号 |
| wLength | 1 |
返回数据 :1 字节,当前备用设置值(bAlternateSetting)
典型应用:USB 音频设备中,Host 查询当前音频接口使用的采样率设置。
4.9 SET_INTERFACE
切换接口的备用设置。
| 字段 | 值 |
|---|---|
| bmRequestType | 0x01 (OUT, Standard, Interface) |
| bRequest | 0x0B |
| wValue | 新的备用设置值 |
| wIndex | 接口编号 |
| wLength | 0 |
典型应用:
- USB 音频设备切换采样率(如 44.1kHz ↔ 48kHz)
- USB 视频设备切换分辨率
- 切换后,该接口的端点配置会相应改变
4.10 SYNCH_FRAME
用于同步传输的端点,获取某个端点当前所在的帧号。
| 字段 | 值 |
|---|---|
| bmRequestType | 0x82 (IN, Standard, Endpoint) |
| bRequest | 0x0C |
| wValue | 0 |
| wIndex | 同步端点地址 |
| wLength | 2 |
返回数据:2 字节,当前帧号(0~2047)
用途:Host 和 Device 的同步传输端点通过帧号对齐,确保数据在正确的时隙传输。
五、类特定请求(Class-Specific Requests)
类特定请求由各个设备类规范定义,标准请求无法满足类设备的特殊需求时使用。
HID Class 0x03
GET_REPORT
SET_REPORT
GET_IDLE
SET_IDLE
GET_PROTOCOL
SET_PROTOCOL
CDC Class 0x02
SET_LINE_CODING
GET_LINE_CODING
SET_CONTROL_LINE_STATE
SEND_BREAK
Mass Storage 0x08
Bulk-Only Reset
Get Max LUN
Video Class 0x0E
SET_CUR
GET_CUR
GET_MIN/MAX/RES/DEF
5.1 HID 类请求
| bRequest | 名称 | bmRequestType | 说明 |
|---|---|---|---|
| 0x01 | GET_REPORT | 0xA1 | 获取 HID 报告 |
| 0x09 | SET_REPORT | 0x21 | 设置 HID 报告(如 LED 状态) |
| 0x02 | GET_IDLE | 0xA1 | 获取空闲速率 |
| 0x0A | SET_IDLE | 0x21 | 设置空闲速率(多久无变化发一次报告) |
| 0x03 | GET_PROTOCOL | 0xA1 | 获取协议(Boot/Report) |
| 0x0B | SET_PROTOCOL | 0x21 | 切换协议 |
SET_REPORT 实例(设置键盘 LED):
Setup Packet:
bmRequestType = 0x21 (OUT, Class, Interface)
bRequest = 0x09 (SET_REPORT)
wValue = 0x0200 (Report Type=Output, Report ID=0)
Bit7~8: Report Type (1=Input, 2=Output, 3=Feature)
Bit0~7: Report ID
wIndex = 0x0000 (Interface 0)
wLength = 0x0001 (1 字节)
Data Stage (OUT):
DATA: 0x02 (Bit1=1 = Num Lock LED On)
5.2 CDC 类请求
| bRequest | 名称 | bmRequestType | 说明 |
|---|---|---|---|
| 0x20 | SET_LINE_CODING | 0x21 | 设置串口参数(波特率等) |
| 0x21 | GET_LINE_CODING | 0xA1 | 获取串口参数 |
| 0x22 | SET_CONTROL_LINE_STATE | 0x21 | 设置 DTR/RTS 信号 |
| 0x23 | SEND_BREAK | 0x21 | 发送 Break 信号 |
SET_LINE_CODING 数据结构(7 字节):
c
typedef struct {
uint32_t dwDTERate; // 波特率 (如 115200 = 0x0001C200)
uint8_t bCharFormat; // 停止位: 0=1位, 1=1.5位, 2=2位
uint8_t bParityType; // 校验: 0=None, 1=Odd, 2=Even, 3=Mark, 4=Space
uint8_t bDataBits; // 数据位: 5, 6, 7, 8, 16
} CDC_LineCoding_t;
5.3 Mass Storage 类请求
| bRequest | 名称 | bmRequestType | 说明 |
|---|---|---|---|
| 0xFF | Bulk-Only Reset | 0x21 | 复位批量传输协议 |
| 0xFE | Get Max LUN | 0xA1 | 获取最大逻辑单元号 |
六、厂商请求(Vendor Requests)
当标准请求和类请求都无法满足需求时,厂商可以定义自己的请求。
USB Device USB Host USB Device USB Host 厂商自定义请求示例 bmRequestType=0x40 0=OUT方向 10=Vendor类型 00000=Device接收者 SETUP: bmRequestType=0x40, bRequest=0x01 ACK
定义规则:
bmRequestType的 Bit6~5 = 10 (Vendor)bRequest值由厂商自定义(通常从 0x00 开始)- 需要配合厂商提供的驱动使用
常见应用场景:
- 固件更新(DFU 的底层实现)
- 设备参数校准
- 自定义诊断命令
- 调试接口
七、枚举过程请求序列实例
7.1 枚举请求全景图
设备插入 + 速度识别
GET_DESCRIPTOR
Device, 8字节
获取 bMaxPacketSize0
SET_ADDRESS
分配地址
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
激活配置
设备就绪
7.2 逐请求字节级解析
以下是一个 Full Speed HID 键盘枚举过程中的实际请求序列:
请求 1:获取设备描述符(8 字节)
目的 : 获取 bMaxPacketSize0,确定 EP0 最大包大小
阶段: Default State,地址 = 0
Setup Packet (8字节):
| 字段 | bmRequestType | bRequest | wValue | wIndex | wLength |
|---|---|---|---|---|---|
| 值 | 0x80 | 0x06 | 0x0100 | 0x0000 | 0x0008 |
| 二进制 | 10000000 | 00000110 | 00000001 | 00000000 | 00000000 |
解析:
bmRequestType = 0x80 = 1 00 00000- 方向: Device→Host (IN)
- 类型: Standard
- 接收者: Device
bRequest = 0x06 = GET_DESCRIPTORwValue = 0x0100 = (0x01 << 8) | 0x00- 描述符类型 = 0x01 (Device Descriptor)
- 描述符索引 = 0x00
wIndex = 0x0000 = 0wLength = 0x0008 = 8 字节
响应:
- Data Stage (IN): 8 字节设备描述符前 8 字节
- Status Stage (OUT): ZLP, ACK
请求 2:设置地址
目的 : 分配设备地址 = 5
阶段: Default State → Address State
Setup Packet:
| 字段 | bmRequestType | bRequest | wValue | wIndex | wLength |
|---|---|---|---|---|---|
| 值 | 0x00 | 0x05 | 0x0005 | 0x0000 | 0x0000 |
| 二进制 | 00000000 | 00000101 | 00000000 | 00000000 | 00000000 |
解析:
bmRequestType = 0x00 = OUT, Standard, DevicebRequest = 0x05 = SET_ADDRESSwValue = 0x0005 = 新地址 = 5wLength = 0x0000 = 无数据阶段
注意: 此请求本身仍使用地址 0 发送。设备在 Status 阶段完成后才切换为地址 5。
请求 3:获取完整设备描述符(18 字节)
目的 : 获取 VID/PID/版本/配置数量等完整信息
阶段: Address State,地址 = 5
Setup Packet:
| 字段 | bmRequestType | bRequest | wValue | wIndex | wLength |
|---|---|---|---|---|---|
| 值 | 0x80 | 0x06 | 0x0100 | 0x0000 | 0x0012 |
解析:
wLength = 0x0012 = 18 字节(完整设备描述符长度)- 其他字段与请求 1 相同
响应:
- Data Stage (IN): 18 字节完整设备描述符
请求 4:获取配置描述符(9 字节)
目的: 获取配置描述符,提取 wTotalLength
Setup Packet:
| 字段 | bmRequestType | bRequest | wValue | wIndex | wLength |
|---|---|---|---|---|---|
| 值 | 0x80 | 0x06 | 0x0200 | 0x0000 | 0x0009 |
解析:
wValue = 0x0200 = (0x02 << 8) | 0x00- 描述符类型 = 0x02 (Configuration Descriptor)
wLength = 0x0009 = 9 字节
响应 Data 中关键字段:
byte[2~3] = wTotalLength = 0x0022(34 字节)- → 下一次请求将请求 34 字节以获取完整配置描述符集
请求 5:获取完整配置描述符集(wTotalLength = 34 字节)
Setup Packet:
| 字段 | bmRequestType | bRequest | wValue | wIndex | wLength |
|---|---|---|---|---|---|
| 值 | 0x80 | 0x06 | 0x0200 | 0x0000 | 0x0022 |
解析:
wLength = 0x0022 = 34 字节 = wTotalLength
响应 Data:
- 包含: 配置描述符(9B) + 接口描述符(9B) + HID描述符(9B) + 端点描述符(7B) = 34 字节
请求 6:设置配置
目的 : 激活配置值 = 1
阶段: Address State → Configured State
Setup Packet:
| 字段 | bmRequestType | bRequest | wValue | wIndex | wLength |
|---|---|---|---|---|---|
| 值 | 0x00 | 0x09 | 0x0001 | 0x0000 | 0x0000 |
解析:
bRequest = 0x09 = SET_CONFIGURATIONwValue = 0x0001 = 配置值 = 1wLength = 0x0000 = 无数据阶段
结果:
- 设备进入 Configured State
- 接口 0 定义的端点(EP1 IN 中断)被激活
- 设备现在可以接受正常的 HID 输入报告
八、总结
请求执行流程
有
无
Host 构造 Setup 包
通过 EP0 发送
Device 解析并执行
有数据阶段?
IN/OUT 数据传输
ZLP Status 握手
标准请求 (11个)
GET_STATUS
CLEAR/SET_FEATURE
SET_ADDRESS
GET/SET_DESCRIPTOR
GET/SET_CONFIGURATION
GET/SET_INTERFACE
SYNCH_FRAME
Setup 数据包
Bit7: 方向
0=OUT, 1=IN
Bit6~5: 类型
00=Std, 01=Class, 10=Vendor
Bit4~0: 接收者
0=Dev, 1=If, 2=EP
学习要点回顾:
| 要点 | 说明 |
|---|---|
| Setup 包 | 固定 8 字节,是所有请求的统一信封 |
| bmRequestType | 核心控制字,决定方向/类型/接收者 |
| 标准请求 | 11 个,枚举和控制的基础 |
| GET_DESCRIPTOR | 枚举中使用最频繁的请求 |
| SET_ADDRESS | 枚举状态切换点,注意地址切换时机 |
| SET_CONFIGURATION | 设备就绪的标志,非零端点激活 |
| 类请求 | HID/CDC/MSC 等类设备的扩展控制 |
| 厂商请求 | 自定义功能,需配合厂商驱动 |