USB 配置描述符定义了设备的完整配置,包括接口、端点和设备功能。主机通过获取配置描述符来了解设备的能力。
设备描述符 (Device Descriptor)
└── 配置描述符 1 (Configuration Descriptor)
├── 接口描述符 1-0 (Interface Descriptor - Setting 0)
│ ├── 端点描述符 1 (Endpoint Descriptor)
│ └── 端点描述符 2 (Endpoint Descriptor)
│
├── 接口描述符 1-1 (Interface Descriptor - Setting 1)
│ └── ...
│
└── 接口描述符 2 (Interface Descriptor)
└── ...
└── 配置描述符 2 (可选)
└── ...
struct usb_device_descriptor {
uint8_t bLength; /* 18 */
uint8_t bDescriptorType; /* 0x01 (DEVICE) */
uint16_t bcdUSB; /* USB 版本: 2.0 = 0x0200 */
uint8_t bDeviceClass; /* 设备类 */
uint8_t bDeviceSubClass; /* 设备子类 */
uint8_t bDeviceProtocol; /* 设备协议 */
uint8_t bMaxPacketSize0; /* EP0 最大包大小: 8/16/32/64 */
uint16_t idVendor; /* 厂商 ID */
uint16_t idProduct; /* 产品 ID */
uint16_t bcdDevice; /* 设备版本 */
uint8_t iManufacturer; /* 厂商字符串索引 */
uint8_t iProduct; /* 产品字符串索引 */
uint8_t iSerialNumber; /* 序列号字符串索引 */
uint8_t bNumConfigurations; /* 配置数量 */
} __packed;
const struct usb_device_descriptor device_desc = {
.bLength = sizeof(struct usb_device_descriptor),
.bDescriptorType = USB_DESC_DEVICE,
.bcdUSB = sys_cpu_to_le16(0x0200), /* USB 2.0 */
.bDeviceClass = USB_BCC_MISCELLANEOUS, /* 使用接口类 */
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
.bMaxPacketSize0 = 64,
.idVendor = sys_cpu_to_le16(0x2FE3), /* Nordic */
.idProduct = sys_cpu_to_le16(0x0100),
.bcdDevice = sys_cpu_to_le16(0x0100), /* Version 1.0 */
.iManufacturer = 1, /* String index 1 */
.iProduct = 2, /* String index 2 */
.iSerialNumber = 3, /* String index 3 */
.bNumConfigurations = 1,
};
struct usb_config_descriptor {
uint8_t bLength; /* 9 */
uint8_t bDescriptorType; /* 0x02 (CONFIGURATION) */
uint16_t wTotalLength; /* 总长度(包括接口和端点描述符) */
uint8_t bNumInterfaces; /* 接口数量 */
uint8_t bConfigurationValue; /* 配置值 */
uint8_t iConfiguration; /* 配置字符串索引 */
uint8_t bmAttributes; /* 属性 */
uint8_t bMaxPower; /* 最大功耗 (2mA 单位) */
} __packed;
#define USB_CONFIGURATION_ATTRIBUTES BIT(7) /* 必须为 1 */
#define USB_CONFIGURATION_SELF_POWERED BIT(6) /* 自供电 */
#define USB_CONFIGURATION_REMOTE_WAKEUP BIT(5) /* 远程唤醒 */
const struct usb_config_descriptor config_desc = {
.bLength = sizeof(struct usb_config_descriptor),
.bDescriptorType = USB_DESC_CONFIGURATION,
.wTotalLength = sizeof(struct usb_config_descriptor) +
sizeof(struct usb_if_descriptor) +
sizeof(struct usb_ep_descriptor) * 2,
.bNumInterfaces = 1,
.bConfigurationValue = 1,
.iConfiguration = 0, /* 无配置字符串 */
.bmAttributes = USB_CONFIGURATION_ATTRIBUTES, /* 总线供电 */
.bMaxPower = 50, /* 100mA (50 * 2mA) */
};
struct usb_if_descriptor {
uint8_t bLength; /* 9 */
uint8_t bDescriptorType; /* 0x04 (INTERFACE) */
uint8_t bInterfaceNumber; /* 接口编号 */
uint8_t bAlternateSetting; /* 备用设置 */
uint8_t bNumEndpoints; /* 端点数量(不包括 EP0) */
uint8_t bInterfaceClass; /* 接口类 */
uint8_t bInterfaceSubClass; /* 接口子类 */
uint8_t bInterfaceProtocol; /* 接口协议 */
uint8_t iInterface; /* 接口字符串索引 */
} __packed;
#define USB_IFACE_CLASS_AUDIO 0x01
#define USB_IFACE_CLASS_CDC 0x02
#define USB_IFACE_CLASS_HID 0x03
#define USB_IFACE_CLASS_PHYSICAL 0x05
#define USB_IFACE_CLASS_IMAGE 0x06
#define USB_IFACE_CLASS_PRINTER 0x07
#define USB_IFACE_CLASS_MASS_STORAGE 0x08
#define USB_IFACE_CLASS_HUB 0x09
#define USB_IFACE_CLASS_CDC_DATA 0x0A
#define USB_IFACE_CLASS_SMART_CARD 0x0B
#define USB_IFACE_CLASS_CONTENT_SECURITY 0x0D
#define USB_IFACE_CLASS_VIDEO 0x0E
#define USB_IFACE_CLASS_PERSONAL_HEALTHCARE 0x0F
#define USB_IFACE_CLASS_AUDIO_VIDEO 0x10
#define USB_IFACE_CLASS_DIAGNOSTIC_DEVICE 0xDC
#define USB_IFACE_CLASS_WIRELESS_CONTROLLER 0xE0
#define USB_IFACE_CLASS_MISCELLANEOUS 0xEF
#define USB_IFACE_CLASS_APPLICATION_SPECIFIC 0xFE
#define USB_IFACE_CLASS_VENDOR_SPECIFIC 0xFF
const struct usb_if_descriptor hid_iface = {
.bLength = sizeof(struct usb_if_descriptor),
.bDescriptorType = USB_DESC_INTERFACE,
.bInterfaceNumber = 0,
.bAlternateSetting = 0,
.bNumEndpoints = 1,
.bInterfaceClass = USB_IFACE_CLASS_HID,
.bInterfaceSubClass = 0, /* No subclass */
.bInterfaceProtocol = 0, /* No protocol */
.iInterface = 0,
};
struct usb_ep_descriptor {
uint8_t bLength; /* 7 */
uint8_t bDescriptorType; /* 0x05 (ENDPOINT) */
uint8_t bEndpointAddress; /* 端点地址 */
uint8_t bmAttributes; /* 端点属性 */
uint16_t wMaxPacketSize; /* 最大包大小 */
uint8_t bInterval; /* 轮询间隔(中断/等时端点) */
} __packed;
#define USB_EP_ADDR_MASK 0x0F
#define USB_EP_DIR_MASK 0x80
#define USB_EP_DIR_IN 0x80 /* 设备到主机 */
#define USB_EP_DIR_OUT 0x00 /* 主机到设备 */
/* 端点地址示例 */
#define EP0_IN_ADDR 0x80 /* 控制端点 IN */
#define EP0_OUT_ADDR 0x00 /* 控制端点 OUT */
#define EP1_IN_ADDR 0x81 /* 端点 1 IN */
#define EP1_OUT_ADDR 0x01 /* 端点 1 OUT */
#define USB_EP_TRANSFER_TYPE_MASK 0x03
#define USB_EP_TYPE_CONTROL 0x00
#define USB_EP_TYPE_ISOCHRONOUS 0x01
#define USB_EP_TYPE_BULK 0x02
#define USB_EP_TYPE_INTERRUPT 0x03
/* 同步类型(仅等时端点) */
#define USB_EP_SYNC_TYPE_MASK 0x0C
#define USB_EP_SYNC_NONE 0x00
#define USB_EP_SYNC_ASYNC 0x04
#define USB_EP_SYNC_ADAPTIVE 0x08
#define USB_EP_SYNC_SYNC 0x0C
/* 使用类型(仅等时端点) */
#define USB_EP_USAGE_TYPE_MASK 0x30
#define USB_EP_USAGE_DATA 0x00
#define USB_EP_USAGE_FEEDBACK 0x10
#define USB_EP_USAGE_EXPLICIT_FB 0x20
/* HID 中断输入端点 */
const struct usb_ep_descriptor hid_ep_in = {
.bLength = sizeof(struct usb_ep_descriptor),
.bDescriptorType = USB_DESC_ENDPOINT,
.bEndpointAddress = 0x81, /* EP 1 IN */
.bmAttributes = USB_EP_TYPE_INTERRUPT,
.wMaxPacketSize = sys_cpu_to_le16(8), /* 8 bytes */
.bInterval = 10, /* 10ms polling */
};
/* CDC 批量端点 */
const struct usb_ep_descriptor cdc_ep_in = {
.bLength = sizeof(struct usb_ep_descriptor),
.bDescriptorType = USB_DESC_ENDPOINT,
.bEndpointAddress = 0x82,
.bmAttributes = USB_EP_TYPE_BULK,
.wMaxPacketSize = sys_cpu_to_le16(64),
.bInterval = 0, /* N/A for bulk */
};
/* 复合描述符 */
const uint8_t hid_config_desc[] = {
/* Configuration Descriptor */
0x09, /* bLength */
USB_DESC_CONFIGURATION, /* bDescriptorType */
0x22, 0x00, /* wTotalLength (34 bytes) */
0x01, /* bNumInterfaces */
0x01, /* bConfigurationValue */
0x00, /* iConfiguration */
0x80, /* bmAttributes (Bus Powered) */
0x32, /* bMaxPower (100mA) */
/* Interface Descriptor */
0x09, /* bLength */
USB_DESC_INTERFACE, /* bDescriptorType */
0x00, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x01, /* bNumEndpoints */
USB_IFACE_CLASS_HID, /* bInterfaceClass */
0x00, /* bInterfaceSubClass */
0x00, /* bInterfaceProtocol */
0x00, /* iInterface */
/* HID Descriptor */
0x09, /* bLength */
0x21, /* bDescriptorType (HID) */
0x11, 0x01, /* bcdHID (1.11) */
0x00, /* bCountryCode */
0x01, /* bNumDescriptors */
0x22, /* bDescriptorType (Report) */
sizeof(hid_report_desc), 0x00, /* wDescriptorLength */
/* Endpoint Descriptor */
0x07, /* bLength */
USB_DESC_ENDPOINT, /* bDescriptorType */
0x81, /* bEndpointAddress (EP1 IN) */
USB_EP_TYPE_INTERRUPT, /* bmAttributes */
0x08, 0x00, /* wMaxPacketSize (8 bytes) */
0x0A, /* bInterval (10ms) */
};
/* CDC ACM 复合描述符 */
const uint8_t cdc_acm_config_desc[] = {
/* Configuration Descriptor */
0x09,
USB_DESC_CONFIGURATION,
0x43, 0x00, /* Total length: 67 bytes */
0x02, /* 2 interfaces */
0x01,
0x00,
0x80,
0x32,
/* Interface 0: CDC Control */
0x09,
USB_DESC_INTERFACE,
0x00, /* Interface 0 */
0x00,
0x01, /* 1 endpoint */
USB_IFACE_CLASS_CDC, /* CDC Class */
USB_CDC_SUBCLASS_ACM, /* Abstract Control Model */
USB_CDC_PROTOCOL_NONE,
0x00,
/* CDC Header Functional Descriptor */
0x05,
USB_DESC_CS_INTERFACE,
USB_CDC_HEADER_FUNC_DESC,
0x10, 0x01, /* CDC Version 1.10 */
/* CDC ACM Functional Descriptor */
0x04,
USB_DESC_CS_INTERFACE,
USB_CDC_ACM_FUNC_DESC,
0x02, /* Set_Line_Coding, Set_Control_Line_State */
/* CDC Union Functional Descriptor */
0x05,
USB_DESC_CS_INTERFACE,
USB_CDC_UNION_FUNC_DESC,
0x00, /* Master interface */
0x01, /* Slave interface */
/* CDC Call Management Functional Descriptor */
0x05,
USB_DESC_CS_INTERFACE,
USB_CDC_CALL_MGMT_FUNC_DESC,
0x00,
0x01, /* Data interface */
/* Endpoint: Interrupt IN */
0x07,
USB_DESC_ENDPOINT,
0x82, /* EP 2 IN */
USB_EP_TYPE_INTERRUPT,
0x08, 0x00,
0x10, /* 16ms interval */
/* Interface 1: CDC Data */
0x09,
USB_DESC_INTERFACE,
0x01, /* Interface 1 */
0x00,
0x02, /* 2 endpoints */
USB_IFACE_CLASS_CDC_DATA,
0x00,
0x00,
0x00,
/* Endpoint: Bulk OUT */
0x07,
USB_DESC_ENDPOINT,
0x01, /* EP 1 OUT */
USB_EP_TYPE_BULK,
0x40, 0x00, /* 64 bytes */
0x00,
/* Endpoint: Bulk IN */
0x07,
USB_DESC_ENDPOINT,
0x81, /* EP 1 IN */
USB_EP_TYPE_BULK,
0x40, 0x00,
0x00,
};
/* 支持的语言 */
const uint8_t lang_desc[] = {
0x04, /* bLength */
USB_DESC_STRING, /* bDescriptorType */
0x09, 0x04, /* English (US) */
};
/* USB 字符串使用 UTF-16LE 编码 */
/* "MyCompany" */
const uint8_t manufacturer_str[] = {
0x14, /* bLength (20 bytes) */
USB_DESC_STRING,
'M', 0, 'y', 0, 'C', 0, 'o', 0,
'm', 0, 'p', 0, 'a', 0, 'n', 0,
'y', 0,
};
/* "USB Device" */
const uint8_t product_str[] = {
0x16,
USB_DESC_STRING,
'U', 0, 'S', 0, 'B', 0, ' ', 0,
'D', 0, 'e', 0, 'v', 0, 'i', 0,
'c', 0, 'e', 0,
};
/* "123456" */
const uint8_t serial_str[] = {
0x0E,
USB_DESC_STRING,
'1', 0, '2', 0, '3', 0, '4', 0,
'5', 0, '6', 0,
};
/* 计算配置描述符总长度 */
#define CONFIG_DESC_SIZE \
(sizeof(struct usb_config_descriptor) + \
sizeof(struct usb_if_descriptor) + \
sizeof(struct usb_hid_descriptor) + \
sizeof(struct usb_ep_descriptor))
/* 验证 */
BUILD_ASSERT(CONFIG_DESC_SIZE == 34, "Config descriptor size mismatch");
*学习笔记创建时间: 2026-03-19*