例如USB鼠标,USB键盘,U盘等等,那么USB主机是如何识别出不同的
设备的呢?这就要依赖于描述符了。
端点描述符,字符串描述符,HID描述符,报告描述符等等。
关于报告描述符,请看我以前写的:《USB HID报告及报告描述符简介 》
http://group.ednchina.com/93/198.aspx 。
少种配置,每种配置描述符对应着配置描述符;而在配置描述符中又定义
了该配置里面有多少个接口,每个接口有对应的接口描述符;在接口描
述符里面又定义了该接口有多少个端点,每个端点对应一个端点描述符;
端点描述符定义了端点的大小,类型等等。由此我们可以看出,USB的
描述符之间的关系是一层一层的,最上一层是设备描述符,下面是配置
描述符,再下面是接口描述符,再下面是端点描述符。在获取描述符时,
先获取设备描述符,然后再获取配置描述符,根据配置描述符中的配置
集合长度,一次将配置描述符、接口描述符、端点描述符一起一次读回。
其中可能还会有获取设备序列号,厂商字符串,产品字符串等。
#define DEVICE_DESCRIPTOR
#define CONFIGURATION_DESCRIPTOR
#define STRING_DESCRIPTOR
#define INTERFACE_DESCRIPTOR
#define ENDPOINT_DESCRIPTOR
下面分别详细介绍一下各描述符。
1.设备描述符
//定义标准的设备描述符结构
typedef struct _DEVICE_DCESCRIPTOR_STRUCT
{
BYTE blength;
BYTE bDescriptorType;
WORD bcdUSB;
BYTE bDeviceClass;
BYTE bDeviceSubClass;
BYTE bDeviceProtocol;
BYTE bMaxPacketSize0;
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),
DEVICE_DESCRIPTOR,
0x1001,
0x00,
0x00,
0x00,
0x10,
0x7104,
0xf0ff,
0x0100,
0x01,
0x02,
0x03,
0x01
};
2.配置描述符
//定义标准的配置描述符结构
typedef struct _CONFIGURATION_DESCRIPTOR_STRUCT
{
BYTE bLength;
BYTE bDescriptorType;
WORD wTotalLength;
BYTE bNumInterfaces;
BYTE bConfigurationValue;
BYTE iConfiguration;
BYTE bmAttributes;
BYTE MaxPower;
}
CONFIGURATION_DESCRIPTOR_STRUCT, * pCONFIGURATION_DESCRIPTOR_STRUCT;
2.接口描述符
//定义标准的接口描述符结构
typedef struct _INTERFACE_DESCRIPTOR_STRUCT
{
BYTE bLength;
BYTE bDescriptorType;
BYTE bInterfaceNumber;
BYTE bAlternateSetting;
BYTE bNumEndpoints;
BYTE bInterfaceClass;
BYTE bInterfaceSubClass;
BYTE bInterfaceProtocol;
BYTE iInterface;
}
INTERFACE_DESCRIPTOR_STRUCT, * pINTERFACE_DESCRIPTOR_STRUCT;
4.端点描述符
//定义标准的端点描述符结构
typedef struct _ENDPOINT_DESCRIPTOR_STRUCT
{
BYTE bLegth;
BYTE bDescriptorType;
BYTE bEndpointAddress;
BYTE bmAttributes;
WORD wMaxPacketSize;
BYTE bInterval;
}
ENDPOINT_DESCRIPTOR_STRUCT, * pENDPOINT_DESCRIPTOR_STRUCT;
下面是一个配置描述符集合的定义
typedef struct _CON_INT_ENDP_DESCRIPTOR_STRUCT
{
CONFIGURATION_DESCRIPTOR_STRUCT configuration_descriptor;
INTERFACE_DESCRIPTOR_STRUCT interface_descritor;
ENDPOINT_DESCRIPTOR_STRUCT endpoint_descriptor[ENDPOINT_NUMBER];
}CON_INT_ENDP_DESCRIPTOR_STRUCT;
配置描述符集合的示例
code CON_INT_ENDP_DESCRIPTOR_STRUCT con_int_endp_descriptor= //配置描述符集合
{
//configuration_descriptor
{
sizeof(CONFIGURATION_DESCRIPTOR_STRUCT),
CONFIGURATION_DESCRIPTOR,
(sizeof(CONFIGURATION_DESCRIPTOR_STRUCT)+
sizeof(INTERFACE_DESCRIPTOR_STRUCT)+
sizeof(ENDPOINT_DESCRIPTOR_STRUCT)*ENDPOINT_NUMBER)*256+
(sizeof(CONFIGURATION_DESCRIPTOR_STRUCT)+
sizeof(INTERFACE_DESCRIPTOR_STRUCT)+
sizeof(ENDPOINT_DESCRIPTOR_STRUCT)*ENDPOINT_NUMBER)/256,
0x01,
0x01,
0x00,
0x80,
0xC8
},
//interface_descritor
{
sizeof(INTERFACE_DESCRIPTOR_STRUCT),
INTERFACE_DESCRIPTOR,
0x00,
0x00,
ENDPOINT_NUMBER,
0x08,
0x06,
0x50,
0x00
},
//endpoint_descriptor[]
{
{
sizeof(ENDPOINT_DESCRIPTOR_STRUCT), //端点描述符的字节数大小,这里为7
ENDPOINT_DESCRIPTOR,
MAIN_POINT_IN,
ENDPOINT_TYPE_BULK,
0x4000,
0x00
},
{
sizeof(ENDPOINT_DESCRIPTOR_STRUCT), //端点描述符的字节数大小,这里为7
ENDPOINT_DESCRIPTOR,
MAIN_POINT_OUT,
ENDPOINT_TYPE_BULK,
0x4000,
0x00
}
}
};
其中关于端点的类型定义如下
//定义的端点类型
#define ENDPOINT_TYPE_CONTROL
#define ENDPOINT_TYPE_ISOCHRONOUS
#define ENDPOINT_TYPE_BULK
#define ENDPOINT_TYPE_INTERRUPT
端点号的定义如下
#define MAIN_POINT_OUT
#define MAIN_POINT_IN