概述报告在这里意思是数据传输(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 DI(用途识别名):Usage=(usage page:usage ID)主项目全域项目区域项目标签代码标签代码标签代码Input0X8?Usage Page0x0?Usage0x0?0x1? Output0x9?Logical Minimum0x1?UsageMinimum0x2? Feature0xb?Logical Maximum0x2?UsageMaximumPhysical Minimum0x3?Designator0x3?举例说明:二个字节分别为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、报告描述符的标签标签:用途卷标只是报告描述符诸多标签的一个。
表1列出所有的卷标,利用这些卷标取可以清楚完整的描述符操作的用途。
报告描述符的语法不同于USB 标准描述符,它是以项目(items)方式排列而成,无一定的长度;项目有一个前辍(prefix),然后跟着一个括号,内为该项目的数据:item =prefix(data)。
项目分成三种类别:主项目,全局项目,区域项目。
主项目中的input,ouput,feature 三个卷标用来表示报告中数据的种类,这些是报告描述符中最主要的项目,其他项目都是用来修饰这三种项目。
主要项目中其他二个卷标后面再作详细的介绍。
Input 项:表示设备操作输入到主机的数据模式。
这个数据格式就形成一个输入报告,虽然输入报告可以用控制型管线以get report(input)来传输,但是通常用中断型输入管线来传输以确保在每一固定周期内都能将更新的输入报告传给主机。
MinimumCollection 0xa?Physical Maximum 0x4?Designator Minimum 0x4?End Collection 0xc0Unit Exponent0x5?Designator Maximum 0x5?Unit0x6?String 0x7?Report Size0x7?Sreing Minimum 0x8?Report ID0x8?String Maximum 0x9?Report Coumt0x9?Delimiter 0xa?Push0xA?Pop 0xb? Output项:表示由主机输出到装置操作的数据格式。
这个数据格式就形成一个输出报告。
输出报告通常不适用轮询的方式来传送给设备,而是由应用软件依实际需求以传令方式要求送出输出报告,所以大多用控制型管线以set report(output)指令来将报告送到设备。
当然也可以选择用中断型输出管线来传送,只是通常不建议这样用。
Feature项:表示由主机送到设备的组态所需数据的数据格式。
这个数据模式就形成一个特征报告。
特征报告只能用控制型管线以getreport(feature)和set report(feature)指令分别来取得和设定设备的特征值。
范例:考虑一个2X16字的显示装置,它的列数、行数、字宽、和字高为固定值属于feature报告;显示状态例如“就绪”和“输入字错误”则属于input报告;光标位置和显示的字需可读写,所以属于另一个feature报告;更新显示的字则为output报告。
为了区别两个deatures,要用到全局项目中的report ID,每个feature报告有一个不同的report ID,因而主机请求指令要加上report ID的值:get report(feature,report ID)和Setreport(feature,report ID)。
主项目用来定义报告中数据的种类和格式,而说明主项目之意义与用途为全局项目和区域项目。
顾名思义,区域性项目只能适用于列于其下的第一个主项目,不适用于其他主项目,若一个主项目之上有几个不同的卷标的区域性项目,则这些区域性项目皆适用于描述该主项目。
相反,全局性项目适用于其下方的所有主项目,除非另一个相同卷标的全局性项目出现。
为了清楚说明报告描述符,将使用“项目状态表”(item state table)用来表示在某位址处适用的全局性项目的组合。
图1显示全局性项目和区域性项目与所描述的主项目之对应关系。
区域性项目卷标:简单地说,区域性项目(见表1)只是说明用途而已。
Designator是要搭配实体描述符使用的,这里不对实体描述符进行介绍,所以略过这些designator 标签。
标签Usage实际上应该称作Usage ID,它搭配全域项目的Usage Page卷标才形成前文所定义的用途{usage}﹔但是报告描述符允许在区域项目的Usage卷标直接用32位的方式来指定用途,这种方式称作扩充式用途指定法(extended usage)以示区别。
例如:Usage(Generic Desktop:Mouse),UsageMinimum(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(Volume)Usage(Volume)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,NoWrap,Linear,No Relative)查阅Universal Serial Bus HID Usage Tables文档,这两个例子的用途需要令为(Consumer:Volume)。
Usage Page前面已经介绍过了。