USB的描述符及各种描述符之间的依赖关系

来源:互联网 发布:单片机汇编set 编辑:程序博客网 时间:2024/06/09 15:50

USB入门系列之七 —— USB的描述符及各种描述符之间的依赖关系

USB是个通用的总线,端口都是统一的。但是USB设备却各种各样,
例如USB鼠标,USB键盘,U盘等等,那么USB主机是如何识别出不同的
设备的呢?这就要依赖于描述符了。
    USB
的描述符主要有设备描述符,配置描述符,接口描述符,
端点描述符,字符串描述符,HID描述符,报告描述符等等。
关于报告描述符,请看我以前写的:《USBHID报告及报告描述符简介

 http://group.ednchina.com/93/198.aspx

一个USB设备有一个设备描述符,设备描述符里面决定了该设备有多少种配置,每种配置描述符对应着配置描述符;而在配置描述符中又定义了该配置里面有多少个接口,每个接口有对应的接口描述符;在接口描述符里面又定义了该接口有多少个端点,每个端点对应一个端点描述符;端点描述符定义了端点的大小,类型等等。由此我们可以看出,USB的描述符之间的关系是一层一层的,最上一层是设备描述符,下面是配置描述符,再下面是接口描述符,再下面是端点描述符。在获取描述符时,先获取设备描述符,然后再获取配置描述符,根据配置描述符中的配置集合长度,一次将配置描述符、接口描述符、端点描述符一起一次读回。其中可能还会有获取设备序列号,厂商字符串,产品字符串等。    

     每种描述符都有自己独立的编号,如下:
#defineDEVICE_DESCRIPTOR                   0x01  //
设备描述符
#define CONFIGURATION_DESCRIPTOR       0x02  //
配置描述符
#defineSTRING_DESCRIPTOR                     0x03  //
字符串描述符
#define INTERFACE_DESCRIPTOR                0x04  //
接口描述符
#defineENDPOINT_DESCRIPTOR                0x05  //
端点描述符
   
下面分别详细介绍一下各描述符。

1.设备描述符

//定义标准的设备描述符结构

typedef struct _DEVICE_DCESCRIPTOR_STRUCT
{
 BYTEblength;                              //
设备描述符的字节数大小
 BYTEbDescriptorType;                     //
设备描述符类型编号
 WORDbcdUSB;                               //USB
版本号
 BYTEbDeviceClass;                         //USB
分配的设备类代码
 BYTEbDeviceSubClass;                      //USB
分配的子类代码
 BYTEbDeviceProtocol;                      //USB
分配的设备协议代码
 BYTEbMaxPacketSize0;                      //
端点0的最大包大小
 WORDidVendor;                             //
厂商编号
 WORDidProduct;                            //
产品编号
 WORDbcdDevice;                            //
设备出厂编号
 BYTE iManufacturer;                        //
设备厂商字符串的索引
 BYTEiProduct;                             //
描述产品字符串的索引
 BYTEiSerialNumber;                        //
描述设备序列号字符串的索引
 BYTEbNumConfigurations;                   //
可能的配置数量
}
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
{
 BYTEbLength;                              //
配置描述符的字节数大小
 BYTE bDescriptorType;                      //
配置描述符类型编号
 WORDwTotalLength;                         //
此配置返回的所有数据大小
 BYTEbNumInterfaces;                       //
此配置所支持的接口数量
 BYTEbConfigurationValue;                  //Set_Configuration
命令所需要的参数值
 BYTE iConfiguration;                       //
描述该配置的字符串的索引值
 BYTEbmAttributes;                         //
供电模式的选择
 BYTEMaxPower;                             //
设备从总线提取的最大电流
}
CONFIGURATION_DESCRIPTOR_STRUCT, * pCONFIGURATION_DESCRIPTOR_STRUCT;

2.接口描述符

//定义标准的接口描述符结构

typedef struct _INTERFACE_DESCRIPTOR_STRUCT
{
 BYTEbLength;                              //
接口描述符的字节数大小
 BYTEbDescriptorType;                      //
接口描述符的类型编号
 BYTEbInterfaceNumber;                     //
该接口的编号
 BYTEbAlternateSetting;                    //
备用的接口描述符编号
 BYTEbNumEndpoints;                        //
该接口使用的端点数,不包括端点0
 BYTEbInterfaceClass;                      //
接口类型
 BYTEbInterfaceSubClass;                   //
接口子类型
 BYTEbInterfaceProtocol;                   //
接口遵循的协议
 BYTE iInterface;                           //
描述该接口的字符串索引值
}
INTERFACE_DESCRIPTOR_STRUCT, * pINTERFACE_DESCRIPTOR_STRUCT;

4.端点描述符

//定义标准的端点描述符结构

typedef struct _ENDPOINT_DESCRIPTOR_STRUCT
{
 BYTEbLegth;                               //
端点描述符字节数大小
 BYTE bDescriptorType;                      //
端点描述符类型编号
 BYTEbEndpointAddress;                     //
端点地址及输入输出属性
 BYTEbmAttributes;                         //
端点的传输类型属性
 WORDwMaxPacketSize;                       //
端点收、发的最大包大小
 BYTEbInterval;                            //
主机查询端点的时间间隔
}
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),      //
配置描述符的字节数大小,这里为9
 CONFIGURATION_DESCRIPTOR,                    //
配置描述符类型编号,配置描述符为2
 (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,                                 //iConfiguration
字段
 0x80,                                 //
采用总线供电,不支持远程唤醒
 0xC8                                  //
从总线获取最大电流400mA
},
//interface_descritor                  //
接口描述符
{
 sizeof(INTERFACE_DESCRIPTOR_STRUCT),   //
接口描述符的字节数大小,这里为9
 INTERFACE_DESCRIPTOR,                 //
接口描述符类型编号,接口描述符为3
 0x00,                                 //
接口编号为4
 0x00,                                 //
该接口描述符的编号为0
 ENDPOINT_NUMBER,                      //
0端点数量为2,只使用端点主端点输入和输出
 0x08,                                 //
定义为USB大容量存储设备
 0x06,                                 //
使用的子类,为简化块命令
 0x50,                                 //
使用的协议,这里使用单批量传输协议
 0x00                                  //
接口描述符字符串索引,为0,表示没有字符串
},

//endpoint_descriptor[]
{
 {                                    //
主端点输入描述
  sizeof(ENDPOINT_DESCRIPTOR_STRUCT),  //
端点描述符的字节数大小,这里为7
 ENDPOINT_DESCRIPTOR,                //
端点描述符类型编号,端点描述符为5
 MAIN_POINT_IN,                      //
端点号,主输入端点
 ENDPOINT_TYPE_BULK,                 //
使用的传输类型,批量传输
 0x4000,                             //
该端点支持的最大包尺寸,64字节
 0x00                                //
中断扫描时间,对批量传输无效
 },
 
 {                                    //
主端点输出描述
  sizeof(ENDPOINT_DESCRIPTOR_STRUCT),  //
端点描述符的字节数大小,这里为7
  ENDPOINT_DESCRIPTOR,                //
端点描述符类型编号,端点描述符为5
 MAIN_POINT_OUT,                     //
端点号,主输出端点
 ENDPOINT_TYPE_BULK,                 //
使用的传输类型,批量传输
 0x4000,                             //
该端点支持的最大包尺寸,64字节
 0x00                                //
中断扫描时间,对批量传输无效
 }
}
};

其中关于端点的类型定义如下
//
定义的端点类型
#defineENDPOINT_TYPE_CONTROL          0x00  //
控制传输
#define ENDPOINT_TYPE_ISOCHRONOUS      0x01  //
同步传输
#defineENDPOINT_TYPE_BULK             0x02  //
批量传输
#define ENDPOINT_TYPE_INTERRUPT        0x03  //
中断传输

端点号的定义如下
#defineMAIN_POINT_OUT          0x02   //2
号输出端点
#defineMAIN_POINT_IN           0x82   //2
号输入端点

 


原创粉丝点击