下面作为一个例子,介绍一个USB接口的101键盘的全部描述符。该键盘固件部分由一个微处理器实现全部控制功能,下面列出的代码为微处理器汇编实现描述符定义。
3.1 设备的描述符
设备描述符的代码如下:
- ;=========================================
- ; Device descriptor 设备描述符
- ;=========================================
- DEVICE_DESC_DATA:
- DB 0x12 ; bLength = 18,该描述符长度为18字节
- DB 0x01 ; bDescriptorType = 01,表明是设备描述符
- DB 0x10, 0x01 ; bcdUSB,USB设备版本号=1.1
- DB 0x00 ; DeviceClass,设备类码,HID设备为0,类别在接口描述符中定义
- DB 0X00 ; DeviceSubClass,设备子类码,DeviceClass为0时该字段必须为0
- DB 0X00 ; bDevicePortocol,协议码,DeviceClass为0时该字段必须为0
- DB 0x08 ; bMaxPacketSize0,端点0的最大包尺寸
- DB 0xFF, 0xFF ; bVendor,厂商ID,由USB实现者论坛确定的
- DB 0x01, 0x00 ; bProduct,产品ID
- DB 0x00, 0x01 ; bcdDevice,设备版本号为1.00
- DB 0x04 ; iManufacturer,厂商字符串的索引值,见字符串描述符
- DB 0x0E ; iProduct,产品字符串的索引值,见字符串描述符
- DB 0x30 ; iSerialNumber,产品序列号字符串的索引值,见字符串描述符
- DB 0X01 ; bNumConfigurations,配置数目只有1个
3.1 配置描述符
配置描述符的代码如下:
- ;=========================================
- ; Configuration descriptor 配置描述符
- ;=========================================
- CONFIG_DESC_DATA:
- DB 0x09 ; bLength=9,该描述符长度为9字节
- DB 0x02 ; bDescriptorType = 02,表明是配置描述符
- DB 0x3B, 0x00 ; wTotalLength = 59,配置、接口、端点和HID描述符的总和字节数
- DB 0x02 ; bNumInterfaces = 2,本配置支持的接口数目为2个
- DB 0x01 ; bConfigurationValue = 1,本配置描述符的标识符
- DB 0x00 ; iCongfiguration = 0,配置描述符说明字符串的索引值,0表示无
- DB 0XA0 ; bmAttributes,电源及唤醒设置,USB1.1版中D7=1,D6=0表示总线供电
- ; D5=1表示支持远程唤醒
- DB 0X32 ; MaxPower = 50,本设备最大耗电为50X2mA=100mA
需要说明的是wTotalLength的值,该数值为配置描述符长度(9)加上后续的键盘的接口描述符长度(9)、端点描述符长度(7)、HID描述符长度(9),以及该配置下的鼠标的接口描述符长度(9)、端点描述符长度(7)、HID描述符长度(9),共59个字节。关于鼠标的相关描述符在下面的叙述中省略了。
3.3 接口描述符
接口描述符的代码如下:
- ;=========================================
- ; Interface descriptor 接口描述符
- ;=========================================
- InterfaceDescriptor0:
- DB 0x09 ; bLength = 9,该描述符长度
- DB 0x04 ; bDescriptorType = 4,表明是接口描述符
- DB 0x00 ; bInterfaceNumber = 0,此接口的识别标识符
- DB 0x00 ; bAlternateSetting = 0,表示此接口无替代设置值
- DB 0x01 ; bNumEndpoints = 1,本接口的端点数目,HID设备使用端点1
- DB 0x03 ; bInterfaceClass = 3,表示该设备是HID类别
- DB 0x01 ; bInterfaceSubClass = 1,表示支持启动接口
- DB 0x01 ; bInterfaceProtocol = 1,表示支持键盘协议
- DB 0x00 ; iInterface = 0,接口描述符说明字符串的索引值,0表示无字符串
3.4 HID描述符
HID描述符的代码如下:
- ;=========================================
- ; HID descriptor HID描述符
- ;=========================================
- HIDDescriptor0:
- DB 0x09 ; bLength = 9,该描述符长度
- DB 0x21 ; bDescriptorType = 21h,表明是HID描述符
- DB 0x00, 0x01 ; bcdHID = 0100,HID规范版本为1.00
- DB 0x00 ; bCountryCode = 0,硬件设备所在国家的国家代码,0表示未指明
- DB 0x01 ; nNumDescriptors = 1,表示支持的描述符有1个,即一个报表描述符
- DB 0x22 ; bDescriptorType = 22h,描述符类别,表示支持的描述符是报表描述符
- DB 0x3F, 0x00 ; wDescriptorLength = 63,表示支持的报表描述符的长度
3.5 端点描述符
端点描述符的代码如下:
- ;=========================================
- ; EndPoint descriptor 端点描述符
- ;=========================================
- EndpointDescriptor0:
- DB 0x07 ; bLength = 7,该描述符长度
- DB 0x05 ; bDescriptorType = 5,表明是端点描述符
- DB 0x81 ; bEndpointAddress = 1000 0001b,表示1号输入端点
- DB 0X03 ; bmAttributes = 00000011b,表示中断类型端点
- DB 0x08, 0x00 ; wMaxPacketSize = 8,端点发送和接收的最大包尺寸为8
- DB 10 ; bInterval = 10,表示中断端点轮询时间间隔为10ms
3.6 字符串描述符
字符串描述符的代码如下:
- ;=========================================
- ; String descriptor 字符串描述符
- ;=========================================
- StringDescriptor0:
- DB 0x04 ; bLength = 4,字符串描述符0的长度为4
- DB 0x03 ; bDescriptorType = 3,表明是字符串描述符
- DB 0x09, 0x00 ; wLANGID = 0009h,表明是英语
- DB 0x0A ; bLength = 10,字符串描述符的长度为10
- DB 0x03 ; bDescriptorType = 3,表明是字符串描述符
- DB 0x41, 0x00, 0x43, 0x00, 0x4D, 0x00, 0x45, 0x00
- ; bString = “ACME“,Unicode编码的字符串
- DB 0x22 ; bLength = 34,字符串描述符的长度为34
- DB 0x03 ; bDescriptorType = 3,表明是字符串描述符
- DB 0x4C, 0x00, 0x6F, 0x00, 0x63, 0x00, 0x61, 0x00
- DB 0x74, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x20, 0x00
- DB 0x4B, 0x00, 0x65, 0x00, 0x79, 0x00, 0x62, 0x00
- DB 0x6F, 0x00, 0x61, 0x00, 0x72, 0x00, 0x64, 0x00
- ; bString = “Locator Keyboard“,Unicode编码的字符串
- DB 0x0E ; bLength = 14,字符串描述符的长度为14
- DB 0x03 ; bDescriptorType = 3,表明是字符串描述符
- DB 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x21, 0x00
- DB 0x22, 0x00, 0x23, 0x00
- ; bString = “ABC123“,Unicode编码的字符串
3.7 报表描述符
报表描述符的代码如下:
- ;=========================================
- ;HID Reports Descriptor 报表描述符
- ;=========================================
- DB 0x05, 1 ; Usage Page (1: Generic Desktop)
- DB 0x09, 6 ; Usage (6: Keyboard) 表示报表定义的是HID键盘
- DB 0xA1, 1 ; Collection (1: Application) ====================集合开始
- ;
- ; 以下定义了键盘的修饰键输入报表,共有8个键,组成一个字节
- ; 用法见HID Usage Table中的第10节中的键盘用法定义
- DB 0x05, 7 ; Usage page (7: Key Codes)
- DB 0x19, 224 ; Usage Minimum (224)
- DB 0x29, 231 ; Usage Maximum (231)
- DB 0x15, 0 ; Logical Minimum (0)
- DB 0x25, 1 ; Logical Maximum (1)
- DB 0x75, 1 ; Report Size (1)
- DB 0x95, 8 ; Report Count (8)
- DB 0x81, 2 ; Input (Data,Variable,Absolute)
- ;
- ; 以下定义了一个保留字节的输入报表
- DB 0x95, 1 ; Report Count (1)
- DB 0x75, 8 ; Report Size (8),
- DB 0x81, 1 ; Input (Constant) = Reserved Byte
- ;
- ; 以下定义了键盘的LED指示灯输出报表项目,共有5个指示灯
- ; 用法见HID Usage Table中的第11节中的LED用法定义
- DB 0x95, 5 ; Report Count (5)
- DB 0x75, 1 ; Report Size (1)
- DB 0x05, 8 ; Usage Page (Page# for LEDs)
- DB 0x19, 1 ; Usage Minimum (1)
- DB 0x29, 5 ; Usage Maximum (5)
- DB 0x91, 2 ; Output (Data, Variable, Absolute)
- ;
- ; 以下定义了3个填充位,与前面的5个LED指示灯数据组成一个完整的字节
- DB 0x95, 1 ; Report Count (1)
- DB 0x75, 3 ; Report Size (3)
- DB 0x91, 1 ; Output (Constant)
- ;
- ; 以下定义了键盘的按键值输入报表项目,共6个字节,存放键编号(0~101)
- ; 用法见HID Usage Table中的第10节中的键盘用法定义
- ; 这样的设计可以允许一次输入6个按键的键值
- DB 0x95, 6 ; Report Count (6)
- DB 0x75, 8 ; Report Size (8)
- DB 0x15, 0 ; Logical Minimum (0)
- DB 0x25, 101 ; Logical Maximum (101)
- DB 0x05, 7 ; Usage Page (7: Key Codes)
- DB 0x19, 0 ; Usage Minimum (0)
- DB 0x29, 101 ; Usage Maximum (101)
- DB 0x81, 0 ; Input (Data, Array)
-
- DB 0xC0 ; End_Collection ================================ 集合结束
通过上面的报表描述符的定义,确定了键盘的输入报表和输出报表的数据格式。其中输入报表共8个字节,输出报表只有1个字节。
图3-1 键盘的输入报表格式
图3-2 USB键盘的输出报表格式
|