USB是个通用的总线,端口都是统一的。但是USB设备却各种各样,
例如USB鼠标,USB键盘,U盘等等,那么USB主机是如何识别出不同的
设备的呢?这就要依赖于描述符了。
USB的描述符主要有设备描述符,配置描述符,接口描述符,
端点描述符,字符串描述符,HID描述符,报告描述符等等。
关于报告描述符,请看我以前写的:《USB HID报告及报告描述符简介 》
http://group.ednchina.com/93/198.aspx。
一个USB设备有一个设备描述符,设备描述符里面决定了该设备有多
少种配置,每种配置描述符对应着配置描述符;而在配置描述符中又定义
了该配置里面有多少个接口,每个接口有对应的接口描述符;在接口描
述符里面又定义了该接口有多少个端点,每个端点对应一个端点描述符;
端点描述符定义了端点的大小,类型等等。由此我们可以看出,USB的
描述符之间的关系是一层一层的,最上一层是设备描述符,下面是配置
描述符,再下面是接口描述符,再下面是端点描述符。在获取描述符时,
先获取设备描述符,然后再获取配置描述符,根据配置描述符中的配置
集合长度,一次将配置描述符、接口描述符、端点描述符一起一次读回。
其中可能还会有获取设备序列号,厂商字符串,产品字符串等。
每种描述符都有自己独立的编号,如下:
- #define DEVICE_DESCRIPTOR 0x01 //设备描述符
- #define CONFIGURATION_DESCRIPTOR 0x02 //配置描述符
- #define STRING_DESCRIPTOR 0x03 //字符串描述符
- #define INTERFACE_DESCRIPTOR 0x04 //接口描述符
- #define ENDPOINT_DESCRIPTOR 0x05 //端点描述符
下面分别详细介绍一下各描述符。
1.设备描述符
- //定义标准的设备描述符结构
- typedef struct _DEVICE_DCESCRIPTOR_STRUCT
- {
- BYTE blength; //设备描述符的字节数大小
- BYTE bDescriptorType; //设备描述符类型编号
- WORD bcdUSB; //USB版本号
- BYTE bDeviceClass; //USB分配的设备类代码
- BYTE bDeviceSubClass; //USB分配的子类代码
- BYTE bDeviceProtocol; //USB分配的设备协议代码
- BYTE bMaxPacketSize0; //端点0的最大包大小
- WORD idVendor; //厂商编号
- WORD idProduct; //产品编号
- WORD bcdDevice; //设备出厂编号
- BYTE iManufacturer; //设备厂商字符串的索引
- BYTE iProduct; //描述产品字符串的索引
- BYTE iSerialNumber; //描述设备序列号字符串的索引
- BYTE bNumConfigurations; //可能的配置数量
- }
- DEVICE_DESCRIPTOR_STRUCT, * pDEVICE_DESCRIPTOR_STRUCT;
- //实际的设备描述符示例
- code DEVICE_DESCRIPTOR_STRUCT device_descriptor= //设备描述符
- {
- sizeof(DEVICE_DESCRIPTOR_STRUCT), //设备描述符的字节数大小,这里是18字节
- DEVICE_DESCRIPTOR, //设备描述符类型编号,设备描述符是01
- 0x1001, //USB版本号,这里是USB01.10,即USB1.1。由于51是大端模式,所以高低字节交换
- 0x00, //USB分配的设备类代码,0表示类型在接口描述符中定义
- 0x00, //USB分配的子类代码,上面一项为0时,本项也要设置为0
- 0x00, //USB分配的设备协议代码,上面一项为0时,本项也要设置为0
- 0x10, //端点0的最大包大小,这里为16字节
- 0x7104, //厂商编号,这个是需要跟USB组织申请的ID号,表示厂商代号。
- 0xf0ff, //该产品的编号,跟厂商编号一起配合使用,让主机注册该设备并加载相应的驱动程序
- 0x0100, //设备出厂编号
- 0x01, //设备厂商字符串的索引,在获取字符串描述符时,使用该索引号来识别不同的字符串
- 0x02, //描述产品字符串的索引,同上
- 0x03, //描述设备序列号字符串的索引,同上
- 0x01 //可能的配置数为1,即该设备只有一个配置
- };
2.配置描述符
- //定义标准的配置描述符结构
- typedef struct _CONFIGURATION_DESCRIPTOR_STRUCT
- {
- BYTE bLength; //配置描述符的字节数大小
- BYTE bDescriptorType; //配置描述符类型编号
- WORD wTotalLength; //此配置返回的所有数据大小
- BYTE bNumInterfaces; //此配置所支持的接口数量
- BYTE bConfigurationValue; //Set_Configuration命令所需要的参数值
- BYTE iConfiguration; //描述该配置的字符串的索引值
- BYTE bmAttributes; //供电模式的选择
- BYTE MaxPower; //设备从总线提取的最大电流
- }
- CONFIGURATION_DESCRIPTOR_STRUCT, * pCONFIGURATION_DESCRIPTOR_STRUCT;