F460 配置描述符、接口描述符和端点描述符

c 复制代码
__USB_ALIGN_BEGIN static uint8_t usb_dev_cdc_cfgdesc[USB_CDC_CONFIG_DESC_SIZ]  = {
    0x09,
    USB_CFG_DESCRIPTOR_TYPE,
    USB_CDC_CONFIG_DESC_SIZ,
    0x00,
    0x02,
    0x01,
    0x00,
    0xC0,
    0x32,

    0x08,
    0x0B,
    0x00,
    0x02,
    0x02,
    0x02,
    0x01,
    0x04,

    0x09,
    USB_INTERFACE_DESCRIPTOR_TYPE,
    0x00,
    0x00,
    0x01,
    0x02,
    0x02,
    0x01,
    0x00,

    0x05,
    0x24,
    0x00,
    0x10,
    0x01,

    0x05,
    0x24,
    0x01,
    0x00,
    0x01,

    0x04,
    0x24,
    0x02,
    0x02,

    0x05,
    0x24,
    0x06,
    0x00,
    0x01,

    0x07,
    USB_ENDPOINT_DESCRIPTOR_TYPE,
    CDC_CMD_EP,
    0x03,
    LOBYTE(CDC_CMD_PACKET_SIZE),
    HIBYTE(CDC_CMD_PACKET_SIZE),
    0xFF,

    0x09,
    USB_INTERFACE_DESCRIPTOR_TYPE,
    0x01,
    0x00,
    0x02,
    0x0A,
    0x00,
    0x00,
    0x00,

    0x07,
    USB_ENDPOINT_DESCRIPTOR_TYPE,
    CDC_OUT_EP,
    0x02,
    LOBYTE(MAX_CDC_PACKET_SIZE),
    HIBYTE(MAX_CDC_PACKET_SIZE),
    0x00,

    0x07,
    USB_ENDPOINT_DESCRIPTOR_TYPE,
    CDC_IN_EP,
    0x02,
    LOBYTE(MAX_CDC_PACKET_SIZE),
    HIBYTE(MAX_CDC_PACKET_SIZE),
    0x00
} ;

F460 USB CDC(Communication Device Class)设备的完整配置描述符(Configuration Descriptor),它定义了该 USB 设备在 CDC 模式下的整体结构,包括接口、端点和 CDC 类特定的功能描述符。

我们将逐段解析这个描述符数组 usb_dev_cdc_cfgdesc,并解释每个字段的含义。


📌 总体结构说明

CDC 设备通常包含 两个接口

  1. 通信类接口(Control Interface):用于发送/接收控制命令(如 AT 指令),使用一个中断端点(IN)。
  2. 数据类接口(Data Interface):用于批量传输数据(如串口数据),使用两个批量端点(IN + OUT)。

此外,CDC 还需要若干 类特定描述符(Class-Specific Descriptors),如:

  • Header Functional Descriptor
  • Call Management Functional Descriptor
  • ACM (Abstract Control Model) Functional Descriptor
  • Union Functional Descriptor

这些都嵌套在第一个接口描述符之后、端点描述符之前。


🔍 逐段解析(按字节顺序)

✅ 1. 配置描述符(Configuration Descriptor)

c 复制代码
0x09,                           // bLength = 9 字节
USB_CFG_DESCRIPTOR_TYPE,        // bDescriptorType = 0x02 (配置描述符)
USB_CDC_CONFIG_DESC_SIZ,        // wTotalLength = 整个配置描述符总长度(低字节)
0x00,                           // wTotalLength 高字节(假设为 0x0067 = 103 字节)
0x02,                           // bNumInterfaces = 2 个接口
0x01,                           // bConfigurationValue = 1(激活此配置时用)
0x00,                           // iConfiguration = 0(无配置字符串)
0xC0,                           // bmAttributes = 1100 0000
                                //   D7=1(必须为1),D6=1(自供电),D5=0(不支持远程唤醒)
0x32                            // MaxPower = 100 mA(0x32 * 2mA = 100mA)

💡 注意:wTotalLength 必须等于整个配置描述符(包括所有接口、端点、CDC 功能描述符)的总字节数。这里高字节是 0x00,低字节来自宏 USB_CDC_CONFIG_DESC_SIZ,应为 0x67(103)左右。


✅ 2. IAD 描述符(Interface Association Descriptor)

⚠️ 虽然类型是 0x0B,但这是 IAD,用于告诉主机"接下来的多个接口属于同一个功能"。

c 复制代码
0x08,               // bLength = 8
0x0B,               // bDescriptorType = IAD (0x0B)
0x00,               // bFirstInterface = 0(从接口 0 开始关联)
0x02,               // bInterfaceCount = 2(关联 2 个接口:0 和 1)
0x02,               // bFunctionClass = CDC Communication Class (0x02)
0x02,               // bFunctionSubClass = Abstract Control Model (ACM)
0x01,               // bFunctionProtocol = AT Commands (V.250 etc.)
0x04                // iFunction = 4(配置字符串索引,对应你之前定义的 CONFIG_STR_IDX=4)

✅ IAD 是 USB 2.0 后推荐的方式,让复合设备(如 CDC+MSC)能被正确识别为一个逻辑设备。


✅ 3. 接口 0:通信类接口(Control Interface)

c 复制代码
0x09,                               // bLength = 9
USB_INTERFACE_DESCRIPTOR_TYPE,      // bDescriptorType = 0x04(接口描述符)
0x00,                               // bInterfaceNumber = 0
0x00,                               // bAlternateSetting = 0
0x01,                               // bNumEndpoints = 1(只有命令端点)
0x02,                               // bInterfaceClass = CDC Communication (0x02)
0x02,                               // bInterfaceSubClass = ACM (0x02)
0x01,                               // bInterfaceProtocol = AT Commands (0x01)
0x00                                // iInterface = 0(无接口字符串)

✅ 4. CDC 类特定描述符(嵌套在接口 0 中)

a) Header Functional Descriptor
c 复制代码
0x05,       // bLength = 5
0x24,       // bDescriptorType = CS_INTERFACE (0x24)
0x00,       // bDescriptorSubtype = Header (0x00)
0x10, 0x01  // bcdCDC = 0x0110 = USB CDC v1.10
b) Call Management Functional Descriptor
c 复制代码
0x05,       // bLength = 5
0x24,       // CS_INTERFACE
0x01,       // Subtype = Call Management (0x01)
0x00,       // bmCapabilities = 0x00 → 不处理呼叫管理,由 Data Interface 处理
0x01        // bDataInterface = 1(数据接口编号)
c) ACM Functional Descriptor
c 复制代码
0x04,       // bLength = 4
0x24,       // CS_INTERFACE
0x02,       // Subtype = Abstract Control Management (0x02)
0x02        // bmCapabilities = 0x02 → 支持 Set_Line_Coding 等请求
d) Union Functional Descriptor
c 复制代码
0x05,       // bLength = 5
0x24,       // CS_INTERFACE
0x06,       // Subtype = Union (0x06)
0x00,       // bMasterInterface = 0(控制接口)
0x01        // bSlaveInterface0 = 1(数据接口)

✅ 这些 CDC 功能描述符告诉主机:"这是一个 ACM CDC 设备,控制接口 0 管理数据接口 1"。


✅ 5. 端点:命令端点(Interrupt IN)

c 复制代码
0x07,                               // bLength = 7
USB_ENDPOINT_DESCRIPTOR_TYPE,       // bDescriptorType = 0x05
CDC_CMD_EP,                         // bEndpointAddress = 如 0x83(IN 端点 3)
0x03,                               // bmAttributes = Interrupt(0x03)
LOBYTE(CDC_CMD_PACKET_SIZE),        // wMaxPacketSize(低字节)
HIBYTE(CDC_CMD_PACKET_SIZE),        // wMaxPacketSize(高字节,通常为 0)
0xFF                                // bInterval = 255 ms(中断端点轮询间隔)

⚠️ 注意:CDC 命令端点通常是 Interrupt IN,用于通知主机状态变化(如 DSR 变化),但在简单实现中可能不用。


✅ 6. 接口 1:数据类接口(Data Interface)

c 复制代码
0x09,                               // bLength = 9
USB_INTERFACE_DESCRIPTOR_TYPE,      // 接口描述符
0x01,                               // bInterfaceNumber = 1
0x00,                               // bAlternateSetting = 0
0x02,                               // bNumEndpoints = 2(IN + OUT)
0x0A,                               // bInterfaceClass = CDC Data (0x0A)
0x00,                               // bInterfaceSubClass = 0
0x00,                               // bInterfaceProtocol = 0
0x00                                // iInterface = 0

💡 数据接口类为 0x0A(CDC Data),不是 0x02


✅ 7. 端点:数据 OUT(主机 → 设备)

c 复制代码
0x07,                               // bLength = 7
USB_ENDPOINT_DESCRIPTOR_TYPE,       // 端点描述符
CDC_OUT_EP,                         // 如 0x02(OUT 端点 2)
0x02,                               // bmAttributes = Bulk(0x02)
LOBYTE(MAX_CDC_PACKET_SIZE),        // wMaxPacketSize(如 64)
HIBYTE(MAX_CDC_PACKET_SIZE),        // 高字节(通常 0)
0x00                                // bInterval = 0(Bulk 端点忽略此字段)

✅ 8. 端点:数据 IN(设备 → 主机)

c 复制代码
0x07,                               // bLength = 7
USB_ENDPOINT_DESCRIPTOR_TYPE,
CDC_IN_EP,                          // 如 0x82(IN 端点 2)
0x02,                               // Bulk
LOBYTE(MAX_CDC_PACKET_SIZE),
HIBYTE(MAX_CDC_PACKET_SIZE),
0x00

🧾 总结:整体结构图

复制代码
[Configuration Descriptor]
 └── [IAD] ------ 关联接口 0 和 1
 └── [Interface 0: CDC Control]
      ├── Header FD
      ├── Call Mgmt FD
      ├── ACM FD
      ├── Union FD
      └── [Endpoint: Interrupt IN]  ← 命令/通知
 └── [Interface 1: CDC Data]
      ├── [Endpoint: Bulk OUT]      ← 主机发数据
      └── [Endpoint: Bulk IN]       ← 设备发数据

🔧 常见宏值参考(需在代码中定义)

c 复制代码
#define CDC_CMD_EP          0x83    // IN 端点 3
#define CDC_OUT_EP          0x02    // OUT 端点 2
#define CDC_IN_EP           0x82    // IN 端点 2
#define CDC_CMD_PACKET_SIZE 0x10    // 16 字节(命令端点)
#define MAX_CDC_PACKET_SIZE 0x40    // 64 字节(数据端点,全速 USB 最大)
#define USB_CDC_CONFIG_DESC_SIZ 0x67 // 总长度 = 103 字节

✅ 你可以用 sizeof(usb_dev_cdc_cfgdesc) 验证总长度是否匹配 USB_CDC_CONFIG_DESC_SIZ


💡 提示

  • Windows / Linux 会根据 IAD + CDC 描述符自动加载 cdc_acmusbser 驱动。
  • 如果没有 IAD,某些旧系统可能无法正确识别双接口 CDC 设备。
  • 确保 wTotalLength 正确,否则枚举会失败!
相关推荐
Championship.23.245 天前
Linux 3.0 USB机制深度解析:USB 3.0支持与传统外设驱动架构
linux·运维·架构·usb
ZenasLDR11 天前
Type-C接口iPad键盘皮套
接口·芯片·usb
smallerxuan11 天前
九、CherryUSB 设计架构与工作逻辑分析
usb·cherryusb·cherryusb分析
smallerxuan12 天前
二、USB协议中的设备类
usb·usb协议·usb设备类
smallerxuan14 天前
三、USB协议通信过程
usb·usb协议·usb通信过程
smallerxuan14 天前
七、USB协议中的事务
usb·usb协议·usb事务
smallerxuan14 天前
五、USB协议中的请求
usb·usb协议·usb请求
smallerxuan14 天前
八、USB协议分析与调试实战
usb·usb协议分析·usb协议·usb协议调测
smallerxuan14 天前
四、USB协议中的描述符
usb·usb协议·usb描述符
ZenasLDR17 天前
Type-C接口水冷散热器
接口·芯片·usb