cpp
__USB_ALIGN_BEGIN static uint8_t usb_dev_cdc_cfgdesc[USB_CDC_CONFIG_DESC_SIZ] = {
0x09,
USB_CFG_DESCRIPTOR_TYPE,///* wTotalLength 低字节 */
USB_CDC_CONFIG_DESC_SIZ,//* wTotalLength 高字节 */
0x00,
0x02,
0x01,
0x00,
0xC0,
0x32,
将wTotalLength 16位总长度拆分为USB小端格式(Little-Endian)
一、USB协议层:小端序强制要求
USB协议规定所有多字节字段必须采用小端序(Little-Endian)传输:
低字节在前,高字节在后。
wTotalLength 是配置描述符中最重要的字段之一,它告知主机整个配置描述符集合的总长度,是USB枚举的"导航地图"。
二、核心作用:主机内存分配的"标尺"
场景:主机获取完整描述符
USB枚举过程中,主机分两步获取配置描述符:
第一步:获取配置描述符头部(仅9字节)
主机 → 设备: GET_DESCRIPTOR(CONFIGURATION, 0, 9)
设备 → 主机: [9字节配置头,含wTotalLength]
第二步:根据wTotalLength获取完整数据
主机读取wTotalLength = 273 (0x0111)
主机 → 设备: GET_DESCRIPTOR(CONFIGURATION, 0, 273) // 请求全部字节
设备 → 主机: [273字节完整配置包]
作用:主机动态分配足够内存,一次性读取所有接口、端点、功能描述符,避免多次小数据包传输。
三、完整配置包结构示例
wTotalLength = 273字节的实际内容:
┌────────────────────────────────────┐
│ 配置描述符 (9字节) │
├────────────────────────────────────┤
│ IAD描述符 (8字节) │
├────────────────────────────────────┤
│ 接口0描述符 (9字节) │
├────────────────────────────────────┤
│ 功能描述符 (Header/ACM/Union) │
├────────────────────────────────────┤
│ 端点描述符2 (7字节) │
├────────────────────────────────────┤
│ 接口1描述符 (9字节) │
├────────────────────────────────────┤
│ 端点描述符1 OUT (7字节) │
├────────────────────────────────────┤
│ 端点描述符1 IN (7字节) │
├────────────────────────────────────┤
│ ...CDC#2/3/4重复结构... │
└────────────────────────────────────┘
关键: wTotalLength 包含了所有下级描述符的长度之和。