USB CDC 配置描述符中对比两个CDC设备配置

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 根真正传数据的"线(端点)"参数一口气交代清楚。


  1. 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 串口"。


  1. 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 字节


  1. 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 字节


  1. 整体拓扑("接线图")

主机视角看到的 3 根"线":

端点 2 IN (中断) ──→ 每 16 ms 最多 8/16 字节,通知串口状态

端点 1 OUT (批量) ←── 用户串口下发数据

端点 1 IN (批量) ──→ 用户串口上传数据

接口 0 不负责传业务数据,只当"管家";

接口 1 才是"搬运工",双向批量管道。


  1. 枚举流程一句话

"主机先读到 IAD,知道 0+1 是一对 CDC-ACM;

接着按接口 0 的 Union 描述符把两张接口绑在一起;

最后给 3 个端点分配带宽,虚拟串口就 Ready 了。"

相关推荐
Java牛马5 分钟前
SpringBoot Starter 依赖相关总结
java·spring·springboot·starter·自动装配·依赖
吴声子夜歌18 分钟前
Java面试——Spring Cloud原理及应用(二)
java·spring cloud·面试
东小西1 小时前
【SAA实战】第 1 篇:ReactAgent 入门——先撸个"会调工具的助手"跑起来
java·人工智能·spring
我是乌鸦的空间2 小时前
什么是网络安全中的电子数据取证与响应?
网络·网络安全
跨境旺仔小拳头2 小时前
如何使用Crawl4AI进行网页爬虫?从0搭建教程与代理配置指南
网络·人工智能·爬虫·chatgpt·aigc
mqiqe2 小时前
AgentScope Java 2.0 协议集成全景解析:A2A、AG-UI、Agent Protocol 三大开放协议实战指南
java·开发语言·ui
沫儿笙2 小时前
焊接机器人氩弧焊省气装置
网络·机器人
脉动数据行情2 小时前
Java 实现台股 TWSE/TPEx 行情采集(个股 + K 线)
java·开发语言·twse·tpex·台股
80s7772 小时前
什么是动态IP?静态IP和动态IP有什么区别?
网络·网络协议·tcp/ip
那年窗外下的雪.3 小时前
AIDC 学习日志|第 15 天|EVPN 多归属故障收敛与撤销机制
网络·学习·php