USBHID设备报告描述符详解
HID报告描述符
基于HID 类的USB 人机接口设计作者:北京交通大学 涂晓强 周洪利 来源:本站原创 点击数:235 更新时间:2007-11-27您可以添加到网摘 让更多人关注此文章:目前市场上USB 设备的种类繁多,但是这些设备会有一些共同的特性,根据这些特性可以把USB 设备划分为不同的类,如显示设备、通信设备、音频设备、大容量存储设备、人机接口设备(HID )。
这里介绍如何实现HID 类设备,以及如何在应用程序中对HID 类设备进行访问。
从Windows98操作系统开始,为HID 类设备提供了通用的驱动程序,所以只要按照HID 设备类的规范编写设备的固件程序,就能够让Windows 系统自动识别设备,省去了复杂的驱动程序编写过程。
1 HID 协议简介人机接口设备(HID )主要是指一些人与计算机进行交互的设备,如键盘、鼠标、游戏杆等;但是HID 设备不一定非要是这些人机交互设备,只要符合HID 设备级定义规范要求的都可以认为是HID 设备。
HID 设备有以下主要特点:① 交换的数据存储在报告的结构内,设备必须支持HID 报告格式。
② 每笔事务可以携带小量或中量的数据。
低速设备每笔事务最大为8字节,全速设备每笔最大为64字节,高速设备最大为1 024字节;③ 有最大传输速度的限制。
低速设备最快10 ms 一笔事务,最高速度为800 B/s ;全速设备最快1 ms 一笔事务,最高速度为64 KB/s ;高速设备最快125 μs 一笔事务,最高速度为24.576 MB/s 。
④ 没有传输速度的保证。
当插入USB 设备后,主机会向设备请求各种描述符来识别设备。
为了把一个设备识别为HID 类别,设备在定义描述符的时候必须遵守HID 规范。
图1显示了HID 各种描述符之间的关系。
事实上,每个设备可以有多个接口描述符来实现多接口设备,而且每个接口描述符下应该有多个端点描述符。
图1 HID各种描述符之间的关系从图1中可以看出,除了USB标准定义的一些描述符外,HID设备还必须定义HID描述符。
hid类键盘的报告描述符的理解
USB学习小记-HID类键盘的报告描述符的理解前言断断续续的学习了将近三个月,才把USB的HID类搞明白,速度真是够慢的。
利用晚上+周末的时间学习自己的东西确实是必要的,不过效率是有点低,以后要更专注一些才行,希望自己能做到吧。
在学习过程中,刚开始主要参考了周立功编写的一本《PDIUSBD12 USB 固件编程与驱动开发》,后面的学习主要参考电脑圈圈的资料包,包括里面的HID类的英文协议文档,还有一位台湾前辈几年前写的几篇文章,还有网络下有下得到的一些例程。
在此感谢各位大虾前辈的分享。
一、学习流程1,先大致看下USB1.1中文版的协议(就是网上能找到的翻译版),先了解一下USB1.1的工作流程(可能此时的你会对其中很多内容都很含糊,不过没关系,请坚持!);2,选择一款最常用的USB芯片,比如我选择的NXP的PDIUSBD12.有很多使用该芯片的源码可以在上网搜索得到,而且周立功公司为其写了一本书,前面的章节对USB的工作流程作了一个简单而又清晰的讲解,而不致让人陷入协议的海洋里;3,有了对USB1.1协议的大致了解,选好了开发的平台(我刚好手上有一块周立功公司的EASEARM2200的开发板,上面有D12)之后,先跑一下附带的例程(此开发板配套的例程是基于UCOS2系统的,刚开始用它来参考肯定晕)。
没有能跑的例程,那就上网找一下经验证的例程,比如电脑圈圈在EDNCHINA建立的USB学习小组里有很好的几个例程,而且都是基于51+D12的,所以极具参考价值。
我是参考周立功公司出的那本书来学习的,电脑圈圈的例程与此书的例子书写风格较相似,所以可以互相参考。
如果也没有开发板,那可购买一套电脑圈圈他们搞活动的套件或者直接用51+D12自己搭一下,这样就可以直接用电脑圈圈写的例程了,可以避免走很多弯路。
4,有了例程的直观印象后,此时可以上BUS HOUND5.0了。
此软件可以观察到USB设备与主机(PC)之间的通讯数据,特别那11个标准请求的理解,通过此软件的观察,可以更好理解其相互之间是如何完成这个握手枚举过程的。
USB_HID设备报告描述符详解
概述报告在这里意思是数据传输(data transfer),而报告描述符是对这些传输的数据作用途(usage)上的说明。
USB通讯协议的规范是以1ms产生一个USB 帧(frame),USB设备可以每一个帧中发送和接收一个交换(transaction)。
交换是由几个封包(packet)组成,而传输是由一个或几个交换来完成传送一口中有效的数据。
在这里,传输和报告的意思相类似。
传输方式有四种,初始学一般只要了解控制型传输(control transfer)和中断型传输(interrupt transfer)即可。
控制型传输是当需要时才执行传输要求,是最一般的传输方式,组态、命令和状态的通讯都可以使用控制型传输;控制型传输主要用于消息型数据(message-type data)。
中断型传输目的在做重复的数据更新(recurring data)传输,精确一点而言,即是在每个有限有周期内(bounded period)作至少一次的小量数据发送或接收;所以适用于流动型数据(stream-type data),注意这里所谓的周期时间就是在端点描述符中的轮询间隔时间。
报告有三种:input,output,和Feature.后面将作进一步介绍。
中断型输入管线(interrupt in pipe)仅可以传送input报告;中断型输出管线(interrupt out pipe)仅可以传送output报告;但是控制型管线(control pipe)可以传送input,output和feature报告。
端点描述符有声明所使用的端点为何种管线。
数据本身没有任何意义,要赋于用途才能明确其为控制什么(control);例如设备上的按钮指示灯和X与Y轴的位移等都通称控制,数据则为按钮和指示灯的开关状态或X与Y轴的位移量。
为了这个目的应运而生报告描述符,其将数据的操控与它的用途作一对一的对应,所以解读报告后就可以知道每个数据作何种操作。
USBHID协议详情
USB HID类设备属于人机交互操作的设备,是一个比较大的类,用于控制计算机操作的某些方面,如USB鼠标、USB键盘、USB游戏操作杆、USB触摸板、USB轨迹球、电话拨号设备、VCR遥控等等设备。
另外,使用HID设备的一个好处就是操作系统自带了HID类的驱动程序,用户无需开发很麻烦的驱动程序,只有直接使用API调用即可完成通信,所有很多简单的USB设备喜欢枚举成HID设备,这样就可以不用安装驱动而直接使用。
1、HID设备描述符当插入USB设备后,主机会向设备请求各种描述符来识别设备。
为了把一个设备识别为HID类,设备在定义描述符的时候必须遵守HID规范。
HID设备的描述符除了5个USB的标准描述符(设备描述符、配置描述符、接口描述符、端点描述符、字符串描述符)外,还包括3个HID设备类特定描述符:HID描述符、报告描述符、物理描述符。
HID描述符是关联于接口(而不是端点)的,所以设备不需要为每个端点都提供一个HID描述符。
设备和主机的通信是通过报告的形式来实现的。
而物理描述符不是必需的。
5个标准描述符中与HID设备有关的部分有:设备描述符中bDeviceClass、bDeviceSubClass和bDeviceProtocol三个字段的值必须为0。
接口描述符中bInterfaceClass的值必须为0x03,bInterfaceSubClass的值为0或1,为1表示HID设备是一个启动设备(BootDevice,一般对PC机而言才有意义,意思是BIOS启动时能识别并使用您的HID设备,且只有标准鼠标或键盘类设备才能成为Boot Device。
如果为0则只有在操作系统启动后才能识别并使用您的HID设备)。
HID接口描述符中bInterfaceProtocol的含义bInterfaceProtocol的取值含0 NO1 键2 鼠3~255 保1.1 HID描述符HID描述符关联于接口描述符,因而如果一个设备只有一个接口描述符,则无论它有几个端点描述符,HID设备只有一个HID描述符。
在USB中_USB_HOST是通过各种描述符来识别设备的
USB HID报告及报告描述符简介在USB中,USB HOST是通过各种描述符来识别设备的,有设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符,报告描述符等等。
USB报告描述符(Report Descriptor)是HID设备中的一个描述符,它是比较复杂的一个描述符。
USB HID设备是通过报告来给传送数据的,报告有输入报告和输出报告。
输入报告是USB设备发送给主机的,例如USB鼠标将鼠标移动和鼠标点击等信息返回给电脑,键盘将按键数值数据返回给电脑等;输出报告是主机发送给USB 设备的,例如键盘上的数字键盘锁定灯和大写字母锁定灯等。
报告是一个数据包,里面包含的是所要传送的数据。
输入报告是通过中断输入端点输入的,而输出报告有点区别,当没有中断输出端点时,可以通过控制输出端点0发送,当有中断输出端点时,通过中断输出端点发出。
而报告描述符,是描述一个报告以及报告里面的数据是用来干什么用的。
通过它,USB HOST可以分析出报告里面的数据所表示的意思。
它通过控制输入端点0返回,主机使用获取报告描述符命令来获取报告描述符,注意这个请求是发送到接口的,而不是到设备。
一个报告描述符可以描述多个报告,不同的报告通过报告ID来识别,报告ID在报告最前面,即第一个字节。
当报告描述符中没有规定报告ID时,报告中就没有ID字段,开始就是数据。
更详细的说明请参看USB HID协议,该协议可从下载。
USB报告描述符可以通过使用HID Descriptor tool来生成,这个工具可以到下载,为了方便大家,我顺便上传了一份。
下面通过由HID Descriptor tool生成的USB鼠标和USB键盘来说明一下报告描述符和报告。
code char KeyBoardReportDescriptor[63] = {5A5A5A7f1.1.0CTL a3 00 00 00 01 00 04 00 GET STATUS 17usDI 01 01 01 00 .... 27u sCTL 23 01 10 00 01 00 00 00 CLEAR FEATUR E 110usCTL a3 00 00 00 01 00 04 00 GET STATUS 56usDI 01 01 00 00 .... 14u sCTL 23 03 04 00 01 00 00 00 SET FEATURE 109msDI 02 . 90ms CTL a3 00 00 00 01 00 04 00 GET STATUS 23usDI 03 01 10 00 .... 22u sCTL 23 01 14 00 01 00 00 00 CLEAR FEATUR E 8usCTL a3 00 00 00 01 00 04 00 GET STATUS 19msDI 03 01 00 00 .... 34us ......!.... 67msCTL a3 00 00 00 01 00 04 00 GET STATUS 49usDI 03 01 00 00 .... 27us CTL 23 03 04 00 01 00 00 00 SET FEATURE 24usDI 02 . 112ms CTL a3 00 00 00 01 00 04 00 GET STATUS 21usDI 03 01 10 00 .... 25us CTL 23 01 14 00 01 00 00 00 CLEAR FEATUR E 8us......!.... 75ms02 01 .. ...... 50msCTL a3 00 00 00 02 00 04 00 GET STATUS 214msDI 00 01 00 00 .... 34us ......!.... 67ms02 01 .. ...... 50ms............. 83ms50 00 07 05 82 02 40 00 00 07 05 02 02 40 00 00 P..... @......@..45ms.. 53ms46ms70ms32 00 2.53ms.......00 00 00 24 00 00 00 00 00 00 00 00 00 00 00 ... $...........以下是我在做USB键盘时,通过串口发回的调试信息,从这也可以看到枚举的过程。
USB HID报告及报告描述符简介
在USB中,USB HOST是通过各种描述符来识别设备的,有设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符,报告描述符等等。
USB报告描述符(Report Descriptor)是HID设备中的一个描述符,它是比较复杂的一个描述符。
USB HID设备是通过报告来给传送数据的,报告有输入报告和输出报告。
输入报告是USB设备发送给主机的,例如USB鼠标将鼠标移动和鼠标点击等信息返回给电脑,键盘将按键数据数据返回给电脑等;输出报告是主机发送给USB设备的,例如键盘上的数字键盘锁定灯和大写字母锁定灯等。
报告是一个数据包,里面包含的是所要传送的数据。
输入报告是通过中断输入端点输入的,而输出报告有点区别,当没有中断输出端点时,可以通过控制输出端点0发送,当有中断输出端点时,通过中断输出端点发出。
而报告描述符,是描述一个报告以及报告里面的数据是用来干什么用的。
通过它,USB HOST可以分析出报告里面的数据所表示的意思。
它通过控制输入端点0返回,主机使用获取报告描述符命令来获取报告描述符,注意这个请求是发送到接口的,而不是到设备。
一个报告描述符可以描述多个报告,不同的报告通过报告ID来识别,报告ID在报告最前面,即第一个字节。
当报告描述符中没有规定报告ID时,报告中就没有ID字段,开始就是数据。
更详细的说明请参看USB HID协议,该协议可从下载。
USB报告描述符可以通过使用HID Descriptor tool来生成,这个工具可以到下载,为了方便大家,我顺便上传了一份。
/Upload/Blog/2007/4/2/af7c3443-ad61-4465-ADC7-a74d28bbc322.zip下面通过由HID Descriptor tool生成的USB鼠标和USB键盘来说明一下报告描述符和报告。
code char KeyBoardReportDescriptor[63] = {//表示用途页为通用桌面设备0x05, 0x01, // USAGE_PAGE (Generic Desktop)//表示用途为键盘0x09, 0x06, // USAGE (Keyboard)//表示应用集合,必须要以END_COLLECTION来结束它,见最后的END_COLLECTION 0xa1, 0x01, // COLLECTION (Application)//表示用途页为按键0x05, 0x07, // USAGE_PAGE (Keyboard)//用途最小值,这里为左ctrl键0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)//用途最大值,这里为右GUI键,即window键0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)//逻辑最小值为00x15, 0x00, // LOGICAL_MINIMUM (0)//逻辑最大值为10x25, 0x01, // LOGICAL_MAXIMUM (1)//报告大小(即这个字段的宽度)为1bit,所以前面的逻辑最小值为0,逻辑最大值为10x75, 0x01, // REPORT_SIZE (1)//报告的个数为8,即总共有8个bits0x95, 0x08, // REPORT_COUNT (8)//输入用,变量,值,绝对值。
HID 报告描述符终极解析
USB HID Report终极解析 HID的报告描述符巨难懂,关键是数据格式与每一位代表的意思。
经过三天的研究,终于将HID Report的每一个数据位的含义弄清楚了,现将数据解析如下,最后附上了一个HID 通信的Report例子。
以一个键盘的HID Report为例:键盘的HID报告描述符:code char KeyBoardReportDescriptor[63] = {0x05, 0x01, // USAGE_PAGE (Generic Desktop)0x09, 0x06, // USAGE (Keyboard)0xa1, 0x01, // COLLECTION (Application)0x05, 0x07, // USAGE_PAGE (Keyboard)0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)0x15, 0x00, // LOGICAL_MINIMUM (0)0x25, 0x01, // LOGICAL_MAXIMUM (1)0x75, 0x01, // REPORT_SIZE (1)0x95, 0x08, // REPORT_COUNT (8)0x81, 0x02, // INPUT (Data,V ar,Abs)0x95, 0x01, // REPORT_COUNT (1)0x75, 0x08, // REPORT_SIZE (8)0x81, 0x03, // INPUT (Cnst,V ar,Abs)0x95, 0x05, // REPORT_COUNT (5)0x75, 0x01, // REPORT_SIZE (1)0x05, 0x08, // USAGE_PAGE (LEDs)0x19, 0x01, // USAGE_MINIMUM (Num Lock)0x29, 0x05, // USAGE_MAXIMUM (Kana)0x91, 0x02, // OUTPUT (Data,V ar,Abs)0x95, 0x01, // REPORT_COUNT (1)0x75, 0x03, // REPORT_SIZE (3)0x91, 0x03, // OUTPUT (Cnst,V ar,Abs)0x95, 0x06, // REPORT_COUNT (6)0x75, 0x08, // REPORT_SIZE (8)0x15, 0x00, // LOGICAL_MINIMUM (0)0x25, 0xFF, // LOGICAL_MAXIMUM (255)0x05, 0x07, // USAGE_PAGE (Keyboard)0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)0x81, 0x00, // INPUT (Data,Ary,Abs)0xc0 // END_COLLECTION};具体分析如下:code char KeyBoardReportDescriptor[63] = {0x05, 0x01, // USAGE_PAGE (Generic Desktop)// 分析根据HID短项目数据格式短项目的编码形式如下:0x05 = 0000 01010000:Usage Page01:bType,全局(bType = 0:主项目;bType = 1:全局项目;bType = 2:区域项目;)01:bSize,1字节(BSize 用来指出项目的数据所需字节的数目,该数目仅可以为0(当bSize=0),1(当bSize=1),2(当bSize=2),和4(当bSize=3)﹔注意不可以为3个字节。
hid协议报告描述总结
HID报告描述符主要内容整理刚刚接触USB(HID)时对【报告描述符】感到难于理解,因此就更无从下手。
下面根据2个主要的协议文本整理出一些常用信息,不完整,备忘。
●主要参考文本:⏹【协议文本1】:《Device Class Definition for Human Interface Devices(HID)》Ver1.11⏹【协议文本2】:《Universal Serial Bus HID Usage Tables》Ver1.12每个协议文本后面的附录都有很多例子可供参考借鉴。
0、主要术语与概念(1)报告(Report):HID设备与主机交换信息的单位(报告字节数似乎没有限制);(2)报告描述符(Report Description):用许多【项目】说明报告的格式与【用途】;(3)用途(Usage):用于指出报告中某个数据域的意义或目的,32bit。
高16bit用途页(Usage Page)指出用途的大类,低16bit用途ID(Usage ID)指出用途大类下的子用途;(4)项目(Item):报告描述符用于说明数据域的某种属性的数据,有短项目和长项目之分,短项目1~5B,长项目3~255B;(5)共有3种类型的项目:主项目、全局项目(Global)、局部项目(Local);(6)主项目(Main Item)共有5个,其中的Input、Output和Feature会产生实际的数据域并附带说明其操作特性(见2.1);其余2个Collection和End Collection 是一对括号,其间的内容构成一个【集合】,用于限定集合中信息的整体特性;(7)全局项目(Global Item):说明其后主项目产生的数据域的某方面特性,一旦说明一直有效,除非遇到一个新的全局项目说明改变其值;(8)局部项目(Local Item):说明其后主项目产生的数据域的某方面特性,但只对其后的一个主项目有效;(9)可以认为所有用【全局项目】说明的各种数据域特性构成一个【全局状态表】,随着新的【全局项目】出现,该表在不断变化。
STM32 USB HID详解
STM32 USB HID详解1、USB简介2、USB描述符USB只是一个总线,只提供一个数据通路而已。
USB总线驱动程序并不知道一个设备具体如何操作,有哪些行为。
具体的一个设备实现什么功能,要由设备自己来决定。
那么,USB主机是如何知道一个设备的功能以及行为呢?这就要通过描述符来实现了。
描述符中记录了设备的类型、厂商ID和产品ID(通常依靠它们来加载对应的驱动程序)、端点情况、版本号等众多信息。
标准的USB设备有5种USB描述符:设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符。
下面详解:2.1、设备描述符一个USB设备只有一个设备描述符。
设备描述符主要记录的信息有:设备所使用的USB协议版本号、设备类型、端点0的最大包大小、厂商ID(VID)和产品ID(PID)、设备版本号、厂商字符串索引、产品字符串索引、设备序列号索引、可能的配置数等。
设备描述符里决定了该设备有多少种配置,每种配置都有一个配置描述符。
配置描述符主要记录的信息有:配置所包含的接口数、配置的编号、供电方式、是否支持远程唤醒、电流需求量等。
2.3、接口描述符在每个配置描述符中又定义了该配置有多少个接口,每个接口都有一个接口描述符。
接口描述符主要记录的信息有:接口的编号、接口的端点数、接口所使用的类、子类、协议等。
2.4、[类描述符]该描述符不是必须的,如果配置的USB类型有类特殊描述符(如HID类),它跟在相应的接口描述符之后。
在接口描述符里又定义了该接口有多少个端点,每个端点都有一个端点描述符。
端点描述符主要记录的信息有:端点号及方向、端点的传输类型、最大包长度、查询时间间隔等。
2.6、[字符串描述符]字符串描述符主要是提供一些方便人们阅读的信息,它不是必需的。
3、USB HID为了把一个设备识别为HID类别,设备在定义描述符的时候必须遵守HID规范。
除了USB标准定义的一些描述符外,HID设备还必须定义HID描述符。
USB描述符完全解析
USB设备描述符完全解析//======================================================= =====================// 文件名: USBDESC.C// 用途: USB描述符// 作者: shenfei5// 时间: 2007.2.3// 版本: V1.10//======================================================= =====================#include <RTL.h>#include "usb.h" // USB模块#include "hid.h" // HID设备#include "usbcfg.h" // 配置USB#include "usbdesc.h" // USB描述符//// HID报文描述符//const U8 HID_ReportDescriptor[] = {HID_UsagePageVendor(0x00), // 报告页版本: 0X06 0X00 0XFFHID_Usage(0x01), // 用途页: 0X05 0X01// 如果是MOUSE,KEY,在这里应该有用法索引HID_Collection(HID_Application), // 用法集合开始: 0XA1 0X01HID_UsagePage(HID_USAGE_PAGE_BUTTON), // BUTTON用法页HID_UsageMin(1), // 用法最小值HID_UsageMax(3), // 用法最小值HID_LogicalMin(0), // 逻辑最小值HID_LogicalMax(1), // 逻辑最大值HID_ReportCount(3), // 报告计数(3)HID_ReportSize(1), // 报告页大小(1)HID_Input(HID_Data | HID_Variable | HID_Absolute), // 输入(2)HID_ReportCount(1), // 报告计数值HID_ReportSize(5), // 报告大小HID_Input(HID_Constant), // 输入1HID_UsagePage(HID_USAGE_PAGE_LED), // LED用法页HID_Usage(HID_USAGE_LED_GENERIC_INDICATOR), // 用法页HID_LogicalMin(0), // 用法最小值HID_LogicalMax(1), // 用法最大值HID_ReportCount(8), // 报告计数值HID_ReportSize(1), // 报告大小(1)HID_Output(HID_Data | HID_Variable | HID_Absolute), // 输出(2)HID_EndCollection, // 报告结束};// HID报告描述符大小const U16 HID_ReportDescSize = sizeof(HID_ReportDescriptor);//// USB 设备描述符//const U8 USB_DeviceDescriptor[] = {USB_DEVICE_DESC_SIZE, // bLength 描述符长度= 12HUSB_DEVICE_DESCRIPTOR_TYPE, // bDescriptorType 描述符类型= 1HWBVAL(0x0110), // 1.10 // bcdUSB 设备版本号= 你发行的版本的号0x00, // bDeviceClass 类型代码= 由USB指定0x00, // bDeviceSubClass 子类型代码= 由USB分配0x00, // bDeviceProtocol 协议代码= 由USB分配USB_MAX_PACKET0, // bMaxPacketSize0 端点0的容量= 64(只能是8,16,32,64) WBVAL(0x1977), // idVendor 供应商ID(同USB协会分配,我就自己分配一份)WBVAL(0X1006), // idProduct 产品ID(由厂商分配)WBVAL(0x0100), // 1.00 // bcdDevice ( 设备出厂编号)0x04, // iManufacturer ( 厂商描述字符串索引, 用来在字符串索引中查找字符串)0x20, // iProduct ( 产品描述字符串索引, 用来在字符串索引中查找字符串)0x42, // iSerialNumber ( 设备序列号描述字符串索引, 用来在字符串索引中查找字符串)0x01 // bNumConfigurations (配置字符串的个数)};//// USB 描述符集// 所有描述符(配置描述符, 接口描述符, 端点描述符, USB类描述符, 设备描述符//const U8 USB_ConfigDescriptor[] = {// 配置描述符USB_CONFIGUARTION_DESC_SIZE, // bLength 描述符长度= 9HUSB_CONFIGURATION_DESCRIPTOR_TYPE, // bDescriptorType 描述符类型= 2H WBVAL( // wTotalLengthUSB_CONFIGUARTION_DESC_SIZE + // 返回描述符串集的长度, 配置描述字符长度USB_INTERFACE_DESC_SIZE + // 接口描述字符长度HID_DESC_SIZE + // HID描述字符长度USB_ENDPOINT_DESC_SIZE // 端点描述字符长度),0x01, // bNumInterfaces// 支持接口数0x01, // bConfigurationValue// 配置值0x00, // iConfiguration// 配置字符串描述索相// 0: 不使用// 如果使用,必须在字符串描述符中添加相应的字符串.USB_CONFIG_BUS_POWERED | // bmAttributes 设置的供电特性USB_CONFIG_REMOTE_WAKEUP, // 总线供电// 有唤醒功能USB_CONFIG_POWER_MA(100), // bMaxPower 设备从供电总线吸取的电流值//// 当前配置为100MA// 接口类描述符// 接口0 ,位置0 , HID类// Interface 0, Alternate Setting 0, HID ClassUSB_INTERFACE_DESC_SIZE, // bLength 描述符长度= 9HUSB_INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType 描述符类型= 4H0x00, // bInterfaceNumber ( 接口编号)0x00, // bAlternateSetting ( 可代替位置)0x01, // bNumEndpoints 使用端点(不含端点0)USB_DEVICE_CLASS_HUMAN_INTERFACE, // bInterfaceClass// USB 类// USB_DEVICE_CLASS_HUMAN_INTERFACE == 3// HID类HID_SUBCLASS_NONE, // bInterfaceSubClass// 子类,没有.HID_PROTOCOL_NONE, // bInterfaceProtocol// 协议代码0x5C, // iInterface// 字符串描述符索引,要使用该字符串必须在字符串描述符里添加相应的字符串// HID类描述符// HID_DESC_OFFSET = 0x0012// HID类描述符的偏移量HID_DESC_SIZE, // bLength 描述符长度=HID_HID_DESCRIPTOR_TYPE, // bDescriptorType HID描述符类型= 21HWBVAL(0x0100), // 1.00 // bcdHID HID版本号0x00, // bCountryCode 国家代码0x01, // bNumDescriptors 支持其它类描述符个数HID_REPORT_DESCRIPTOR_TYPE, // bDescriptorType 从属类描述类型= 报告描述符22H WBVAL(HID_REPORT_DESC_SIZE), // wDescriptorLength 从属类描述的长度// Endpoint, HID Interrupt In// HID 端点描述描,端点1输入USB_ENDPOINT_DESC_SIZE, // bLength 端点描述符长度USB_ENDPOINT_DESCRIPTOR_TYPE, // bDescriptorType 端点描述符类型= 5HUSB_ENDPOINT_IN(1), // bEndpointAddress 逻辑端点号BIT.7 = DIR// BIT.0..3 端点号// 这个值是用来把逻辑端点号换成物理端点号USB_ENDPOINT_TYPE_INTERRUPT, // bmAttributes 端点属性= 中断WBVAL(0x0004), // wMaxPacketSize 端点容量10, // 10ms // bInterval// 传输间隔时间.只对中断端点有效// Terminator0 // bLength// 结果码.};//// USB 字符串描述符(可选)// 字符描述符结构:// {// 字符串描述符1 大小// 描述符类型= 字符串描述符(0X03)// 描述符内容.// ... ...// 字符串描述符n 1 大小// 描述符类型n = 字符串描述符(0X03)// 描述符内容n.// }//const U8 USB_StringDescriptor[] = {// 字符串索引: 0x00:// 字符串用途: 语言代码0x04, // 描述符长度bLengthUSB_STRING_DESCRIPTOR_TYPE, // bDescriptorType,描述符类型:3(字符串描述符)//WBVAL(0x0409), // 使用English 语言// 描述符内容wLANGIDWBVAL(0x0804), // 试一下中文的行不行,改了之后,在硬件属性里看不到,在客户端可以看到,不明原因. // 字符串索引: 0x04:// 字符串用途: 生产产商字符描述符0x1C, // 描述符长度bLengthUSB_STRING_DESCRIPTOR_TYPE, // bDescriptorType,描述符类型:3(字符串描述符)0xc1,0,0xd6,0,0xca,0,0xb7,0,0xe1,0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,// 字符串索引: 0x20// 字符串用途: 产品名称0x22, // 描述符长度bLengthUSB_STRING_DESCRIPTOR_TYPE, // bDescriptorType,描述符类型:3(字符串描述符) 0xc1,0,0xd6,0,0xca,0,0xa4,0,0xb7,0,0xe1,0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,' ',0,'H',0,'I',0,'D',0,// 字符串索引: 0x42// 字符串用途: 产品系列号0x1A, // 描述符长度bLengthUSB_STRING_DESCRIPTOR_TYPE, // bDescriptorType,描述符类型:3(字符串描述符) 'T',0,'E',0,'S',0,'T',0,'0',0,'0',0,'0',0,'0',0,'0',0,'0',0,'0',0,// 字符串索引号0x5C// 接口Interface 0, 位置Alternate Setting 00x08, // 描述符长度bLengthUSB_STRING_DESCRIPTOR_TYPE, // bDescriptorType,描述符类型:3(字符串描述符) 'H',0,'I',0,'D',0,}。
USB HID键盘报告描述符
USB HID键盘报告描述符usbhid键盘报告描述符USB HID键盘报告描述符最近弄usb驱动,里面的报告描述符晕了我好几天!找了一些资料希望能对大家有帮助~~~~~~~~~~~~~~理解hidscript脚本语言:globalitem--global item mainitem--main item localitem--local item对于main项,parser解释器,将顺序解释集合中的数据,并且,解释器解释完的数据,根据主要项目的顺序,主要是输入和输出项目,相应的数据位将按顺序拼接,解释器将以关键字collection开始解释并拼接bit位信息,关键字endcollection将在完成Paser解释器的工作后,我调用keyword collection和keyword endcollection\set\,关键字collection和关键字endcollection都是mainitem主项,对应的控制字分别为:101000nn和110000nn。
如果在采集后有一个参数数据,则为10100001=0xa1,例如采集(应用)翻译成控制码后为:0xa1,0x01;0xa1的1表示有1个参数数据,0x01表示application 在hid协议中指定的索引值为0x01。
PC的HID驱动程序将通过解析器中的0x01知道,是对application进行数据流位生成,就是说hid报告描述符(reportdescriptor)所述数据流用于应用程序,包括在两种设备:mouse和keyboard,至于collection(application)里边描述的是mouse或者键盘,这将由用法进一步定义,例如用法(键盘),也就是说,描述是准确的告诉pc的hid驱动程序的paser解释器,接下来的这段信息最后生成出来的bits位数据信息,它将由PC的HID驱动程序中键盘对应的API函数处理。
当然,这只是HID硬件设备开发人员给pc的hid驱动程序的paser解释器提供的一个建议值,比如我们做ddk下的hid驱动二次开发,所以我们可以免费,但是应该遵循HID硬件设备开发者推荐的HID驱动程序API接口,因为hid硬件设备开发者比ddk开发人员更清楚送上来的bit数据流的真正物理意义.输入和输出是用于真正生成比特流数据字段的关键字。
USBHID设备报告描述符详解
USBHID设备报告描述符详解
USBHID设备报告描述符是一种描述USBHID设备报告的结构,用于定义设备报告的输入输出特性,允许设备与控制器的主机通信。
通常,报告描述符是一段二进制数据,其中包含由设备提供的输入和输出报告,以及描述报告的数据结构要求信息。
它是一种混合结构,由多个子块组成,每个子块又由一个或多个报告描述符中的域组成。
报告描述符的结构如下:
报告描述符
-
-bLengt
-bDescriptorTyp
-wDescriptorLengt
-数据
-输入报
-输出/特殊报
-特殊报
头部:报告描述符的头部包括三个字段:报告描述符的字节长度(bLength),报告描述符类型(bDescriptorType)和报告描述符的总长度(wDescriptorLength)。
bLength:报告描述符的字节长度,是报告描述符数据的字节数。
bDescriptorType:报告描述符类型,用于指示报告描述符的类型,必须为0x22
wDescriptorLength:报告描述符的总长度,用于指示报告描述符的总字节数。
数据段:数据段包括输入报告、输出/特殊报告和特殊报告。
输入报告:输入报告用于获取主机发送到设备的数据,一般由设备按定义的格式读取。
输出报告:输出报告用于将设备发送到主机的数据。
3.3.2 HID基本描述符_USB应用开发宝典_[共2页]
║38 应用开发宝典3.3.2 HID基本描述符在USB协议中,HID设备需要支持标准的USB描述符以及HID类描述符。
这里首先介绍HID设备类支持的5个USB标准描述符:设备描述符、配置描述符、接口描述符、端点描述符和字符串描述符。
1.设备描述符HID设备的设备描述符格式如表3.16所示。
HID设备的设备描述符和标准USB设备描述符类似,这里不再详细介绍。
需要指出的是,其中类代码、子类代码和协议代码必须设置为0;而端点0所支持的最大数据包长度可选8、16、32和64。
表3.16 HID设备的设备描述符字段名长度地址偏移量含义bLength 1字节0 描述符的长度(字节):12HbDescriptorType 1字节 1 描述符的类型:设备 = 01HbcdUSB 2字节 2 USB规范版本号(BCD码),例如0x100 bDeviceClass 1字节 4 类代码,0x00bDeviceSubClass 1字节 5 子类代码,0x00bDeviceProtocol 1字节 6 协议代码,0x00bMaxPackerSize01字节7 端点0所支持的最大数据包长度,可选8、16、32和64idVendor 2字节8 供应商IDidProduct 2字节10 产品IDbcdDevice 2字节12 设备版本号(BCD码)iManufacturer 1字节14 供应商字符串描述符的索引值iProduct 1字节15 产品字符串描述符的索引值iSerialNumber 1字节16 设备序列号字符串描述符的索引值bNumConfigurations 1字节17 所支持的配置数2.配置描述符HID设备的配置描述符格式如表3.17所示。
HID设备的配置描述符和USB配置描述符类似,这里不再详细介绍。
表3.17 HID设备的配置描述符字段名长度地址偏移量含义bLength 1字节0 描述符的长度(字节):09H bDescriptorType 1字节 1 描述符的类型:配置 = 02H。
关于USBHID协议以及鼠标键盘描述符的解释【转】
关于USBHID协议以及⿏标键盘描述符的解释【转】转⾃:⼀.HID设备识别前⾯有提到关于SCSI协议的USB设备实现。
现在来谈谈USBHID设备。
HID全称Human Interface Device。
HID协议⾥增加了HID描述符和报告描述符,以及特定的关于HID的类请求。
HID设备的通信是通过报表来进⾏的。
据说,报告描述符是USB设备中最难的描述符了。
关于HID描述符可以参考HID协议。
接下来我们谈谈报告描述符。
⼆.报告描述符每⼀个HID设备都有⾃⼰的报告描述符。
报告描述符有三种类项⽬:Main类项⽬,Global类项⽬,Local类项⽬。
具体看下表Global作⽤域是遇到下⼀个同名Global,Local作⽤域是遇到下⼀个Main(Input,Output,Feature)。
Usage Min-Max表⽰有⼏种功能,Logical Min-Max表⽰有⼏种状态。
每个报告描述符都有报告ID,报告ID是⽤来区别复合设备的。
在报告描述符⾥没有写报告ID,默认报告ID是0。
USB的控制端点可以进⾏Input,Output,Feature项⽬的传输,中断端点可以进⾏Input,Output传输。
三.⿏标和键盘的报告描述符(1)键盘的报告描述符1. 0x05,0x01,// Global Generic Desktop2. 0x09,0x06,// Local KeyBoard3. 0xA1,0x01,// Main app collection4. 0x05,0x07,// Global KeyBoard5. //////////////////////////////////第1字节6. 0x19,0xe0,// Local Usage Min (KeyBoard LeftControl)7. 0x29,0xe7,// Local Usage Max (KeyBoard Right GUI)8. 0x15,0x00,// Global Logical Min9. 0x25,0x01,// Global Logical Max10. 0x95,0x08,// Global ReportCount11. 0x75,0x01,// Global ReportSize12. 0x81,0x02,// Main Input(Data,Var,Abs)13. //////////////////////////////////第2字节14. 0x95,0x01,// Global ReportCount15. 0x75,0x08,// Global ReportSize16. 0x81,0x03,// Main Input(Cnst,Var,Abs)17. //////////////////////////////////第3-8字节18. 0x95,0x06,// Global ReportCount19. 0x75,0x08,// Global ReportSize20. 0x15,0x00,// Global Logical Min21. 0x26,0xff,0x00,//Global Logical Max22. 0x19,0x00,// Local Usage Min23. 0x29,0x65,// Local Usage Max24. 0x81,0x00,// Main Output(Data,Ary,Abs)25. ////////////////////////////////1字节输出报告26. 0x15,0x00,// Global Logical Min27. 0x25,0x01,// Global Logical Max28. 0x95,0x05,// Global ReportCount29. 0x75,0x01,// Global ReportSize30. 0x05,0x08,// Global LED31. 0x19,0x01,// Local Usage Min32. 0x29,0x05,// Local Usage Max33. 0x91,0x02,// Main Output(Data,Var,Abs)34. ////////////////////////////////补⾜上⾯变成1个字节35. 0x95,0x01,// Global ReportCount36. 0x75,0x03,// Global ReportSize37. 0x91,0x03,// Main Output(Cnst,Var,Abs)38. 0xc0 // Main End collection键盘的描述符共有8字节的输⼊报告和1字节的输出报告。
HID设备描述符介绍
HID设备描述符介绍最近在做一个投票系统的上位机。
虽然是上位机,但还是要弄清楚下位机与自己的接口――HID。
因为windows下已经有一个usb监听程序――USB HOUND。
所以,我选择先写好下位机的程序,成功发送数据后,再进行上位机程序的编写。
下位机程序,重点在于HID设备的描述符配置。
什么是描述符?HID设备通过设备描述符来标识自己的设备信息,如设备ID、厂商名称、版本、配置数量等;通过配置描述符集合来标识自己的配置信息,包括:配置描述符(总述)、接口描述符(接口类型,鼠标,键盘,自定义设备等)、端点描述符(端点读写类型,支持的数据包属性等)和HID描述符(HID版本、下级描述符信息等)。
通过字符串描述符来定义自己的一些字符串,如厂商名称等;通过报告描述符来标识数据流的格式,如数据用途(鼠标、键盘、自定义等)、长度、大小等。
网上的很多示例和介绍都使用c语言,但是,我遇到的源码,却是汇编编写的,所以我以我的项目为例,用汇编来介绍各个描述符结构,也算是个不一样的体验吧。
具体的描述介绍如下:设备描述符deviceDesc: ; Device descriptorDB deviceDescEnd - deviceDesc ; bLength 该描述符长度DB DESC_TYPE_DEVICE ; bDescriptorType 类型DW 0200H ; bcdUSB (USB 2.0) USB 版本DB 00H ; bDeviceClass (given by interface) 类代码DB 00H ; bDeviceSubClass 子类代码DB 00H ; bDeviceProtocol 设备协议DB EP0_PACKET_SIZE ; 端点0最大包长DW 0451H ; idV endor (Texas Instruments) 厂商ID (VID)#if (chip==2531)DW 16A9H ; idProduct (CC2531 HID) 产品ID (PID)#elif (chip==2511)DW 16A5H ; idProduct (CC2511 HID)#elseDW 16A7H ; idProduct (CC1111 HID)#endifDW 0100H ; bcdDevice (v1.0) 设备版本号DB 01H ; iManufacturer 描述厂商的字符串索引DB 02H ; iProduct 描述产品的字符串索引DB 00H ; iSerialNumber 产品序列号字符串的索引DB 01H ; bNumConfigurations 可能的配置数deviceDescEnd:在里面,最重要的是VID和PID,它一般用来标识你的USB设备。
USBHID报告描述符详解
USBHID报告描述符详解
1、HID报告描述符介绍
USB人机界面设备,简称HID,是计算机系统中最常见的一种通信接口,它使用设备描述符(Device Descriptors)来描述设备特性,同时使用报告描述符(Report Descriptors)来描述设备支持的数据报文格式,操作系统或软件驱动可以根据报告描述符中设置的信息来识别HID设备所具有的功能,从而支持和控制HID设备。
HID报告描述符描述了与设备相关的数据信息,它是HID设备进行自然交互的基础。
2、HID报告描述符的作用
输入报告(Input Reports)可以被认为是从HID设备发送到操作系统的数据,它可以描述HID设备特性的状态,可以用来报告控制命令、操作状态、三轴分量数据等信息;输出报告(Output Reports)则相反,它表示从操作系统发送给HID设备的数据。
usbHid
一、应用场合USB HID类是比较大的一个类,HID类设备属于人机交互操作的设备。
用于控制计算机操作的一些方面,如USB鼠标,USB键盘,USB游戏操纵杆,USB触摸板,USB轨迹球、电话拨号设备、VCR遥控等等设备。
另外,使用HID设备的一个好处就是,操作系统自带了HID类的驱动程序,而用户无需去开发很麻烦的驱动程序,只要直接使用API调用即可完成通信。
所以很多简单的USB设备,喜欢枚举成HID设备,这样就可以不用安装驱动而直接使用。
二、USB HID类可采用的通信管道所有的HID设备通过USB的控制管道(默认管道,即端点0)和中断管道与主机通信。
控制管道主要用于以下3个方面:接收/响应USB主机的控制请示及相关的类数据在USB主机查询时传输数据(如响应Get_Report请求等)接收USB主机的数据中断管道主要用于以下两个方面:USB主机接收USB设备的异步传输数据USB主机发送有实时性要求的数据给USB设备从USB主机到USB设备的中断输出数据传输是可选的,当不支持中断输出数据传输时,USB主机通过控制管道将数据传输给USB设备。
三、与USB HID设备有关的描述符HID设备的描述符除了5个USB的标准描述符(设备描述符、配置描述符、接口描述符、端点描述符、字符串描述符,另一篇文章:USB开发基础--USB命令(请求)和USB描述符)外,还包括3个HID设备类特定描述符:HID描述符、报告描述符、实体描述符。
除了HID的三个特定描述符组成对HID设备的解释外,5个标准描述符中与HID设备有关的部分有:设备描述符中bDeviceClass、bDeviceSubClass和bDeviceProtocol三个字段的值必须为零。
接口描述符中bInterfaceClass的值必须为0x03,bInterfaceSubClass的值为0或1,为1表示HID设备符是一个启动设备(Boot Device,一般对PC机而言才有意义,意思是BIOS 启动时能识别并使用您的HID设备,且只有标准鼠标或键盘类设备才能成为Boot Device。
HID报告描述详解
在USB中,USB HOST是通过各种描述符来识别设备的,有设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符,报告描述符等等。
USB报告描述符(Report Descriptor)是HID设备中的一个描述符,它是比较复杂的一个描述符。
USB HID设备是通过报告来给传送数据的,报告有输入报告和输出报告。
输入报告是USB 设备发送给主机的,例如USB鼠标将鼠标移动和鼠标点击等信息返回给电脑,键盘将按键数据数据返回给电脑等;输出报告是主机发送给USB设备的,例如键盘上的数字键盘锁定灯和大写字母锁定灯等。
报告是一个数据包,里面包含的是所要传送的数据。
输入报告是通过中断输入端点输入的,而输出报告有点区别,当没有中断输出端点时,可以通过控制输出端点0发送,当有中断输出端点时,通过中断输出端点发出。
而报告描述符,是描述一个报告以及报告里面的数据是用来干什么用的。
通过它,USB HOST可以分析出报告里面的数据所表示的意思。
它通过控制输入端点0返回,主机使用获取报告描述符命令来获取报告描述符,注意这个请求发送到接口的,而不是到设备。
一个报告描述符可以描述多个报告,不同的报告通过报告ID 来识别,报告ID在报告最前面,即第一个字节。
当报告描述符中没有规定报告ID时,报告中就没有ID字段,开始就是数据。
更详细的说明请参看USB HID协议,该协议可从下载。
下面通过由HID Descriptor tool生成的USB鼠标和USB键盘来说明一下报告描述符和报告。
code char KeyBoardReportDescriptor[63] = {//表示用途页为通用桌面设备0x05, 0x01, // USAGE_PAGE (Generic Desktop)//表示用途为键盘0x09, 0x06, // USAGE (Keyboard)//表示应用集合,必须要以END_COLLECTION来结束它,见最后的END_COLLECTION 0xa1, 0x01, // COLLECTION (Application)//表示用途页为按键0x05, 0x07, // USAGE_PAGE (Keyboard)//用途最小值,这里为左ctrl键0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)//用途最大值,这里为右GUI键,即window键0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)//逻辑最小值为00x15, 0x00, // LOGICAL_MINIMUM (0)//逻辑最大值为10x25, 0x01, // LOGICAL_MAXIMUM (1)//报告大小(即这个字段的宽度)为1bit,所以前面的逻辑最小值为0,逻辑最大值为10x75, 0x01, // REPORT_SIZE (1)//报告的个数为8,即总共有8个bits0x95, 0x08, // REPORT_COUNT (8)//输入用,变量,值,绝对值。
USB固件开发(HID设备)
USB固件开发(HID设备)收藏USB固件开发(HID设备)1. HID设备的识别HID设备类除了有文档第一部分所述的一些标准描述符(包括设备描述符、配置描述符、接口描述符、端点描述符、字符串描述符)外,还有自己的类专有描述符:HID描述符报告描述符物理描述符正确实现HID设备类专用描述符是主机成功识别HID设备的关键。
HID描述符和报告描述符是必须要使用的,物理描述符一般不被使用。
1.1 HID描述符HID描述符跟接口描述符、端点描述符类似,也是随配置信息一起返回给主机的,主机并不会单独发出请求来读取它。
HID描述符在配置信息中的位置是紧接接口描述符。
例如:_Config_Descriptor:.dw _Config_Descriptor_End-_Config_Descriptor //bLength: 0x09 byte.dw 0x02 //bDescriptorType: CONFIGURATION.dw _Config_Descriptor_Total-_Config_Descriptor //wTotalLength:.dw 0x00.dw 0x01 //bNumInterfaces: 1 interfaces.dw 0x01 //bConfigurationValue: configuration 1.dw 0x00 //iConfiguration: index of string.dw 0xC0 //bmAttributes: self powered, Not Support Remote-Wakeup.dw 0x32 //MaxPower: 100 mA_Config_Descriptor_End:_HID_Interface_Descriptor://Interface 1 (0x09 byte).dw 0x09 //bLength: 0x09 byte.dw 0x04 //bDescriptorType: INTERFACE.dw 0x01 //bInterfaceNumber: interface 0.dw 0x00 //bAlternateSetting: alternate setting 0.dw 0x01 //bNumEndpoints: 1 endpoints(EP1).dw 0x03 //bInterfaceClass: 人机接口设备(HID)类.dw 0xff //bInterfaceSubClass: 供应商定义.dw 0xff //bInterfaceProtocol 使用的协议:供应商定义.dw 0x00 //iInterface: index of string_HID_Interface_Descriptor_End:HID_Descriptor:.dw 0x09 //bLength: 0x09 byte.dw 0x21 //bDescriptorType: HID描述符类型编号.dw 0x01, 0x10 //HID类协议版本号,为1.1.dw 0x21 //固件的国家地区代号,0x21为美国.dw 0x01 //下级描述符的数量.dw 0x22 //下级描述符为报告描述符.dw _ReportDescriptor_End-_ReportDescriptor, 0x00 //下级描述符的长度_HID_Descriptor_End:_Endpoint3:.dw 0x07 //bLength: 0x07 byte.dw 0x05 //bDescriptorType: ENDPOINT.dw 0x83 //bEndpointAddress: IN endpoint 3.dw 0x03 //bmAttributes: Interrupt.dw 0x02, 0x00 //wMaxPacketSize: 2 byte.dw 0x0A //bInterval: polling interval is 10 ms_Config_Descriptor_Total:HID描述符其实是为了提供下级描述符(如报告描述符)的信息。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
USBHID设备报告描述符详解概述:报告在这里意思是数据传输(data transfer),而报告描述符是对这些传输的数据作用途(usage)上的说明。
USB通讯协议的规范是以1ms产生一个USB帧(frame),USB设备可以每一个帧中发送和接收一个交换(transaction)。
交换是由几个封包(packet)组成,而传输是由一个或几个交换来完成传送一口中有效的数据。
在这里,传输和报告的意思相类似。
传输方式有四种,初始学一般只要了解控制型传输(control transfer)和中断型传输(interrupt transfer)即可。
控制型传输是当需要时才执行传输要求,是最一般的传输方式,组态、命令和状态的通讯都可以使用控制型传输;控制型传输主要用于消息型数据(message-type data)。
中断型传输目的在做重复的数据更新(recurring data)传输,精确一点而言,即是在每个有限有周期内(bounded period)作至少一次的小量数据发送或接收;所以适用于流动型数据(stream-type data),注意这里所谓的周期时间就是在端点描述符中的轮询间隔时间。
报告有三种:input,output,和Feature.后面将作进一步介绍。
中断型输入管线(interrupt in pipe)仅可以传送input报告;中断型输出管线(interrupt out pipe)仅可以传送output报告;但是控制型管线(control pipe)可以传送input,output和feature报告。
端点描述符有声明所使用的端点为何种管线。
数据本身没有任何意义,要赋于用途才能明确其为控制什么(control);例如设备上的按钮指示灯和X与Y轴的位移等都通称控制,数据则为按钮和指示灯的开关状态或X与Y 轴的位移量。
为了这个目的应运而生报告描述符,其将数据的操控与它的用途作一对一的对应,所以解读报告后就可以知道每个数据作何种操作。
所以“传输的数据”和“操作”只是一事件的两种描述方式。
用途是以一个32位卷标(称作usage tag)来表示,高16位称作usage page(用途类页),低16位称为usage ID(用途识别名):Usage = (usage page:usage ID)举例说明:二个字节分别为x和y轴的位移数据,因此第一个字节的usage=(generic desktop:X),而第二个字节的usage = (generic desktop:Y),其中generic desktop为用途的大类别(称作用途类页)之一,x和y轴的操作用途属于此用途类页。
文件universal serial Bus HID Usage Table完整列出所有的usage pages(用途类页)和usage ID(用途识别名),使用者必须遵照文件的规范来声明操作的用途。
该文件的附录A有十多个报告描述符的范例,值得研究下。
表1、报告描述符的标签主项目全域项目区域项目标签代码标签代码标签代码InputX08?Usage Page0x0?Usage0x0?Output0x9?Logical Minimum 0x1?Usage Minimum 0x1?Feature0x0b?Logical Maximum0x2?Usage Maximum0x2?Physical Minimum 0x3?Designator Minimum 0x3?Collection0xa1Physical Maximum0x4?Designator Minimum 0x4?End Collection0xc0Unit Exponent0x5?Designator Maximum 0x5?Unit0x6?String0x7?Report Size0x7?Sreing Minimum0x8?Report ID0x8?String Maximum0x9?Report Coumt0x9?Delimiter0xa?Push0xA?Pop0xb?标签:用途卷标只是报告描述符诸多标签的一个。
表1列出所有的卷标,利用这些卷标取可以清楚完整的描述符操作的用途。
报告描述符的语法不同于USB标准描述符,它是以项目(items)方式排列而成,无一定的长度;项目有一个前辍(prefix),然后跟着一个括号,内为该项目的数据:item = prefix(data)。
项目分成三种类别:主项目,全局项目,区域项目。
主项目中的input,ouput,feature三个卷标用来表示报告中数据的种类,这些是报告描述符中最主要的项目,其他项目都是用来修饰这三种项目。
主要项目中其他二个卷标后面再作详细的介绍。
>> Input 项:表示设备操作输入到主机的数据模式。
这个数据格式就形成一个输入报告,虽然输入报告可以用控制型管线以get report(input)来传输,但是通常用中断型输入管线来传输以确保在每一固定周期内都能将更新的输入报告传给主机。
>> Output项:表示由主机输出到装置操作的数据格式。
这个数据格式就形成一个输出报告。
输出报告通常不适用轮询的方式来传送给设备,而是由应用软件依实际需求以传令方式要求送出输出报告,所以大多用控制型管线以set report(output)指令来将报告送到设备。
当然也可以选择用中断型输出管线来传送,只是通常不建议这样用。
>> Feature项:表示由主机送到设备的组态所需数据的数据格式。
这个数据模式就形成一个特征报告。
特征报告只能用控制型管线以get report(feature)和set report(feature)指令分别来取得和设定设备的特征值。
>> 范例:考虑一个2X16字的显示装置,它的列数、行数、字宽、和字高为固定值属于feature报告;显示状态例如“就绪”和“输入字错误”则属于input报告;光标位置和显示的字需可读写,所以属于另一个feature报告;更新显示的字则为output报告。
为了区别两个features,要用到全局项目中的report ID,每个feature报告有一个不同的report ID,因而主机请求指令要加上report ID的值:getreport(feature,report ID)和Set report(feature,report ID)。
主项目用来定义报告中数据的种类和格式,而说明主项目之意义与用途为全局项目和区域项目。
顾名思义,区域性项目只能适用于列于其下的第一个主项目,不适用于其他主项目,若一个主项目之上有几个不同的卷标的区域性项目,则这些区域性项目皆适用于描述该主项目。
相反,全局性项目适用于其下方的所有主项目,除非另一个相同卷标的全局性项目出现。
为了清楚说明报告描述符,将使用“项目状态表”(item state table)用来表示在某位址处适用的全局性项目的组合。
图1显示全局性项目和区域性项目与所描述的主项目之对应关系。
区域性项目卷标:简单地说,区域性项目(见表1)只是说明用途而已。
Designator是要搭配实体描述符使用的,这里不对实体描述符进行介绍,所以略过这些designator标签。
标签Usage 实际上应该称作Usage ID,它搭配全域项目的Usage Page 卷标才形成前文所定义的用途{usage}﹔但是报告描述符允许在区域项目的Usage 卷标直接用32位的方式来指定用途,这种方式称作扩充式用途指定法(extended usage)以示区别。
例如:Usage(Generic Desktop:Mouse),Usage Minimum(Keyboard:0),和Usage Maximum(Keyboard:101)。
很明显的,扩充式用途指定法会取代『项目状态表』中的Usage Page。
还有,使用扩充式用途指定法时,数据的高16 个位为用途类页Usage Page,低16 个位则为用途识别名Usage ID。
往往一个报告数据会对应到几个操作,因而会有几个用途,例如101 按键的键盘利用不同代码代表不同的键,每一个键是一个操作,有自己的用途,要将所有Usage ID 列出不太现实,所以就需要Usage Minimum 和Usage Maximum 二个标签。
以键盘为例,主项目之上只要二个区域项目:Usage Minimum (0), Usage Maximum (101)。
如此一来,则无键按下(Usage ID 为0)和101 键中任一键被按下(Usage ID 为1 至101)的用途都被赋于到一个报告数据上,后面会有一个范例进一步解说。
卷标String Index 类似卷标Usage,而卷标String Minimum 和String Maximum 则类似标签Usage Minimum 和Usage Maximum。
如果希望某个操作对应到一个字串,则用String Index 来描述该操控的报告数据,这个字符串在字符串描述符中,StringIndex (data)项目中的data 是这个字符串在字符串描述符中的位置索引。
如果需要用到几个字符串,则可以使用String Minimum 来指向字符串描述符中被用到字符串的最先位置索引,和String Maximum 来指向最后位置索引。
标签Delimiter 很少用到,请参考Universal Serial Bus HID Usage Tables 文件中Appendix B 的范例详细说明。
全局项目卷标全局项目的卷标事实上只要Usage Page,Logical Minimum,Logical Maximum,Report Size,Report ID,Report Count 就足够了。
表2 列了二个音量操作的例子(音量增减键和音量旋钮)将用来辅助说明这些卷标,不过主项目括号内的数据会在后文中再做说明。
表2、音量操作举例音量减键音量旋钮Usage Page(consumer)Usage Page(Consumer)Usage(V olume)Usage(V olume)Logical Minimum(-1)Logical Minimum(0)Logical Maximum(1)Logical Maximum(100)Report Size(2)Report Size(7)Report Count(1)Report Count(1)Input(Data,Variable,Relative)Input(Data,Variable,Absolute,No Wrap,Linear,No Relative)查阅Universal Serial Bus HID Usage Tables 文档,这两个例子的用途需要令为(Consumer: V olume)。