目录
描述符
在每一个USB设备内部,包含了固定格式的数据,通过这些数据,USB主机就可以获取USB设备的类型、生产厂商等信息。这些固定格式的数据,我们就称之为USB描述符。标准的USB设备有5种USB描述符:设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符。
1 设备描述符
bLength : 描述符长度,固定为0x12。
bDescriptorType : 设备描述符类型,固定为0x01。
bcdUSB : USB 规范发布号。表示了本设备能适用于那种协议,如2.0=0200
bDeviceClass : 类型代码。
bDeviceSubClass : 子类型代码。
bDeviceProtocol : 协议代码。
bMaxPacketSize0 : 端点0最大分组大小。
idVendor : 供应商ID。
idProduct : 产品ID(由厂商分配)。
bcdDevice : 设备出产编码,由厂家自行设置。
iManufacturer : 厂商描述符字符串索引.索引到对应的字符串描述符。
iProduct : :产品描述符字符串索引。
iSerialNumber : 设备序列号字符串索引。
bNumConfigurations : 可能的配置数。
2 配置描述符
bLength : 描述符长度,固定为0x09。
bDescriptorType : 配置描述符类型,固定为0x02。
wTotalLength : 返回整个数据的长度,指此配置返回的配置描述符,接口描述符以及端点描述符的全部大小。
bNumInterfaces : 配置所支持的接口数,指该配置配备的接口数量,也表示该配置下接口描述符数量。
bConfigurationValue : 作为Set Configuration的一个参数选择配置值。
iConfiguration : 用于描述该配置字符串描述符的索引。
bmAttributes : 供电模式选择。Bit4-0保留,D7:总线供电,D6:自供电,D5:远程唤醒.
MaxPower : 总线供电的USB设备的最大消耗电流,以2mA为单位。
3 接口描述符
bLength : 描述符长度,固定为0x09。
bDescriptorType : 接口描述符类型,固定为0x04。
bInterfaceNumber: 该接口的编号。
bAlternateSetting : 用于为上一个字段选择可供替换的设置。
bNumEndpoint : 使用的端点数目,端点0除外。
bInterfaceClass : 类型代码(由USB组织分配)。
bInterfaceSunClass : 子类型代码(由USB组织分配)。
bInterfaceProtocol : 协议代码(由USB组织分配)。
iInterface : 字符串描述符的索引。
4 端点描述符
bLength : 描述符大小,固定为0x07。
bDescriptorType : 接口描述符类型,固定为0x05。
bEndpointType : USB设备的端点地址。Bit7,方向,对于控制端点可以忽略,1/0:IN/OUT。Bit6-4,保留。BIt3-0:端点号.
bmAttributes : 端点属性,Bit7-2,保留。BIt1-0:00控制,01同步,02批量,03中断。
wMaxPacketSize : 本端点接收或发送的最大信息包大小。
bInterval : 轮训数据传送端点的时间间隔.对于批量传送和控制传送的端点忽略.对于同步传送的端点,必须为1,对于中断传送的端点,范围为1-255。
5 部分实例(基于CH32V203)
/*
* 所有描述符的第一个字段都是长度bLength,第二个字段都是描述符类型bDescriptorType
*
*
* 描述符类型bDescriptorType值对应如下:
* 0x01 设备描述符
* 0x02 配置描述符
* 0x03 字符串描述符
* 0x04 接口描述符
* 0x05 端点描述符
* 0x06 设备限定描述符
* 0x07 其他速率配置描述符 *
* 0x08 接口电源描述符
* 0x0B 接口关联描述符
* 0x21 HID描述符
* 0x22 报告描述符
* 0x23 物理描述符
* 0x24 功能描述符
* 0x29 Hub描述符
*
* 类/协议选择 参考:https://www.usb.org/defined-class-codes
*
*
* 前缀含义:
* b 表一个字节,=8bits;
* w 表一个字,=16bits;
* bm 表按位寻址;
* bcd 用BCD码表示;
* i 表索引值
* id 表标识码
*
*/
/* 设备描述符 Device Descriptor */
const uint8_t MyDevDescr[ ] =
{
0x12, // bLength 设备描述符 固定长度 0x12
0x01, // bDescriptorType (Device) 描述符类型 0x01
0x10, 0x01, // bcdUSB 1.10 USB版本
//设备类 HID设备类为0x03 这里我们要用复合设备
0xEF, // bDeviceClass
0x02, // bDeviceSubClass
0x01, // bDeviceProtocol
//端点0所支持的最大数据包大小
DEF_USBD_UEP0_SIZE, // bMaxPacketSize0 64
//厂家-产品-设备ID
(uint8_t)DEF_USB_VID, (uint8_t)(DEF_USB_VID >> 8), // idVendor 0x1A86
(uint8_t)DEF_USB_PID, (uint8_t)(DEF_USB_PID >> 8), // idProduct 0x5537
DEF_IC_PRG_VER, 0x00, // bcdDevice 0.01
0x01, // iManufacturer (String Index) 厂商字符串索引值
0x02, // iProduct (String Index) 产品字符串索引值
0x03, // iSerialNumber (String Index) 设备序列号字符串索引值
0x01, // bNumConfigurations 1 该设备所具有的配置数
};
/* 配置描述符(全速) Configuration Descriptor (FS) */
const uint8_t MyCfgDescr[ ] =
{
/******************************** 配置描述符 ************************************/
/* 标准配置描述符 Configure descriptor */
0x09, // bLength 固定长度 0x09字节
0x02, // bDescriptorType 描述符类型 0x02 配置描述符
0x6B,0x00, // wTotalLength 返回整个数据的长度.指此配置返回的配置描述符,接口描述符以及端点描述符的全部大小
0x03, // bNumInterfaces 接口数,配置所支持的接口数.指该配置配备的接口数量,也表示该配置下接口描述符数量
0x01, // bConfigurationValue 配置数,每个配置都有一个标识值,作为Set Configuration的一个参数选择配置值
0x00, // iConfiguration 用于描述该配置字符串描述符的索引
0x80, // bmAttributes 总线供电 供电模式选择.D7:总线供电,D6:自供电,D5:远程唤醒,Bit4-0保留
0x32, // bMaxPower 总线供电的USB设备的最大消耗电流.以2mA为单位
/* 接口关联 描述符 IAD(Interface Association Descriptor) Descriptor(interface 0/1)*/
// 用于多接口 复用设备
0x08, // 长度
0x0B, // 接口关联描述符类型
0x00, // 与该功能关联的第一个接口的接口号
0x02, // 与该功能关联的连续接口的数量
0x02, // 类码
0x02, // 子类码
0x01, // 协议码
0x00, // 字符串描述符索引
/******************************** CDC ************************************/
// CDC需要定义功能描述符和类特殊接口描述符
/* CDC接口描述符 Interface 0 (CDC) descriptor */
0x09, // bLength 长度
0x04, // bDescriptorType 描述符类型 0x04 接口描述符
0x00, // bInterfaceNumber 接口ID 这个是第一个接口,所以是0
0x00, // bAlternateSetting 转换设置
0x01, // bNumEndpoints 使用的端点数
//类型/协议选择参考:https://www.usb.org/defined-class-codes
0x02, // 类码 0x02表示CDC
0x02, // 子类码
0x01, // 协议码
0x00, // 字符串描述符索引
/* 功能描述符 Functional Descriptors */
0x05, // 长度
0x24, // bDescriptorType 描述符类型 0x04 接口描述符
0x00, // bDescriptorSubtype 子类型
0x10,0x01, // bcdCDC CDC版本号
/* 管理描述符 Length/management descriptor (data class interface 1) */
/*Call Management Functional Descriptor*/
0x05, // 长度
0x24, // bDescriptorType 描述符类型 0x04 接口描述符
0x01, // bDescriptorSubtype 子类型
0x00, // bmCapabilities D0+D1:设备自己不处理调用管理
0x01, // bDataInterface 用来做调用管理的数据类接口编号
0x04, // 长度
0x24, // 描述符类型
0x02, // 类型
0x02, // bmCapabilities
0x05, // 长度
0x24, // 描述符类型
0x06, // 类型
0x00, // bmCapabilities
0x01, // bSlaveInterface0
/* CDC端点描述符 Interrupt upload endpoint descriptor */
0x07, // 长度
0x05, // 描述符类型 0x05 端点描述符
0x81, // 端点地址 b7--0(out),1(in) b6:b4--保留 b3:b0--端点数量
0x03, // 传输类型:0-控制传输,1-同步传输,2-批量传输,3-中断传输
(uint8_t)DEF_USBD_ENDP1_SIZE,(uint8_t)( DEF_USBD_ENDP1_SIZE >> 8 ), //表示当前配置下此端点能够接收或发送的最大数据包的大小
0x01, // 轮询间隔(ms)
/******************************** CDC_Data ************************************/
/* 数据接口描述符 Interface 1 (data interface) descriptor */
0x09, // bLength
0x04, // bDescriptorType 描述符类型
0x01, // bInterfaceNumber 接口ID 这个是第2个接口,所以是1
0x00, // bAlternateSetting 转换设置
0x02, // bNumEndpoints 使用的端点数
//类型/协议选择参考:https://www.usb.org/defined-class-codes
0x0a, // 类码 0x0A表示CDC_DATA
0x00, // 子类码
0x00, // 协议码
0x00, // 字符串描述符索引
/* 端点1描述符 Endpoint descriptor */
0x07, // 长度
0x05, // 描述符类型 0x05 端点描述符
0x02, // 端点地址 b7--0(out),1(in) b6:b4--保留 b3:b0--端点口
0x02, // 传输类型:0-控制传输,1-同步传输,2-批量传输,3-中断传输
(uint8_t)DEF_USBD_ENDP2_SIZE,(uint8_t)( DEF_USBD_ENDP2_SIZE >> 8 ), // 表示当前配置下此端点能够接收或发送的最大数据包的大小
0x00, // 轮询间隔(ms)
/* 端点2描述符 Endpoint descriptor */
0x07, // 长度
0x05, // 描述符类型 0x05 端点描述符
0x83, // 端点地址 b7:0(out),1(in) b6-b4:保留 b3-b0:端点口
0x02, // 传输类型:0-控制传输,1-同步传输,2-批量传输,3-中断传输
(uint8_t)DEF_USBD_ENDP3_SIZE,(uint8_t)( DEF_USBD_ENDP3_SIZE >> 8 ), // 表示当前配置下此端点能够接收或发送的最大数据包的大小
0x00, // 轮询间隔(ms)
/******************************** HID ************************************/
/* HID接口描述符 interface 2 (HID interface) descriptor */
0x09, // bLength
0x04, // bDescriptorType 描述符类型
0x02, // bInterfaceNumber 接口ID 这个是第3个接口,所以是2
0x00, // bAlternateSetting: Alternate setting
0x02, // bNumEndpoints HID接口有两个端点
//类型/协议选择参考:https://www.usb.org/defined-class-codes
0x03, // 类码 0x03表示HID
0x00, // 子类码 1=BOOT, 0=no boot
0x00, // 协议码 0=none, 1=keyboard, 2=mouse
0x00, // 字符串描述符索引
/* HID描述符 interface 2 HID descriptor */
0x09, //bLength
0x21, //bDescriptorType: 描述符类型 0x21:HID
0x00, //bcdHID: HID设备所遵循的HID版本号,为4位16进制的BCD码。1.0即0x0100,1.1即0x0101,2.0即0x0200
0x01, 0x00, //bCountryCode: 国家/地区代码
0x01, //bNumDescriptors: HID设备支持的下级描述符的数量(至少有一个报告描述符)
0x22, //bDescriptorType:下级描述符的类型,0x22:报告描述符
DEF_USBD_REPORT_DESC_LEN, // wItemLength:报告描述符大小
0x00, // 标志类别描述符说明结束
/* 端点1描述符 interface 2 endpoint descriptor*/
0x07, // 长度
0x05, // 描述符类型 0x05 端点描述符
0x84, // 端点地址 b7--0(out),1(in) b6:b4--保留 b3:b0--端点口
0x03, // 传输类型:0-控制传输,1-同步传输,2-批量传输,3-中断传输
(uint8_t)DEF_USBD_ENDP4_SIZE,(uint8_t)( DEF_USBD_ENDP4_SIZE >> 8 ), // 表示当前配置下此端点能够接收或发送的最大数据包的大小
0x01, // 轮询间隔(ms)
/* 端点2描述符 interface 2 endpoint descriptor */
0x07, // 长度
0x05, // 描述符类型 0x05 端点描述符
0x04, // 端点地址 b7--0(out),1(in) b6:b4--保留 b3:b0--端点口
0x03, // 传输类型:0-控制传输,1-同步传输,2-批量传输,3-中断传输
(uint8_t)DEF_USBD_ENDP4_SIZE,(uint8_t)( DEF_USBD_ENDP4_SIZE >> 8 ), // 表示当前配置下此端点能够接收或发送的最大数据包的大小
0x01, // 轮询间隔(ms)
};
//HID报告描述符
const uint8_t MyHIDReportDesc[ ] =
{
0x06,0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
0x09, 0x01, // Usage (0x01)
0xA1, 0x01, // Collection (Application)
0x09, 0x02, // Usage (0x02)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x95, 0x40, // Report Count (64)
0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x02, // Usage (0x02)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (8)
0x95, 0x40, // Report Count (64)
0x91, 0x06, // Output (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
};
/* 语言ID 字符串描述符 Language Descriptor */
const uint8_t MyLangDescr[] =
{
//0x1404- Cn 0x0409- En
0x04, 0x03, 0x09, 0x04
};
/* 字符串描述符 Manufacturer Descriptor */
const uint8_t MyManuInfo[] =
{
0x0E, 0x03, 'w', 0, 'c', 0, 'h', 0, '.', 0, 'c', 0, 'n', 0
};
/* 字符串描述符 Product Information */
const uint8_t MyProdInfo[] =
{
0x12, 0x03, 'C', 0, 'H', 0, '3', 0, '2', 0, 'V', 0, '1', 0
, '0', 0, 'x', 0
};
/* 字符串描述符 Serial Number Information */
const uint8_t MySerNumInfo[] =
{
0x16, 0x03, '0', 0, '1', 0, '2', 0, '3', 0, '4', 0, '5', 0
, '6', 0, '7', 0, '8', 0, '9', 0
};