CDC1
cpp
/*---------------------------------------------------------------------------*/
// IAD Interface Association Descriptor
0x08, // bLength: Interface Descriptor size
0x0B, // bDescriptorType: IAD
0x00, // bFirstInterface
0x02, // bInterfaceCount
0x02, // bFunctionClass: CDC
0x02, // bFunctionSubClass
0x01, // bFunctionProtocol
0x02, // iFunction
/*Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
/* Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoints used */
0x02, /* bInterfaceClass: Communication Interface Class */
0x02, /* bInterfaceSubClass: Abstract Control Model */
0x01, /* bInterfaceProtocol: Common AT commands */
0x00, /* iInterface: */
/*Header Functional Descriptor*/
0x05, /* bLength: Endpoint Descriptor size */
0x24, /* bDescriptorType: CS_INTERFACE */
0x00, /* bDescriptorSubtype: Header Func Desc */
0x10, /* bcdCDC: spec release number */
0x01,
/*Call Management Functional Descriptor*/
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: Call Management Func Desc */
0x00, /* bmCapabilities: D0+D1 */
0x01, /* bDataInterface: 1 */
/*ACM Functional Descriptor*/
0x04, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
0x02, /* bmCapabilities */
/*Union Functional Descriptor*/
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: Union func desc */
0x00, /* bMasterInterface: Communication class interface */
0x01, /* bSlaveInterface0: Data Class Interface */
/*Endpoint 2 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_CMD_EP2, /* bEndpointAddress */
0x03, /* bmAttributes: Interrupt */
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
HIBYTE(CDC_CMD_PACKET_SIZE),
0x10, /* bInterval: */
/*---------------------------------------------------------------------------*/
/*Data class interface descriptor*/
0x09, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
0x01, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints: Two endpoints used */
0x0A, /* bInterfaceClass: CDC */
0x00, /* bInterfaceSubClass: */
0x00, /* bInterfaceProtocol: */
0x00, /* iInterface: */
/*Endpoint OUT Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_OUT_EP1, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
0x00, /* bInterval: ignore for Bulk transfer */
/*Endpoint IN Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_IN_EP1, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
0x00, /* bInterval: ignore for Bulk transfer */
CDC2
cpp
/*---------------------------------------------------------------------------*/
// IAD Interface Association Descriptor
0x08, // bLength: Interface Descriptor size
0x0B, // bDescriptorType: IAD
0x02, // bFirstInterface
0x02, // bInterfaceCount
0x02, // bFunctionClass: CDC
0x02, // bFunctionSubClass
0x01, // bFunctionProtocol
0x02, // iFunction
/*Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
/* Interface descriptor type */
0x02, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoints used */
0x02, /* bInterfaceClass: Communication Interface Class */
0x02, /* bInterfaceSubClass: Abstract Control Model */
0x01, /* bInterfaceProtocol: Common AT commands */
0x00, /* iInterface: */
/*Header Functional Descriptor*/
0x05, /* bLength: Endpoint Descriptor size */
0x24, /* bDescriptorType: CS_INTERFACE */
0x00, /* bDescriptorSubtype: Header Func Desc */
0x10, /* bcdCDC: spec release number */
0x01,
/*Call Management Functional Descriptor*/
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: Call Management Func Desc */
0x00, /* bmCapabilities: D0+D1 */
0x01, /* bDataInterface: 1 */
/*ACM Functional Descriptor*/
0x04, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
0x02, /* bmCapabilities */
/*Union Functional Descriptor*/
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: Union func desc */
0x00, /* bMasterInterface: Communication class interface */
0x01, /* bSlaveInterface0: Data Class Interface */
/*Endpoint 2 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_CMD_EP4, /* bEndpointAddress */
0x03, /* bmAttributes: Interrupt */
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
HIBYTE(CDC_CMD_PACKET_SIZE),
0x10, /* bInterval: */
/*---------------------------------------------------------------------------*/
/*Data class interface descriptor*/
0x09, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
0x03, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints: Two endpoints used */
0x0A, /* bInterfaceClass: CDC */
0x00, /* bInterfaceSubClass: */
0x00, /* bInterfaceProtocol: */
0x00, /* iInterface: */
/*Endpoint OUT Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_OUT_EP3, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
0x00, /* bInterval: ignore for Bulk transfer */
/*Endpoint IN Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_IN_EP3, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
下面这段描述符就是 USB-IF 定义的 "CDC-ACM 虚拟串口" 完整模板。
把它按层次竖着看,就是主机枚举时一次性读到的 "表结构"------先告诉你"这是一个复合设备",再告诉你"里面有两张接口(0 号控制口 + 1 号数据口)",最后把 3 根真正传数据的"线(端点)"参数一口气交代清楚。
- IAD(Interface Association Descriptor)------"打包票"
偏移 值 含义
08 08 本描述符长度
0B 0B 0x0B = IAD 类型
00 00 第一张接口编号 = 0
02 02 这个"功能"共占用 2 张接口(0 和 1)
02 02 bFunctionClass = CDC 类
02 02 bFunctionSubClass = ACM 子类
01 01 bFunctionProtocol = AT 命令 v1
02 02 iFunction = 字符串索引 2(可选名字)
→ 告诉系统:别把接口 0 和 1 拆成两个独立设备,它们合起来只是一个"CDC-ACM 串口"。
- Interface 0 ------ "控制口"(Communication Class Interface)
09 04 00 00 01 02 02 01 00
-
只有 1 个中断 IN 端点,专门发"串口状态/通知"
-
后面跟 5 个"功能描述符"补充说明:
① Header Func Desc
05 24 00 10 01 → CDC 版本 1.10
② Call Management
05 24 01 00 01 → 设备不自己接电话,数据口在接口 1
③ ACM Func Desc
04 24 02 02 → 支持 SetLineCoding / SetControlLineState
④ Union Func Desc
05 24 06 00 01 → 主接口 0 控制从接口 1
⑤ Endpoint 2 IN (Interrupt)
07 05 CDC_CMD_EP2 03 08/16 10
端点号 2,IN,中断,16 ms 轮询一次,最大 8/16 字节
- Interface 1 ------ "数据口"(Data Class Interface)
09 04 01 00 02 0A 00 00 00
-
占用 2 个批量端点,一出一进,真正的用户数据就走路径
-
后面两根"线":
⑥ Endpoint OUT (Bulk)
07 05 CDC_OUT_EP1 02 512/64 00
端点号 1 OUT,批量,高速时 512 字节,全速 64 字节
⑦ Endpoint IN (Bulk)
07 05 CDC_IN_EP1 02 512/64 00
端点号 1 IN, 批量,高速时 512 字节,全速 64 字节
- 整体拓扑("接线图")
主机视角看到的 3 根"线":
端点 2 IN (中断) ──→ 每 16 ms 最多 8/16 字节,通知串口状态
端点 1 OUT (批量) ←── 用户串口下发数据
端点 1 IN (批量) ──→ 用户串口上传数据
接口 0 不负责传业务数据,只当"管家";
接口 1 才是"搬运工",双向批量管道。
- 枚举流程一句话
"主机先读到 IAD,知道 0+1 是一对 CDC-ACM;
接着按接口 0 的 Union 描述符把两张接口绑在一起;
最后给 3 个端点分配带宽,虚拟串口就 Ready 了。"