USB -- SET_ADDRESS or --SET_ADDRESS or --SET_CONFIGURATION or --SET_INTERFACE

AI 生成

USB 枚举过程中最核心的四个控制请求:

USB 枚举流程(就像"设备入职流程")

想象一个新员工入职公司:

公司流程 对应 USB 操作
1. 登记基本信息(姓名、身份证) GET_DESCRIPTOR
2. 分配工号 SET_ADDRESS
3. 安排部门和岗位 SET_CONFIGURATION
4. 设置具体工作权限(如打印机权限) SET_INTERFACE

🔍 逐个解析

1. 🟦 GET_DESCRIPTOR ------ "请介绍一下你自己"

📌 目的:

让主机获取设备的基本信息,判断它是什么类型的设备。

🧩 常见描述符类型:
描述符 内容
Device Descriptor 厂商、产品、版本、支持配置数等
Configuration Descriptor 功耗、接口数量、端点信息
String Descriptor 厂商名、产品名、序列号(人类可读)
Interface Descriptor 接口类(如 HID、CDC、MSC)
Endpoint Descriptor 端点地址、传输类型、包大小
📥 请求格式(SETUP 包):
复制代码
bmRequestType: 0x80  // Device → Host
bRequest:      0x06  // GET_DESCRIPTOR
wValue:        0x0100 // 高字节=类型(1=Device), 低字节=索引
wIndex:        0x0000
wLength:       0x0012 // 请求长度(如 18 字节)
📤 响应示例:
复制代码
Device Descriptor:
  idVendor  = 0x2341 (QinHeng)
  idProduct = 0x7523
  bNumConfigurations = 1

✅ 这是主机认识设备的第一步。


2. 🟨 SET_ADDRESS ------ "你的新工号是 13"

📌 目的:

为主机分配一个唯一的地址(非 0),以便后续通信。

🧩 为什么需要?
  • 所有设备刚插入时地址都是 0x00(默认地址)
  • 如果多个设备同时使用 0x00,会冲突
  • 所以主机必须为每个设备分配唯一地址(0x01 ~ 0x7F
📥 请求格式:
复制代码
bmRequestType: 0x00  // Host → Device
bRequest:      0x05  // SET_ADDRESS
wValue:        0x0013 // 新地址 = 0x13
wIndex:        0x0000
wLength:       0x0000 // 无数据
📤 响应:
  • 设备返回 ACK
  • 设备内部切换地址为 0x13
  • 后续通信使用 Addr=0x13

⚠️ 注意:SET_ADDRESS 是唯一一个在地址 0x00 上执行,但影响未来地址的命令。


3. 🟩 SET_CONFIGURATION ------ "你属于研发部,配置编号 1"

📌 目的:

启用设备的某个配置(Configuration),使其进入工作状态。

🧩 为什么需要?
  • 一个设备可以有多个配置(如省电模式 vs 高性能模式)
  • 但只能启用一个
  • 主机选择最合适的配置并激活它
📥 请求格式:
复制代码
bmRequestType: 0x00  // Host → Device
bRequest:      0x09  // SET_CONFIGURATION
wValue:        0x0001 // 启用配置 1
wIndex:        0x0000
wLength:       0x0000
📤 响应:
  • 设备返回 ACK
  • 设备初始化所有接口和端点
  • 可以开始正常通信

✅ 这是设备"真正开始工作"的标志。


4. 🟪 SET_INTERFACE ------ "你现在使用调试接口"

📌 目的:

在某个配置中,切换接口的备用设置(Alternate Setting)

🧩 为什么需要?
  • 一个接口可以有多个"备用设置"(Alternate Settings)
  • 例如:音频设备可以有不同采样率
  • 或复合设备中启用特定功能
📥 请求格式:
复制代码
bmRequestType: 0x01  // Interface → Host
bRequest:      0x0B  // SET_INTERFACE
wValue:        0x0000 // 使用 Alternate Setting 0
wIndex:        0x0000 // 接口编号
wLength:       0x0000
📤 响应:
  • 设备返回 ACK
  • 切换到指定的接口设置
  • 可能重新配置端点

💡 示例:

  • 音频设备:切换采样率(44.1kHz → 48kHz)
  • 网卡:启用/禁用 VLAN 支持
  • 复合设备:只启用串口,关闭打印机

✅ 四者的执行顺序(典型枚举流程)

复制代码
1. GET_DESCRIPTOR (获取设备描述符)
2. GET_DESCRIPTOR (获取配置描述符)
3. SET_ADDRESS (分配地址,如 0x13)
4. GET_DESCRIPTOR (再次获取设备/配置描述符,验证)
5. GET_DESCRIPTOR (获取字符串描述符,如产品名)
6. SET_CONFIGURATION (启用配置 1)
7. SET_INTERFACE (可选,设置接口模式)

✅ 一旦完成,设备就可以正常通信了。


🧩 类比理解(公司入职流程)

USB 命令 公司对应操作 类比说明
GET_DESCRIPTOR HR 问:"你是谁?有什么技能?" 获取基本信息
SET_ADDRESS 分配工号 唯一标识,避免混淆
SET_CONFIGURATION 安排部门和岗位 决定整体工作模式
SET_INTERFACE 设置具体权限(如门禁卡权限) 微调功能,启用子模块

✅ 总结对比表

命令 方向 目的 是否必须 示例
GET_DESCRIPTOR Host → Device 获取设备信息 ✅ 必须 读取厂商、产品、配置数
SET_ADDRESS Host → Device 分配唯一地址 ✅ 必须 wValue=0x13
SET_CONFIGURATION Host → Device 启用配置 ✅ 必须 wValue=0x01
SET_INTERFACE Host → Device 切换接口设置 ❌ 可选 音频采样率切换

💡 实际抓包中的体现

如果你用 Wireshark 抓包,你会看到类似:

复制代码
SETUP: GET_DESCRIPTOR (Device)
IN: DATA0 (设备描述符)
OUT: ACK

SETUP: SET_ADDRESS (wValue=0x13)
IN: DATA1 (空包) ← STATUS 阶段
OUT: ACK

SETUP: SET_CONFIGURATION (wValue=0x01)
IN: DATA1 (空包) ← STATUS 阶段
OUT: ACK

✅ 每个 SET_* 命令后都有一个 STATUS 阶段(OUT + DATA1)


✅ 最终结论

这四个命令是 USB 枚举的核心:

  • GET_DESCRIPTOR认识设备
  • SET_ADDRESS分配身份
  • SET_CONFIGURATION启动设备
  • SET_INTERFACE微调功能

它们共同完成了从"设备插入"到"可以正常使用"的全过程。

相关推荐
深圳佛手3 分钟前
几种限流算法介绍和使用场景
网络·算法
拾忆,想起14 分钟前
超时重传 vs 快速重传:TCP双保险如何拯救网络丢包?
java·开发语言·网络·数据库·网络协议·tcp/ip·php
2021_fc27 分钟前
WebSocket技术分享
网络·websocket·网络协议
zizisuo43 分钟前
为什么TCP设计中要设计ACK不重传?
网络·网络协议·tcp/ip
偶像你挑的噻1 小时前
Linux应用开发-17-套接字
linux·网络·stm32·嵌入式硬件
AI分享猿1 小时前
小白学规则编写:雷池 WAF 配置教程,用 Nginx 护住 WordPress 博客
java·网络·nginx
AORO20252 小时前
遨游科普:三防平板是指哪三防?有哪些应用场景?
大数据·网络·5g·智能手机·电脑·信息与通信
鸢尾掠地平2 小时前
DNS的正向、反向解析的服务配置知识点及实验
运维·服务器·网络
草莓熊Lotso2 小时前
C++ 方向 Web 自动化测试实战:以博客系统为例,从用例到报告全流程解析
前端·网络·c++·人工智能·后端·python·功能测试
GhostGuardian2 小时前
DNS报文结构全解析
网络·网络协议