全文链接: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号输入端点

(转)USB的描述符及各种描述符之间的依赖关系的更多相关文章

  1. usb驱动开发8之配置描述符

    前面分析了usb的四大描述符之端点描述符,接口描述符(每一个接口对应一个功能,与之配备相应驱动),下面是看配置描述符还是看设备描述符呢??我们知道,设备大于配置,配置大于接口,接口可以有多种设置. 我 ...

  2. usb驱动开发7之接口描述符

    前面struct usb_interface里表示接口设置的struct usb_host_interface被有意的飘过了,咱们在这节主要讲讲这个结构体,同样在include/linux/usb.h ...

  3. usb协议分析-设备描述符配置包-描述符

    /* usb协议分析仅供大家参考---设备描述符配置包,设备描述符, 地址设置, 配置描述符, 字符串描述符 */ /* -1- usb设备描述符配置包 */ typedef struct _USB_ ...

  4. usb的hid鼠标键盘报告描述符(五)

    title: usb的hid鼠标键盘报告描述符 tags: linux date: 2018/12/20/ 18:05:08 toc: true --- usb的hid鼠标键盘报告描述符 https: ...

  5. STM32 USB设备描述符、配置描述符、端点描述符含义

    查了一整天的资料,自己把不懂的全部试了一遍 一下是程序以及注释 /* USB设备描述符*/ const uint8_t CustomHID_DeviceDescriptor[CUSTOMHID_SIZ ...

  6. 在Visual Studio中使用组件图描述项目组件依赖关系

    如果想描述项目组件的关系,可以考虑使用UML组建图. 在建模项目下添加一个名称为"Applicaiton Component Structure"的UML组建图. 添加各个组件,并 ...

  7. 2016 2 - 23 arc中的所有权修饰符(_strong修饰符与_weak修饰符)

    一 _strong修饰符 1._strong修饰符是id类型和对象类型默认的所有权修饰符.如下: id obj = [[NSObject alloc] init];//在没用明确变量所有权修饰符时,会 ...

  8. 背水一战 Windows 10 (9) - 资源: 资源限定符概述, 资源限定符示例

    [源码下载] 背水一战 Windows 10 (9) - 资源: 资源限定符概述, 资源限定符示例 作者:webabcd 介绍背水一战 Windows 10 之 资源 资源限定符概述 资源限定符示例 ...

  9. 说说ID选择符、类选择符和HTML标记选择符的优先级顺序

    ID选择符.类选择符和HTML标记选择符三者之间的优先级顺序是:ID选择符>类选择符>HTML标记选择符,但是可以用!important提升优先权. 如:       p{color:#f ...

随机推荐

  1. 【.Net】net 反射15分钟速成

    概述 什么是反射 Reflection,中文翻译为反射.        这是.Net中获取运行时类型信息的方式,.Net的应用程序由几个部分:‘程序集(Assembly)’.‘模块(Module)’. ...

  2. HDU4811_Ball

    又是数学题. 每次放入一个球所得到的的分数为x1+x2(x1表示左边的球中颜色的种数,x2表示右边) 其实如果一个球的数量超过了2,那么剩下的就是一个乘法了. 这个理解很简单,因为超过了2的话,说明最 ...

  3. CF373C-Counting Kangaroos is Fun

    题意 有\(n\)只袋鼠,每只袋鼠有一个体积,如果一个袋鼠的体积小于等于另一个袋鼠体积的一半,那么这个袋鼠就可以被那一个袋鼠装进袋里.一个装了袋鼠的袋鼠不能再装或被装.被装进袋子的袋鼠就看不到了. 问 ...

  4. bzoj4754[JSOI2016]独特的树叶

    这个题....别人写得怎么都....那么短啊? 我怎么....WA了好几次啊....怎么去loj扒了数据才调出来啊? 这个算法...怎么我还是不知道对不对啊 怎么回事啊怎么回事啊怎么回事啊? 请无视上 ...

  5. 【bzoj4487】[Jsoi2015]染色问题 容斥原理

    题目描述 棋盘是一个n×m的矩形,分成n行m列共n*m个小方格.现在萌萌和南南有C种不同颜色的颜料,他们希望把棋盘用这些颜料染色,并满足以下规定: 1.  棋盘的每一个小方格既可以染色(染成C种颜色中 ...

  6. BZOJ4719 NOIP2016天天爱跑步(线段树合并)

    线段树合并的话这个noip最难题就是个裸题了. 注意merge最后return x,以及如果需要区间查询的话这里还需要up,无数次死于这里. #include<iostream> #inc ...

  7. ubuntu adduser

    ubuntu adduser 添加用户 hexan 到目录 /home/hexan 下.$ sudo adduser hexan -home /home/hexan 添加一个普通用户adduser [ ...

  8. 【BZOJ4198】【NOI2015】荷马史诗(贪心,Huffman树)

    [BZOJ4198][NOI2015]荷马史诗(贪心,Huffman树) 题面 BZOJ 洛谷 题解 合并果子都是不知道多久以前做过的了.现在才知道原来本质就是一棵哈夫曼树啊. 这题我们仔细研究一下题 ...

  9. 【BZOJ】2956:模积和

    Time Limit: 10 Sec  Memory Limit: 128 MB Description 求∑∑((n mod i)*(m mod j))其中1<=i<=n,1<=j ...

  10. 《Java程序设计》第7周学习总结 20165218 2017-2018-1

    20165218 2017-2018-1 <Java程序设计>第7周学习总结 教材学习内容总结 JDBC与MySQL数据库 数据库的功能:数据的存储.查询.修改.安全 MySQL:数据库: ...