当前位置: 首页 > news >正文

USB 描述符怎么写都不对?别只抄例程,看看 bLength 与 wTotalLength

摘要:USB 描述符复制了例程,只是改了个 PID,电脑就提示“设备描述符请求失败”?不是 USB 栈坏了,而是描述符长度(bLength)或总长度(wTotalLength)算错了。本文拆解 USB 描述符的“字节级”潜规则。


一、问题描述(现象)

**用 CubeMX 生成的 HID 例程,枚举一切正常;

只是加了一个自定义 Usage Page,设备管理器就开始报黄叹号;

Bus Hound 抓包显示 GET_DESCRIPTOR 返回的数据长度不对。**

很多工程师的排查方向是:

  1. 是不是 PID/VID 冲突了?

  2. 描述符数组是不是没对齐?

  3. 换个 USB 端口试试?


二、原理分析

1. 物理模型

USB 主机在枚举时,会先问设备:“你多长?”

Host: GET_DESCRIPTOR (wLength = 64) Device: [Descriptor Data...]

2. 核心参数

  • bLength:当前这个描述符结构体的实际字节数

  • wTotalLength整个配置描述符集合(Configuration + Interface + Endpoint)的总字节数。

3. 反直觉真相

USB 主机根本不相信你给的长度,它会自己算。

  • 如果你在代码中修改了某个描述符(比如多加了一个 Endpoint)。

  • 但忘了更新wTotalLength

  • 结果:主机算出的长度和实际发送的不一致 → 枚举失败。


三、工程级解决方案

方案 1:手算长度(最稳,推荐)

Configuration Descriptor​ 为例:

// 标准配置描述符长度 = 9 字节 // 接口描述符 = 9 字节 // 端点描述符 = 7 字节 // 如果有两个端点: wTotalLength = 9 + 9 + 7 + 7 = 32;

切记:wTotalLength小端格式(低字节在前)。

方案 2:利用编译器自动算(进阶)

如果是 C 语言,可以用结构体技巧。

typedef struct { USB_ConfigDescTypeDef config; USB_InterfaceDescTypeDef interface; USB_EndpointDescTypeDef ep_in; USB_EndpointDescTypeDef ep_out; } __attribute__((packed)) USBD_CDC_DescTypedef; #define USBD_CDC_DESC_SIZE sizeof(USBD_CDC_DescTypedef)

方案 3:用工具验证

不要只靠眼睛看。

  • USBView (Windows):直接展开描述符树,看每一项的长度是否正确。

  • Bus Hound:查看 GET_DESCRIPTOR 返回的原始字节流。


四、选型避坑建议

  1. bLength 必须精确

    • Device Descriptor = 18 bytes

    • Configuration Descriptor = 9 bytes

    • Interface Descriptor = 9 bytes

    • Endpoint Descriptor = 7 bytes

  2. 字符串描述符

    • bLength包含字符串长度 × 2 + 2(Unicode)。

  3. 不要混用:HID 描述符有自己的长度计算方法,不能直接套用 CDC/MSC。


五、总结 Checklist

  • [ ] 是否检查了每个描述符的bLength是否正确?

  • [ ] 修改描述符后,是否更新了wTotalLength

  • [ ]wTotalLength是否按小端格式填写?

  • [ ] 是否用 USBView/Bus Hound 验证过原始数据?


六、写在最后(关注我,少走弯路)

我是 gqqsherry,一个拒绝调包、专注底层逻辑的嵌入式工程师。

USB 描述符是“写一次,调三天”的典型代表,一个字节的错误就能让整个设备变砖。

关注我的专栏《嵌入式底层避坑指南》,我会持续更新 USB、CAN、UART 等外设的真实调试案例量产级解决方案

👉下一篇预告:《USB CDC 虚拟串口识别不了?别只怪驱动,看看 VID/PID 与 INF》


References

  • USB 2.0 Specification – Chapter 9 (Device Framework)

  • Microsoft Docs – USB Descriptor Overview


如果你在写 USB 描述符时遇到过“怎么改都报错”的情况,欢迎在评论区晒出你的描述符代码片段。

原创文章,转载请注明出处。

http://www.rkmt.cn/news/1485981.html

相关文章:

  • ArcGIS工具箱实战:手把手教你定制自己的MODIS数据处理工具(附完整Python代码)
  • Wand-Enhancer:免费解锁Wand专业版功能的终极增强工具
  • 成都市2026年黄金回收白银回收铂金回收 5 家高性价比门店实地测评盘点 - 马刺总冠军
  • 如何用AI轻松征服2048游戏?这款智能助手让你胜率提升85%
  • STM32F103C8T6智慧大棚实战工程:OneNET云直连+光照/温湿度/CO₂/土壤墒情四合一采集与远程开关控制
  • 3分钟掌握科研数据提取:WebPlotDigitizer从图表图像中智能提取数值数据
  • 2026上饶市权威认证贵金属回收 TOP5+黄金回收白银回收铂金回收门店地址电话推荐
  • PRISM架构:白盒Transformer的信号-噪声分解技术解析
  • Beyond Compare过滤.DS_Store和__pycache__,Mac/Win双平台保姆级配置
  • 如何3分钟搞定抖音批量下载:douyin-downloader完全指南
  • AD9361/AD9363接收功能验证:从官方配置软件到SPI脚本的完整避坑指南
  • 避坑指南:在Windows 11上安装配置罗技G HUB最新版,并成功运行第一个Lua脚本
  • STM32 FOC电机控制实战:从定时器PWM到ADC同步采样的完整配置避坑指南
  • 从族谱到文件系统:3种遍历(先根/后根/层次)搞定‘树’的实际应用场景
  • 射频芯片技术演进与市场战略:从GaAs/SiGe工艺到系统级解决方案
  • XHS-Downloader数据持久化架构:轻量级存储方案与高效查询优化
  • Gemini 3.1 辅助论文写作实操:选题到定稿每一步怎么用
  • 3分钟搞定网易云插件:BetterNCM-Installer终极安装指南
  • ArcGIS坡度计算翻车实录:地理坐标系的DEM,Z因子到底怎么设?(附28°N实测参数)
  • 从外企到华强北:工程师如何将“信用”打造成硬核商业资产
  • 2026上海市权威认证贵金属回收 TOP5+黄金回收白银回收铂金回收门店地址电话推荐
  • 毕业设计用的Python入侵检测系统:带真实流量数据、SVM模型代码和详细运行指南
  • Linux服务器离线部署PyTorch1.10 GPU版(CUDA11.3)完整流程:从驱动更新到whl包手动安装
  • Solidworks 2018 默认模板修改:手把手教你打造Z轴朝上的个人专属坐标系
  • 大模型微调三层进阶:PyTorch→Transformers→Lightning实战路径
  • 大模型底层原理:注意力机制优化与长上下文处理
  • 豆瓣Top250电影数据采集与可视化分析系统(Flask+Echarts可运行全栈Demo)
  • AMD Ryzen调试工具SMUDebugTool终极指南:如何深度掌控你的处理器性能
  • 告别单用户!用JMeter CSV参数化搞定多用户登录压力测试(附完整脚本)
  • 告别CloudDrive!用开源WebDAV Client在群晖上挂载任意网盘(附Docker Compose配置)