前面几节说了设备描述符和配置描述符,这一篇文章看一下接口描述符。首先要明确的一点是:接口描述符不能单独返回USB主机,必须跟在配置描述符后面返回。
它的结构如下:
偏移量 | 名称 | 大小 | 说明 |
0 | bLength | 1 | 描述符的长度(9字节) |
1 | bDescriptorTyep | 1 | 描述符类型(接口描述符为0x04) |
2 | bInterfaceNumber | 1 | 该接口的编号(从0开始) |
3 | bAlternateSetting | 1 | 该接口的备用编号 |
4 | bNumEndpoints | 1 | 该接口使用的端点数 |
5 | bInterfaceClass | 1 | 该接口使用的类 |
6 | bInterfaceSubClass | 1 | 该接口使用的子类 |
7 | bInterfaceProtocol | 1 | 该接口使用的协议 |
8 | iInterface | 1 | 描述该接口的字符串的索引值 |
注意:接口不是端点,两者不要混淆。
对比设备描述符、配置描述符,你会发现这几者格式非常类似。我们继续简单的过一下。
bLength,描述符长度,不解释。
bDescriptorTyep,描述符类型,看代码,不解释。
#define USB_DESC_TYPE_DEVICE 0x01U
#define USB_DESC_TYPE_CONFIGURATION 0x02U
#define USB_DESC_TYPE_STRING 0x03U
#define USB_DESC_TYPE_INTERFACE 0x04U
#define USB_DESC_TYPE_ENDPOINT 0x05U
#define USB_DESC_TYPE_DEVICE_QUALIFIER 0x06U
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 0x07U
#define USB_DESC_TYPE_BOS 0x0FU
bInterfaceNumber,接口编号。如果一个配置有多个接口的话,那么每个接口的编号都有一个独立的编号,编号从0开始递增。这里可以设置为0。
bAlternateSetting,备用接口编号。用法和接口编号一样,但一般很少用,一般设置为0。
bNumEndpoints,该接口使用的端点个数。从名字就看出来了,很简单不解释。注意一点,这个端点个数不包括0端点。
接下来,bInterfaceClass、bInterfaceSubClass与bInterfaceProtocol相对麻烦一些。这里需要参考相应的文档:hid1_11.
根据文档说明:
The USB Core Specification defines the HID class code. The bInterfaceClass
member of an Interface descriptor is always 3 for HID class devices.
bInterfaceClass,因为鼠标属于HID类,而HID类的编码默认是3.
bInterfaceSubClass,子类中只有一个接口子类,就是0x02.
bInterfaceProtocol,看下图。Keyboard是1,Mouse是2.
懂了?
iInterface,字符串索引值。没有的话一般都是0.
最后,放一段STM32中接口描述符的代码:
/************** Descriptor of Joystick Mouse interface ****************/
/* 09 */
0x09, /*bLength: Interface Descriptor size*/
USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/
0x00, /*bInterfaceNumber: Number of Interface*/
0x00, /*bAlternateSetting: Alternate setting*/
0x01, /*bNumEndpoints*/
0x03, /*bInterfaceClass: HID*/
0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
0x02, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
0, /*iInterface: Index of string descriptor*/
好了,接口描述符说完了。文章中提到的文档hid1_11可以从USB官网获得,或者也可以关注公众号:单片机爱好者,回复关键词:hid1_11。