☰
the USB CDC-ACM descriptor layout
2026/9/26 11:09:28 网站建设 项目流程

For aUSB CDC-ACM (Virtual COM Port)device, the descriptor hierarchy typically looks like this:

Device Descriptor │ └── Configuration Descriptor │ ├── Interface 0 (Communication Class Interface, CIC) │ ├── Header Functional Descriptor │ ├── Call Management Functional Descriptor │ ├── ACM Functional Descriptor │ ├── Union Functional Descriptor │ └── Endpoint Descriptor (Interrupt IN) │ └── Interface 1 (Data Class Interface, DIC) ├── Endpoint Descriptor (Bulk OUT) └── Endpoint Descriptor (Bulk IN)

Example CDC-ACM Descriptor Set

Communication Interface (Interface 0)

Interface Descriptor -------------------- bInterfaceClass = 0x02 (CDC) bInterfaceSubClass = 0x02 (ACM) bInterfaceProtocol = 0x01 (AT Commands) bNumEndpoints = 1

Header Functional Descriptor

bFunctionLength = 5 bDescriptorType = 0x24 (CS_INTERFACE) bDescriptorSubType = 0x00 (Header) bcdCDC = 0x0120

Call Management Descriptor

bFunctionLength = 5 bDescriptorType = 0x24 bDescriptorSubType = 0x01 bmCapabilities = 0x00 bDataInterface = 1

ACM Functional Descriptor

bFunctionLength = 4 bDescriptorType = 0x24 bDescriptorSubType = 0x02 bmCapabilities: bit0 = Supports Set_Line_Coding bit1 = Supports Set_Control_Line_State bit2 = Supports Send_Break

Common value:

bmCapabilities = 0x02 ``

Union Functional Descriptor

bFunctionLength = 5 bDescriptorType = 0x24 bDescriptorSubType = 0x06 bMasterInterface = 0 bSlaveInterface0 = 1

Notification Endpoint

Endpoint Descriptor ------------------- bEndpointAddress = 0x81 (Interrupt IN) bmAttributes = 0x03 wMaxPacketSize = 8 bInterval = 16

Data Interface (Interface 1)

Interface Descriptor -------------------- bInterfaceClass = 0x0A (CDC Data) bInterfaceSubClass = 0x00 bInterfaceProtocol = 0x00 bNumEndpoints = 2

Bulk OUT Endpoint

bEndpointAddress = 0x02 bmAttributes = 0x02 (Bulk) wMaxPacketSize = 64 (FS)

Bulk IN Endpoint

bEndpointAddress = 0x82 bmAttributes = 0x02 (Bulk) wMaxPacketSize = 64 (FS)

Descriptor Byte Layout

Many STM32/NXP/ESP32 examples use something close to:

/* Interface Association Descriptor (optional) */ 08 0B 00 02 02 02 01 00 /* Communication Interface */ 09 04 00 00 01 02 02 01 00 ** Header Functional */ 05 *4 00 20 01 /* Call Management */ 05 *4 01 00 01 /* ACM */ 04 24 02 02 /* Union */ 05 24 06 00 01 /* Interrupt IN EP */ 07 05*81 03 08 00 10* /* Data Interface */ 09 04 01 00 02 0A 00 00 00 /* Bulk OUT */ 07 05 02 02 40 00 00 /* Bulk IN */ 07 05 82 02 40 00 00

Enumeration Result in Windows/Linux

After enumeration, the host issues CDC class requests such as:

SET_LINE_CODING GET_LINE_CODING SET_CONTROL_LINE_STATE SEND_BREAK

SET_LINE_CODINGcarries UART settings:

dwDTERate = 115200 bCharFormat = 0 *(1 stop bit) bParityType = 0 (none) bDataBits = 8 ``

This is why CDC-ACM appears as aCOM portin Windows and as/dev/ttyACM0in Linux. The actual UART settings are often ignored by MCU firmware unless bridged to a real UART. The CDC ACM subclass is defined within the USB Communications Device Class specification. [usb.org], [cscott.net]

Common Endpoint Map

EP0 Control EP1*IN Interrupt (Notifications) EP2*OUT Bulk (Host -> Device data) EP2*IN Bulk (Device -> Host data)

This is the descriptor structure you'll see in STM32Cube USB CDC, TinyUSB CDC-ACM, Zephyr USB CDC, Linux gadget CDC-ACM, and most MCU virtual COM port implementations.

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询