全文链接: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. 第115天:Ajax 中artTemplate模板引擎(一)

    一.不分离与分离的比较 1.前后端不分离,以freemarker模板引擎为例,看一下不分离的前后端请求的流程是什么样的? 从上图可以看出,前后端开发人员的工作耦合主要在(3)Template的使用.后 ...

  2. ueditor与mvc4中坑 -编辑时显示源码问题

    最近一次使用 ueditor 时,在MVC中的修改新闻内容时发现,怎么调用都是编辑器保存下来的源码,代码如下 <script id="ucontent" name=" ...

  3. 【EF】Entity Framework实现属性映射约定

    Entity Framework Code First属性映射约定中“约定”一词,在原文版中为“Convention”,翻译成约定或许有些不好理解,这也是网上比较大多数的翻译,我们就当这是Entity ...

  4. Hadoop RPC protocol description--转

    原文地址:https://spotify.github.io/snakebite/hadoop_rpc.html Snakebite currently implements the followin ...

  5. P4551 最长异或路径

    题目描述 给定一棵 nnn 个点的带权树,结点下标从 111 开始到 NNN .寻找树中找两个结点,求最长的异或路径. 异或路径指的是指两个结点之间唯一路径上的所有边权的异或. 输入输出格式 输入格式 ...

  6. 【刷题】LOJ 6038 「雅礼集训 2017 Day5」远行

    题目描述 Miranda 生活的城市有 \(N\) 个小镇,一开始小镇间没有任何道路连接.随着经济发现,小镇之间陆续建起了一些双向的道路但是由于经济不太发达,在建设过程中,会保证对于任意两个小镇,最多 ...

  7. 【BZOJ4540】【HNOI2016】序列(莫队)

    [BZOJ4540][HNOI2016]序列(莫队) 题面 BZOJ 洛谷 Description 给定长度为n的序列:a1,a2,-,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是 ...

  8. 测试开发面试的Linux面试题总结之一:vim使用方法

    现在做测试没有说不用到linux,大部分公司都会涉及到,作为测试经常使用linux最常见手段就是查看日志,帮助开发定位问题,这是目前最常见的测试当中使用linux方法,今天就讲一讲vim文本编辑器的使 ...

  9. jqury中关于ajax的几个常用的函数

    一: AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术. 什么是 AJAX ? AJAX = 异步 JavaScript 和 XML. AJAX 是一种用于创建快速动态网页的技术 ...

  10. 【bzoj3678】wangxz与OJ

    Portal -- > bzoj 3678 Solution 这题==真实智力康复qwq 然而众多神犇都说是10min写完的题我..可能写了近1h吧==深深感受到自己的弱小qwq (丢上来是因为 ...