zoukankan      html  css  js  c++  java
  • (转)USB的描述符及各种描述符之间的依赖关系

     

    全文链接:http://justmei.blog.163.com/blog/static/11609985320102421659260/?latestBlog

    1

    推荐

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

        USB是个通用的总线,端口都是统一的。但是USB设备却各种各样,

    例如USB鼠标,USB键盘,U盘等等,那么USB主机是如何识别出不同的

    设备的呢?这就要依赖于描述符了。

        USB的描述符主要有设备描述符,配置描述符,接口描述符,

    端点描述符,字符串描述符,HID描述符,报告描述符等等。

     

        一个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;

    2.接口描述符

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

    typedef struct _INTERFACE_DESCRIPTOR_STRUCT

    {

     BYTE bLength;                               //接口描述符的字节数大小

     BYTE bDescriptorType;                       //接口描述符的类型编号

     BYTE bInterfaceNumber;                      //该接口的编号

     BYTE bAlternateSetting;                     //备用的接口描述符编号

     BYTE bNumEndpoints;                         //该接口使用的端点数,不包括端点0

     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),      //配置描述符的字节数大小,这里为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                                 //中断扫描时间,对批量传输无效

     }

    }

    };

    其中关于端点的类型定义如下

    //定义的端点类型

    #define ENDPOINT_TYPE_CONTROL           0x00  //控制传输

    #define ENDPOINT_TYPE_ISOCHRONOUS       0x01  //同步传输

    #define ENDPOINT_TYPE_BULK              0x02  //批量传输

    #define ENDPOINT_TYPE_INTERRUPT         0x03  //中断传输

    端点号的定义如下

    #define MAIN_POINT_OUT           0x02   //2号输出端点

    #define MAIN_POINT_IN            0x82   //2号输入端点

  • 相关阅读:
    verilog学习(9)实战之存储器&奇偶校验
    求职经验之综合岗位三面
    求职经验之综合岗位二面
    求职经验之综合岗位
    verilog学习(8)实战之PPL与串行/解串器
    verilog学习(7)实战之扫描链
    verilog学习(6)实战4之触发器与锁存器
    verilog学习(5)实战3之计数器与bus
    verilog学习(4)实战1之基础练习
    求职经验之器件与芯片岗
  • 原文地址:https://www.cnblogs.com/zxc2man/p/5627759.html
Copyright © 2011-2022 走看看