USB描述符【整理】

USB描述符

USB描述符信息存储在USB设备中,在枚举过程中,USB主机会向USB设备发送GetDescriptor请求,USB设备在收到这个请求之后,会将USB描述符信息返回给USB主机,USB主机分析返回来的数据,判断出该设备是哪一种USB设备,建立相应的数据链接通道。那么USB描述符信息到底是一个什么样的数据呢,USB协议中有详细描述。

 

通用的USB描述符信息包括设备描述符、配置描述符、接口描述符和端点描述符,具体不同的USB设备还包括其它类型的描述符,例如,USB鼠标、键盘还包括HID描述符和报告描述符,还有可能包括字符串描述符,USB协议中对描述符类型定义如下:

 

所有的描述符信息都是通过发送GetDescriptor请求得到的,但是USB设备也不知道你要获取的是哪种描述符,所以还需要在GetDescriptor请求中指定描述符的类型以及描述符的长度,这样USB设备才能正确的返回描述符信息。

 

 

1 设备描述符

Linux中对于设备描述符结构体定义如下:

 

216 /* USB_DT_DEVICE: Device descriptor */
217 struct usb_device_descriptor {
218         __u8  bLength;
219         __u8  bDescriptorType;
220     
221         __le16 bcdUSB;
222         __u8  bDeviceClass;
223         __u8  bDeviceSubClass;
224         __u8  bDeviceProtocol;
225         __u8  bMaxPacketSize0;
226         __le16 idVendor;
227         __le16 idProduct;
228         __le16 bcdDevice;
229         __u8  iManufacturer;
230         __u8  iProduct;
231         __u8  iSerialNumber;
232         __u8  bNumConfigurations;
233 } __attribute__ ((packed));
234 
235 #define USB_DT_DEVICE_SIZE              18

 

bLength: 描述符的长度,设备描述符的长度为18个字节。

bDescriptorType: 描述符的类型,设备描述符的类型为0x01。

bcdUSB: USB设备所遵循的协议版本号,例如2.0协议为0x0200。

bDeviceClass: USB设备类代码,由USB-IF分配,如果该字段为0x00,表示由接口描述符来指定(有可能该USB设备是一个复合设备,USB设备的各个接口相互独立,分别属于不同的设备类)。如果是0x01~0xfe,表示为USB-IF定义的设备类,例如0x03为HID设备,0x09为HUB设备。如果是0xff,表示由厂商自定义设备类型。

bDeviceSubClass: USB子类代码,由USB-IF分配,如果bDeviceClass为0x00,那么该字段也必须为 0x00,其它情况可以参考USB关于对于USB Device Class的定义。

bDeviceProtocol: 协议代码,由USB-IF分配,如果bDeviceClass和bDeviceSubClass定义为0x00,那么该字段也必须为0x00。

bMaxPacketSize0: 端点0最大数据包长度,必须为8、16、32和64。

idVendor: 厂商ID,由USB-IF分配,需要向USB-IF组织申请。

idProduct: 产品ID,由厂商指定。

bcdDevice: 设备序列号,由厂商自行设置。

iManufacturer: 用于描述厂商的字符串描述符索引。

iProduct: 用于描述产品的字符串描述符索引。

iSerialNumber: 用于描述产品序列号的字符串描述符索引,注意,所有的字符串描述符是可选的,如果没有字符串描述符,指定这些索引为0x00。

bNumConfigurations:配置描述符数量。

例如,我的USB鼠标设备描述符信息如下:

 

从中可以看出该USB设备符合USB1.1协议,在设备描述中并没有指定该USB设备类型,端点0最大数据包长度为8个字节,也就是说一次还不能获取完全设备描述符,需要三次才能获取完全。再看bMaxPacketSize0在设备描述符中的偏移,刚好是第8个字节,也就是说传输一次就能知道端点0一次能够传输多长的数据,根据这个值才能判断出是否继续传输,来完整的获取描述符信息。该USB设备的idVendor为0x80ee,idProduct为0x0021,有一个配置等等信息。

 

 

2 配置描述符

一个USB设备只有一个USB设备描述符,可以有多个配置描述符,配置描述符定义如下:

 

265 /* USB_DT_CONFIG: Configuration descriptor information.
266  *
267  * USB_DT_OTHER_SPEED_CONFIG is the same descriptor, except that the
268  * descriptor type is different.  Highspeed-capable devices can look
269  * different depending on what speed they're currently running.  Only
270  * devices with a USB_DT_DEVICE_QUALIFIER have any OTHER_SPEED_CONFIG
271  * descriptors.
272  */
273 struct usb_config_descriptor {
274         __u8  bLength;
275         __u8  bDescriptorType;
276 
277         __le16 wTotalLength;
278         __u8  bNumInterfaces;
279         __u8  bConfigurationValue;
280         __u8  iConfiguration;
281         __u8  bmAttributes;
282         __u8  bMaxPower;
283 } __attribute__ ((packed));
284 
285 #define USB_DT_CONFIG_SIZE              9

 

bLength: 配置描述符长度,配置描述符长度为9字节大小。

bDescriptorType: 描述符类型,配置描述符类型为0x02。

wTotalLength: 配置描述符信息总的大小,包括接口描述符、端点描述符等等。

bNumInterfaces: USB接口数量。

bConfigurationValue: 当使用SetConfiguration和GetConfiguration请求时所指定的配置索引值。

iConfiguration: 描述配置的字符串描述符索引。

bmAttributes: 供电配置,位详细定义如下:

                          D7              保留,必须置1

                          D6              自供电模式

                          D5              远程唤醒

                          D4~D0      保留

bMaxPower: 最大功耗,以2mA为单位,例如0x32为50*2=100mA。

我的USB鼠标配置描述符信息如下:

 

从中可以看出该设备配置信息总大小为0x22=34字节大小,有一个接口,最大功耗为100mA等信息。

 

 

3 接口描述符

一个配置中可以有一个或多个接口,一个接口中有0个或多个端点,接口描述符和端点描述符不能直接通过GetDescriptor请求返回,必须连同配置描述符一起返回,Linux中接口描述符定义如下:

 

309 /* USB_DT_INTERFACE: Interface descriptor */
310 struct usb_interface_descriptor {
311         __u8  bLength;
312         __u8  bDescriptorType;
313 
314         __u8  bInterfaceNumber;
315         __u8  bAlternateSetting;
316         __u8  bNumEndpoints;
317         __u8  bInterfaceClass;
318         __u8  bInterfaceSubClass;
319         __u8  bInterfaceProtocol;
320         __u8  iInterface;
321 } __attribute__ ((packed));
322 
323 #define USB_DT_INTERFACE_SIZE           9

 

bLength: 描述符长度,接口描述符长度为9个字节。

bDescriptorType: 描述符类型,接口描述符的类型为0x04。

bInterfaceNumber: 该接口编号,接口编号从0开始分配,当一个配置有多个接口时,就用该字段来区分不同的接口。

bAlternateSetting:

bNumEndpoints:  端点数量,不包括端点0。

bInterfaceClass

bInterfaceSubClass

bInterfaceProtocol:  和设备描述符中的bDeviceClass、bDeviceSubClass、bDeviceProtocol类似。

iInterface: 描述该接口的字符串描述符索引。

接口描述符实例如下:

 

前面9个字节是配置描述符,从中可以看出端点数量为1,bInterfaceClass为0x03,即为HID设备。

 

 

4 端点描述符

注意,端点0没有端点描述符,Linux中端点描述符结构定义如下:

 

327 /* USB_DT_ENDPOINT: Endpoint descriptor */
328 struct usb_endpoint_descriptor {
329         __u8  bLength;
330         __u8  bDescriptorType;
331 
332         __u8  bEndpointAddress;
333         __u8  bmAttributes;
334         __le16 wMaxPacketSize;
335         __u8  bInterval;
336 
337         /* NOTE:  these two are _only_ in audio endpoints. */
338         /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
339         __u8  bRefresh;
340         __u8  bSynchAddress;
341 } __attribute__ ((packed));
342 
343 #define USB_DT_ENDPOINT_SIZE            7
344 #define USB_DT_ENDPOINT_AUDIO_SIZE      9       /* Audio extension */

 

bLength: 描述符长度,这里有两个值如果是audio设备的端点,那么端点描述符长度就为9个字节,对于其它设备端点,端点描述符长度就为7个字节。

bDescriptorType: 描述符类型,端点描述符类型为0x05。

bEndpointAddress: 端点地址,详细定义如下:

                                  D7 端点方向

                                  0                  OUT端点

                                  1                  IN端点

                                  D6~D4       保留 

                                  D3~D0       端点编号

bmAttributes: 端点类型,详细定义如下:

                                  D5~D4 用途

                                  00     数据端点

                                  01     反馈端点

                                  10     隐式反馈数据端点

                                  11     保留

                                  D3~D2 同步类型

                                  00     非同步

                                  01     异步

                                  10     自适应

                                  11     同步

                                  D1~D0 传输类型

                                  00     控制传输

                                  01     同步传输

                                  10     块传输

                                  11     中断传输

                                  如果该端点不是同步端点,D5~D2保留且必须置0。

wMaxPacketSize: 端点所支持最大数据包的长度,详细定义如下:

                                D10~D0 最大数据包长度

                                D12~D11

                                其余位保留且必须置0。

bInterval:端点数据传输的访问时间间隔。对于全速/低速的中断端点,取值范围为 1~255,对于高速中断端点,取值范围为1~16,详细定义可以参考USB协议。

端点描述符实例如下:

 

因为不能单独的获取接口和端点描述符,所以我将设备配置信息全获取下来了,端点描述符从0x07处开始,0x07为端点描述符长度,该端点是一个IN端点,端点地址为1,该端点是一个中断端点,最大数据包长度为6个字节,时间间隔为10ms。

 

 

5 HID描述符

从上图可以看出,除了配置描述符、接口描述符、端点描述符之外、还有一个描述符,它就是HID描述符,HID描述符专用于HID类设备。Linux关于HID描述符结构定义如下:

 

537 struct hid_class_descriptor {
538         __u8  bDescriptorType;
539         __le16 wDescriptorLength;
540 } __attribute__ ((packed));
541 
542 struct hid_descriptor {
543         __u8  bLength;
544         __u8  bDescriptorType;
545         __le16 bcdHID;
546         __u8  bCountryCode;
547         __u8  bNumDescriptors;
548 
549         struct hid_class_descriptor desc[1];
550 } __attribute__ ((packed));

 

bLength: 描述符长度。

bDescriptorType:描述符类型,HID描述符的类型为0x21。

bcdHID: 所遵循的HID协议版本。

bCountryCode: 国家代码。

bNumDescriptors: 下级描述符数量,通常至少需要一个报告描述符。

bDescriptorType: 下级描述符类型,例如报告描述符。

wDescriptorLength: 下级描述符长度。

从上面USB鼠标配置描述符中可以看出,该鼠标所遵循的HID协议版本为1.1,有一个HIDclass描述符,描述符类型为0x22,即报告描述符,描述符长度为0x46。

原文地址:http://blog.csdn.net/mcgrady_tracy/

转载于:https://www.cnblogs.com/Daniel-G/p/3993904.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/359560.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是垃圾回收?

以下是我们的垃圾收集手册中的一个示例,该手册将在接下来的几周内发布。 同时,花点时间熟悉垃圾收集的基础知识-这将是本书的第一章。 乍一看,垃圾收集应该处理顾名思义的问题-查找并丢弃垃圾。 实际上,它所做的恰恰相反。 垃圾收…

Extjs弹窗-简单文本编辑框-Ext.Msg.show

var datavalue测试202109;//文本传入数据 Ext.Msg.show({ title:标题, msg:说明, width:600, height:500, prompt:true, multiline:200, closable:true, …

word模板插入文本域并调整表格某一个行的列宽度

一、插入文本域 操作步骤:插入(菜单)->文档部件(菜单)->域(菜单)->邮件合并->输入名称->确认 二、调整word表格某个单元格宽度 选中某行,按住ctrl键的同时&#xf…

java泛型视频教程_Java泛型快速教程

java泛型视频教程泛型是Java SE 5.0引入的一种Java功能,在其发布几年后,我发誓那里的每个Java程序员不仅会听说过,而且已经使用过。 关于Java泛型,有很多免费和商业资源,而我使用的最佳资源是: Java教程 …

Windows上的Oracle Java

我最近为基于Windows 7的笔记本电脑下载了JDK 9的早期访问版本 (内部版本68 )。 由于这是早期版本,因此当自动安装在笔记本电脑上安装主要Java Runtime Environment(JRE)引入了一些不太理想的问题时,我并不…

extjs弹出窗口查看文本内容-new Ext.Window

代码样例&#xff1a; function processscan(){ var text时间 用户 操作<br> 时间 用户 操作<br> 时间 用户 操作; var win new Ext.Window({ layout: fit, width: 700, height: 600, closeAction: hide, dra…

Ioc Autofac心得

对于这个容器注入&#xff0c;个人也不是很熟悉&#xff0c;很多还不懂&#xff0c;只会基本的操作&#xff0c;几天把它记录下来&#xff0c;说不定以后帮助就大了呢&#xff0c;这方面跟安卓差距还是挺大的 下面记录下应用的流程 步骤&#xff1a; 1.添加应用 2.重写工厂&…

深入学习Web Service系列----异步开发模式

概述 在本篇随笔中&#xff0c;通过一些简单的示例来说一下Web Service中的异步调用模式。调用Web Service方法有两种方式&#xff0c;同步调用和异步调用。同步调用是程序继续执行前等候调用的完成&#xff0c;而异步调用在后台继续时&#xff0c;程序也继续执行&#xff0c;不…

navicate导出导入表数据问题

1.导出导入json&#xff0c;如下图&#xff0c;右击表点击导出向导&#xff0c;选择json导出类型&#xff0c;根据提示导出即可。 导入时&#xff0c;右击接收的表&#xff0c;点击导入向导&#xff0c;根据提示即可快速导入&#xff08;注&#xff1a;不同系统之间导出导入易…

tongweb通过控制台简单设置确认相关常用参数

1.环境版本 jdk&#xff0c;tongweb版本确认是否正确 2.检查tongweb的 license是不是永久版本&#xff0c;试用期版本到期会停止服务。 3 JVM运行编码配置-根据系统需要配置 3.1-Dfile.encodingUTF-8 编码根据系统需要配置 4. tongweb运行内存大小--根据系统需要配置 4.1一般 …

编译原理--LL(1)分析法实验C++

一、实验项目要求 1.实验目的 根据某一文法编制调试LL&#xff08;1&#xff09;分析程序&#xff0c;以便对任意输入的符号串进行分析。本次实验的目的主要是加深对预测分析LL&#xff08;1&#xff09;分析法的理解。 2.实验要求 对下列文法&#xff0c;用LL&#xff08;…

实际中进行GC调整

调优垃圾回收与任何其他性能调优活动没有什么不同。 您需要确保了解当前的情况和期望的结果&#xff0c;而不是因为对应用程序的随机部分进行调整而产生了诱惑。 通常&#xff0c;只需执行以下过程即可&#xff1a; 陈述您的绩效目标 运行测试 测量 与目标比较 进行更改并…

达梦数据库出现卡慢简单分析点

1.检查是否有锁表 查询锁表&#xff1a;select sess_id,sql_text from v$sessions sess,v$lock lck where sess.trx_idlck.trx_id and lck.blocked1; --查询僵死会话 解锁&#xff1a;根据会话ID&#xff0c;停止会话 sp_close_session(sess_id); 2.根据v$sessions,V$L…

SEL selector (二)

SEL消息机制工作原理是什么 引用下面文章&#xff1a; 我们在之前有提到,一个类就像一个 C 结构.NSObject 声明了一个成员变量: isa. 由于 NSObject 是所有类的根类,所以所有的对象都会有一个 isa 的成员变量[公共继承].而该 isa 变量指向该对象的类(图3.15)[类在Objective-C中…

mobile cpu上禁用alpha test的相关总结

因为&#xff0c;每家芯片的特性不同&#xff0c;根据向framebuffer写法的不同&#xff0c;分为tile-based的mobile cpu&#xff0c;如ImgTec PowerVR&#xff0c;ARM Mali&#xff0c;一部分老版本Qualcomm Adreno。还有标准的direct&#xff08;immediate&#xff09;的mobil…

达梦定时迁移数据

1. 生成迁移源代码 1.1 启动DM迁移工具&#xff08;bin/dts.exe&#xff09; 1.2 右击迁移管理空白处 -> 新建工程 1.3 展开工程 -> 右击迁移&#xff0c;新建迁移 -> 输入迁移名称&#xff0c;确认 1.4 右击迁移名称&#xff0c;打开 -> 输入源数据库连接信息&…

JSP教程–最终指南

编者注&#xff1a; JavaServer Pages&#xff08;JSP&#xff09;技术使您可以轻松创建同时包含静态和动态组件的Web内容。 JSP技术提供了Java Servlet技术的所有动态功能&#xff0c;但提供了一种更自然的方法来创建静态内容。 JSP技术的主要功能包括用于开发JSP页面的语言&…

tongweb6数据源使用中时常报空异常处理方式

1.在tongweb控制台 -> jdbc配置中设置数据源参数 1.1 勾选空闲超时&#xff0c;时间默认 1.2 勾选泄露超时时间 &#xff0c;时间为半天&#xff08;14400&#xff09; 1.3 勾选连接有效性检查、创建连接验证、获取连接验证、归还连接验证 图中设置泄露超时时间为900…

eclipse远程tomcat javaweb debug样例(windows)

1.tomcat配置可被远程debug端口参数 catalina.bat 中添加 set CATALINA_OPTS-Xdebug -agentlib:jdwptransportdt_socket,servery,suspendn,address8000 导出项目war包到tomcat/webapps/目录下 切换到tomcat/bin目录下 双击startup.bat启动运行项目 2.eclipse中启动远程debug…

ASP.NET MVC的ContentResult

ASP.NET MVC的ContentResult返回简单的纯文本内容&#xff0c;可通过ContentType属性指定应答文档类型&#xff0c;通过ContentEncoding属性指定应答文档的字符编码。一个例子来演习&#xff0c;自定义一个RwResult&#xff0c;它继承ContentResult&#xff0c;为视图象ASP.NET…