USB HID介绍
HID是一种USB通信协议,无需安装驱动就能进行交互,在学习HID之前,先来复习一下USB协议的相关内容。
USB设备描述符-概述
当插入USB设备后,主机会向设备请求各种描述符来识别设备。那什么是设备描述符呢?
Descriptor即描述符,是一个完整的数据结构,可以通过C语言等编程实现,并存储在USB设备中,用于描述一个USB设备的所有属性,USB主机是通过一系列命令来要求设备发送这些信息的。
描述符的作用就是通过命令操作来给主机传递信息,从而让主机知道设备具有什么功能、属于哪一类设备、要占用多少带宽、使用哪类传输方式及数据量的大小,只有主机确定了这些信息之后,设备才能真正开始工作。
USB有那些标准描述符?
USB有5种标准描述符:设备描述符 、配置描述符、字符描述符、接口描述符、端点描述符 。
描述符之间有一定的关系,一个设备只有一个设备描述符,而一个设备描述符可以包含多个配置描述符,而一个配置描述符可以包含多个接口描述符,一个接口使用了几个端点,就有几个端点描述符。由此我们可以看出,USB的描述符之间的关系是一层一层的,最上一层是设备描述符,下面是配置描述符,再下面是接口描述符,再下面是端点描述符。在获取描述符时,先获取设备描述符,然后再获取配置描述符,根据配置描述符中的配置集合长度,一次将配置描述符、接口描述符、端点描述符一起一次读回。其中可能还会有获取设备序列号,厂商字符串,产品字符串等。
设备描述符
struct _DEVICE_DEscriptOR_STRUCT
{
BYTE bLength; //设备描述符的字节数大小
BYTE bDescriptorType; //描述符类型编号,为0x01
WORD bcdUSB; //USB版本号
BYTE bDeviceClass; //USB分配的设备类代码,0x01~0xfe为标准设备类,0xff为厂商自定义类型,0x00不是在设备描述符中定义的,如HID
BYTE bDeviceSubClass; //usb分配的子类代码,同上,值由USB规定和分配的,HID设备此值为0
BYTE bDeviceProtocl; //USB分配的设备协议代码,同上HID设备此值为0
BYTE bMaxPacketSize0; //端点0的最大包的大小
WORD idVendor; //厂商编号
WORD idProduct; //产品编号
WORD bcdDevice; //设备出厂编号
BYTE iManufacturer; //描述厂商字符串的索引
BYTE iProduct; //描述产品字符串的索引
BYTE iSerialNumber; //描述设备序列号字符串的索引
BYTE bNumConfiguration; //可能的配置数量
}
配置描述符
struct _CONFIGURATION_DEscriptOR_STRUCT
{
BYTE bLength; //配置描述符的字节数大小
BYTE bDescriptorType; //描述符类型编号,为0x02
WORD wTotalLength; //配置所返回的所有数量的大小
BYTE bNumInterface; //此配置所支持的接口数量
BYTE bConfigurationVale; //Set_Configuration命令需要的参数值
BYTE iConfiguration; //描述该配置的字符串的索引值
BYTE bmAttribute; //供电模式的选择
BYTE MaxPower; //设备从总线提取的最大电流
}
字符描述符
struct _STRING_DEscriptOR_STRUCT
{
BYTE bLength; //字符串描述符的字节数大小
BYTE bDescriptorType; //描述符类型编号,为0x03
BYTE SomeDescriptor[36]; //UNICODE编码的字符串
}
接口描述符
struct _INTERFACE_DEscriptOR_STRUCT
{
BYTE bLength; //接口描述符的字节数大小
BYTE bDescriptorType; //描述符类型编号,为0x04
BYTE bInterfaceNunber; //接口的编号
BYTE bAlternateSetting;//备用的接口描述符编号
BYTE bNumEndpoints; //该接口使用端点数,不包括端点0
BYTE bInterfaceClass; //接口类型 HID设备此值为0x03
BYTE bInterfaceSubClass;//接口子类型 HID设备此值为0或者1
BYTE bInterfaceProtocol;//接口所遵循的协议
BYTE iInterface; //描述该接口的字符串索引值
}
端点描述符
struct _ENDPOIN_DEscriptOR_STRUCT
{
BYTE bLength; //端点描述符的字节数大小
BYTE bDescriptorType; //描述符类型编号,为0x05
BYTE bEndpointAddress; //端点地址及输入输出属性
BYTE bmAttribute; //端点的传输类型属性
WORD wMaxPacketSize; //端点收、发的最大包的大小
BYTE bInterval; //主机查询端点的时间间隔
}
HID设备描述符
温习了以上内容,我们再来看看HID协议与这些描述符之间的关系。
当插入USB设备后,主机会向设备请求各种描述符来识别设备。
为了把一个设备识别为HID类别,设备在定义描述符的时候必须遵守HID规范。
从框图中,可以看出除了USB标准定义的一些描述符外,HID设备还必须定义HID描述符。另外设备和主机的通信是通过报告的形式来实现的,所以还必须定义报告描述符;而物理描述符不是必需的。还有就是HID描述符是关联于接口(而不是端点)的,所以设备不需要为每个端点都提供一个HID描述符。
接口描述符中bInterfaceClass的值必须为0x03,bInterfaceSubClass的值为0或1,为1表示HID设备符是一个启动设备(Boot Device,一般对PC机而言才有意义,意思是BIOS启动时能识别并使用您的HID设备,且只有标准鼠标或键盘类设备才能成为Boot Device。如果为0则只有在操作系统启动后才能识别并使用您的HID设备)。
USB HID类描述符的结构 |
||||
偏移量 |
域 |
大小 |
值 |
描述 |
0 |
bLength |
1 |
数字 |
此描述符的长度(以字节为单位) |
1 |
bDescriptorType |
1 |
常量 |
描述符种类(此处为0x21即HID类描述符) |
2 |
bcdHID |
2 |
数字 |
HID规范版本号(BCD码),采用4个16进制的BCD格式编码,如版本1.0的BCD码为0x0100,版本为1.1的BCD码为0x0110 |
4 |
bCountryCode |
1 |
数字 |
硬件目的国家的识别码(BCD码)(见表3) |
5 |
bNumDescritors |
1 |
数字 |
支持的附属描述符数目 |
6 |
bDescriptorType |
1 |
常量 |
HID相关描述符的类型 0x21:HID描述符 0x22:报告描述符 0x23:物理描述符 |
7 |
wDescriptorLength |
2 |
数字 |
报告描述符总长度 |
9 |
bDescriptorType |
1 |
常量 |
用于识别描述符类型的常量,使用在有一个以上描述符的设备 |
10 |
wDescriptorLength |
2 |
数字 |
描述符总长度,使用在有一个以上描述符的设备 |
报告描述符
报告描述符比较复杂,它是以item形式排列组合而成,无固定长途,用户可以自定义长度以及每一bit的含义。item类型分三种:main,global和local,其中main类型又可分为5种tag:
项目分成三种类别:主项目,全局项目,区域项目。主项目中的 input,ouput,feature三个卷标用来表示报告中数据的种类,这些是报告描述符中最主要的项目,其他项目都是用来修饰这三种项目。主要项目中其他二个卷标后面再作详细的介绍。
>> Input 项:表示设备操作输入到主机的数据模式。这个数据格式就形成一个输入报告,虽然输入报告可以用控制型管线以get report(input)来传输,但是通常用中断型输入管线来传输以确保在每一固定周期内都能将更新的输入报告传给主机。
>> Output 项:表示由主机输出到装置操作的数据格式。这个数据格式就形成一个输出报告。输出报告通常不适用轮询的方式来传送给设备,而是由应用软件依实际需求以传令方式要求送出输出报告,所以大多用控制型管线以set report(output)指令来将报告送到设备。当然也可以选择用中断型输出管线来传送,只是通常不建议这样用。
>> Feature 项:表示由主机送到设备的组态所需数据的数据格式。这个数据模式就形成一个特征报告。特征报告只能用控制型管线以get report(feature)和set report(feature)指令分别来取得和设定设备的特征值
主项目用来定义报告中数据的种类和格式,而说明主项目之意义与用途为全局项目和区域项目。顾名思义,区域性项目只能适用于列于其下的第一个主项目,不适用于其他主项目,若一个主项目之上有几个不同的卷标的区域性项目,则这些区域性项目皆适用于描述该主项目。相反,全局性项目适用于其下方的所有主项目,除非另一个相同卷标的全局性项目出现!!!
Report descriptors are composed of pieces of information. Each piece of information is called an Item.
报告描述符由一些数据片组成。这些数据片被叫做Item。
All items have a one-byte prefix that contains the item tag, item type, and item size.
每一个Item都包含一个字节的前缀,这个前缀中包含了三个信息--item tag,、item type、item size。
An item may include optional item data。
Item可以包含一个可选的数据段。
The size of the data portion of an item is determined by its fundamental type.
Item的数据部分的长度取决于Item的基本类型。
There are two basic types of items: short items and long items.
Item有两种基本类型:short items and long item。
There are three categories of short item tags: Main, Global, and Local.
short item 的 item tags 有三种类型:Main, Global, and Local.
Main items: </center>
Main items are used to either define or group certain types of data fields within a Report descriptor. There are two types of Main items: data and non-data. Data-type Main items are used to create a field within a report and include Input, Output, and Feature. Other items do not create fields and are subsequently referred to as non-data Main items.
好了,到此我们应该可以对照实际应用的报告描述符,寻找其中的 Main items了。
至此我们已经可以明白报告描述符中的几个MAIN Item的意义,接下来继续看Global Item 和 Local Item.
Global Item: </center>
Global items describe rather than define data from a control. A new Main item assumes the characteristics of the item state table. Global items can change the state table. As a result Global item tags apply to all subsequently defined items unless overridden by another Global item.
(原文件名:Global Item.jpg)
至此我们已经可以明白报告描述符中的几个Global Item的意义
Local Item: </center>
Local item tags define characteristics of controls. These items do not carry over to the next Main item. If a Main item defines more than one control, it may be preceded by several similar Local item tags. For example, an Input item may have several Usage tags associated with it, one for each control.
item的数据格式有两种,分别是短item和长item。
短item格式
bSize |
0:0个字节 1:1个字节 2:2个字节 3:4个字节 |
bType |
0:main 1:global 2:local 3:保留 |
bTag |
item类型 8:input 9:output A:collection B:feature C:end collection |
长item,其bType位值为3,bTag值为F
bDataSize |
0:0个字节 1:1个字节 2:2个字节 3:4个字节 |
bLongItemTag |
0:main 1:global 2:local 3:保留 |
data | 数据 |
HID设备6种特定请求
HID类请求(命令)包格式 |
|||
偏移量 |
域 |
大小 |
说明 |
0 |
bmRequestType |
1 |
HID设备类请求特性如下: 因而,针对HID的设备类请求,仅仅10100001和00100001有效 |
1 |
bRequest |
1 |
HID类请求(参考下表) |
2 |
wValue |
2 |
高字节说明描述符的类型 0x21:HID描述符 0x22:报告描述符 0x23:物理描述符 低字节为非0值时被用来选定实体描述符。 |
4 |
wIndex |
2 |
2字节数值,根据不同的bRequest有不同的意义 |
6 |
wLength |
2 |
该请求的数据段长度 |
HID类请求 |
||
数值 |
HID类请求描述符 |
注释 |
0x01 |
GET_REPORT |
主机用控制传输从设备接收数据,所有HID类设备都要支持这个请求; |
0x02 |
GET_IDLE |
主机读取设备当前的空闲速率,设备可以不支持此请求; |
0x03 |
GET_PROTOCOL |
仅仅适应于支持启动功能的HID设备(Boot Device) |
0x09 |
SET_REPORT |
设备用控制传输接收主机的数据,设备可以不支持此请求; |
0x0A |
SET_IDLE |
设置闲置状态,设备可不支持此请求; |
0x0B |
SET_PROTOCOL |
仅仅适应于支持启动功能的HID设备(Boot Device) |
GET_REPORT:主机通过控制端点获取一个Report
域 |
值 |
描述 |
bmRequestType |
0xA1 |
|
bRequest |
0x01 |
|
wValue |
高字节表示报告类型 0x01:input 0x02:output 0x03:feature other:reserved 低字节表示ReportID,如不使用设为0 |
|
wIndex |
HID的interface索引值 |
|
wLength |
Report长度 |
|
Data |
Report内容 |
SET_REPORT:主机发送一个Report给设备,用以设置input,output或者feature
域 |
值 |
描述 |
bmRequestType |
0x21 |
|
bRequest |
0x09 |
|
wValue |
高字节表示报告类型 0x01:input 0x02:output 0x03:feature other:reserved 低字节表示ReportID,如不使用设为0 |
|
wIndex |
HID的interface索引值 |
|
wLength |
Report长度 |
|
Data |
Report内容 |
GET_IDLE
域 |
值 |
描述 |
bmRequestType |
0xA1 |
|
bRequest |
0x02 |
|
wValue |
高字节0 低字节表示ReportID,如不使用设为0 |
|
wIndex |
HID的interface索引值 |
|
wLength |
1 |
|
Data |
空闲速率 |
SET_IDLE
域 |
值 |
描述 |
bmRequestType |
0x21 |
|
bRequest |
0x0A |
|
wValue |
新的速率 低字节表示ReportID,如不使用设为0 |
|
wIndex |
HID的interface索引值 |
|
wLength |
0 |
|
Data |
无 |
GET_PROTOCOL
域 |
值 |
描述 |
bmRequestType |
0xA1 |
|
bRequest |
0x03 |
|
wValue |
0 |
|
wIndex |
HID的interface索引值 |
|
wLength |
1 |
|
Data |
0 = Boot Protocol 1 = Report Protocol |
SET_PROTOCOL
域 |
值 |
描述 |
bmRequestType |
0x21 |
|
bRequest |
0x0B |
|
wValue |
0 = Boot Protocol 1 = Report Protocol |
|
wIndex |
HID的interface索引值 |
|
wLength |
0 |
|
Data |
无 |
USB HID介绍的更多相关文章
- USB HID介绍【转】
本文转载自:http://blog.csdn.net/leo_wonty/article/details/6721214 HID是一种USB通信协议,无需安装驱动就能进行交互,在学习HID之前,先来复 ...
- USB HID描述符【转】
本文转载自: USB是个通用的总线,端口都是统一的.但是USB设备却各种各样,例如USB鼠标,USB键盘,U盘等等,那么USB主机是如何识别出不同的设备的呢?这就要依赖于描述符了.USB的描述符主要有 ...
- USB HID报告及报告描述符简介
在USB中,USB HOST是通过各种描述符来识别设备的,有设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符,报告描述符等等.USB报告描述符(Report Descriptor)是HID ...
- PIC32MZ 通过USB在线升级 -- USB HID bootloader
了解 bootloader 的实现, 请加QQ: 1273623966(验证填bootloader); 欢迎咨询或定制bootloader; 我的博客主页 www.cnblogs.com/geekyg ...
- USB HID设备报告描述符详解(转)
转自:http://group.ednchina.com/93/198.aspx. 参考:USB HID usage table 概述: 报告在这里意思是数据传输(data transfer),而 ...
- 浅析USB HID ReportDesc (HID报告描述符)
在USB中,USB Host是通过各种描述符来识别识别设备的,一般在设备枚举的过程将会获取有设备描述符/配置描述符/接口描述符/端点描述符/字符串描述符等 现在我们来介绍一下HID ReportDes ...
- STC8H开发(九): STC8H8K64U模拟USB HID外设
目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...
- C#与USB HID间的通信
原文:C#与USB HID间的通信 C#与USBHID接口的通讯相对于与串口间的通讯较为复杂,其中需要多次调用到Windows的一些API.其原理编者尚未全部理清,以下提供简单的USBHID通讯流程. ...
- C# 访问USB(HID)设备
原文:C# 访问USB(HID)设备 二话不说,直接给代码,如果您真想做这方面的东西,还是稍微研究下,没有现成的好类用,就需要自己了解其原理 //引用空间 using System; using Sy ...
随机推荐
- Android 如何调用自写APK和非自写APK
由于项目需要,调用一个现成的APK,总结之余,顺便把怎么调用自写APK的方法也写上,以做比较 1.如何调用现成的APK: 先上调用代码,然后再一一解释: Intent mIntent = new In ...
- 营配数据质量核查,关于营销mis系统与配电gis系统里面的sql语句查询,做为积累使用,下次就不用重复写同样的语句了。
1.配电gis线路导出数据: select r.name 线路名称,r.run_status 运行状态,r.voltage_level 电压等级,r.manager_depart 管理部门,r.bel ...
- 将图片转换为Base64
string Imagefilename 硬盘路径 protected string ImgToBase64String(string Imagefilename) { try { Bitmap ...
- JQuery 表单验证--jquery validation
jquery validation,表单验证控件 官方地址 :http://jqueryvalidation.org/ jquery表单验证 默认值校验规则 jquery表单验证 默认的提示 < ...
- c++模板类被继承时他的成员不能被子类看到
c++模板类被继承时他的成员不能被子类看到,必须用限定的符号 this->foo 或者 baseclass::foo,或者using bassclass::foo. msvc不提示错误,gcc ...
- PLSQL developer连接不上64位Oracle的解决方法
PLSQL developer连接不上64位Oracle的解决方法 64位下装Oracle 11g 64位,PLSQL Developer使用出现问题. 问题描述: 登录对话框中,数据库下拉框为空: ...
- token验证 sae
在微信平台中修改服务器设置时,使用微信Demo的php,刚开始一直验证token 失败 解决办法 :在echo $echoStr;之前添加header('content-type:text');一句这 ...
- jquery mobile将页面内容当成弹框进行显示
注:必须使用相对应版本的jquery mobile css.不然无法正常显示 <div data-role="page" id="pageone"> ...
- 关于PHP伪静态Rewrite设置
Rewirte主要的功能就是实现URL的跳转和隐藏真实地址,基于Perl语言的正则 表达式规范.平时帮助我们实现拟静态,拟目录,域名跳转,防止盗链等 一.Apache配置: 1.支持httpd ...
- Mysql删除表名中有特殊字符的表
由于公司业务和应用的调整,之前在Mysql中的很多表都不需要了,故需要对数据库进行整理. 刚开始,我在想:不就删除一些表吗?很好解决,写个简单的脚本就可以了.我先看了数据库中有80000多个表,很 ...