USBHID设备报告描述符详解.docx

上传人:b****6 文档编号:7466838 上传时间:2023-05-11 格式:DOCX 页数:14 大小:29.11KB
下载 相关 举报
USBHID设备报告描述符详解.docx_第1页
第1页 / 共14页
USBHID设备报告描述符详解.docx_第2页
第2页 / 共14页
USBHID设备报告描述符详解.docx_第3页
第3页 / 共14页
USBHID设备报告描述符详解.docx_第4页
第4页 / 共14页
USBHID设备报告描述符详解.docx_第5页
第5页 / 共14页
USBHID设备报告描述符详解.docx_第6页
第6页 / 共14页
USBHID设备报告描述符详解.docx_第7页
第7页 / 共14页
USBHID设备报告描述符详解.docx_第8页
第8页 / 共14页
USBHID设备报告描述符详解.docx_第9页
第9页 / 共14页
USBHID设备报告描述符详解.docx_第10页
第10页 / 共14页
USBHID设备报告描述符详解.docx_第11页
第11页 / 共14页
USBHID设备报告描述符详解.docx_第12页
第12页 / 共14页
USBHID设备报告描述符详解.docx_第13页
第13页 / 共14页
USBHID设备报告描述符详解.docx_第14页
第14页 / 共14页
亲,该文档总共14页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

USBHID设备报告描述符详解.docx

《USBHID设备报告描述符详解.docx》由会员分享,可在线阅读,更多相关《USBHID设备报告描述符详解.docx(14页珍藏版)》请在冰点文库上搜索。

USBHID设备报告描述符详解.docx

USBHID设备报告描述符详解

USB/HID设备报告描述符详解

概述:

报告在这里意思是数据传输(datatransfer),而报告描述符是对这些传输的数据作用途(usage)上的说明。

USB通讯协议的规是以1ms产生一个USB帧(frame),USB设备可以每一个帧中发送和接收一个交换(transaction)。

交换是由几个封包(packet)组成,而传输是由一个或几个交换来完成传送一口中有效的数据。

在这里,传输和报告的意思相类似。

传输方式有四种,初始学一般只要了解控制型传输(controltransfer)和中断型传输(interrupttransfer)即可。

控制型传输是当需要时才执行传输要求,是最一般的传输方式,组态、命令和状态的通讯都可以使用控制型传输;控制型传输主要用于消息型数据(message-typedata)。

中断型传输目的在做重复的数据更新(recurringdata)传输,精确一点而言,即是在每个有限周期(boundedperiod)作至少一次的小量数据发送或接收;所以适用于流动型数据(stream-typedata),注意这里所谓的周期时间就是在端点描述符中的轮询间隔时间。

报告有三种:

input、output和Feature。

后面将作进一步介绍。

中断型输入管线(interruptinpipe)仅可以传送input报告;中断型输出管线(interruptoutpipe)仅可以传送output报告;但是控制型管线(controlpipe)可以传送input、output和feature报告。

端点描述符有声明所使用的端点为何种管线。

数据本身没有任何意义,要赋于用途才能明确其为控制什么(control);例如设备上的按钮指示灯和X与Y轴的位移等都通称控制,数据则为按钮和指示灯的开关状态或X与Y轴的位移量。

为了这个目的应运而生报告描述符,其将数据的操控与它的用途作一对一的对应,所以解读报告后就可以知道每个数据作何种操作。

所以“传输的数据”和“操作”只是一事件的两种描述方式。

用途是以一个32位卷标(称作usagetag)来表示,高16位称作usagepage(用途类页),低16位称为usageID(用途识别名):

Usage=(usagepage:

usageID)

举例说明:

二个字节分别为x和y轴的位移数据,因此第一个字节的usage=(genericdesktop:

X),而第二个字节的usage=(genericdesktop:

Y),其中genericdesktop为用途的大类别(称作用途类页)之一,x和y轴的操作用途属于此用途类页。

文件universalserialBusHIDUsageTable完整列出所有的usagepages(用途类页)和usageID(用途识别名),使用者必须遵照文件的规来声明操作的用途。

该文件的附录A有十多个报告描述符的例,值得研究下。

表1、报告描述符的标签

主项目MainItem

全域项目GlobalItem

区域项目LocalItem

标签

代码

标签

代码

标签

代码

Input

0x8?

UsagePage

0x0?

Usage

0x0?

Output

0x9?

LogicalMinimum

0x1?

UsageMinimum

0x1?

Feature

0xB?

LogicalMaximum

0x2?

UsageMaximum

0x2?

PhysicalMinimum

0x3?

DesignatorMinimum

0x3?

Collection

0xA1

PhysicalMaximum

0x4?

DesignatorMinimum

0x4?

EndCollection

0xc0

UnitExponent

0x5?

DesignatorMaximum

0x5?

Unit

0x6?

String

0x7?

ReportSize

0x7?

SreingMinimum

0x8?

ReportID

0x8?

StringMaximum

0x9?

ReportCoumt

0x9?

Delimiter

0xA?

Push

0xA4

Pop

0xB4

标签:

用途卷标只是报告描述符诸多标签的一个。

表1列出所有的卷标,利用这些卷标可以清楚完整的描述符操作的用途。

报告描述符的语法不同于USB标准描述符,它是以项目(items)方式排列而成,无一定的长度;项目有一个前辍(prefix),然后跟着一个括号,为该项目的数据:

item=prefix(data)。

项目分成三种类别:

主项目,全局项目,区域项目。

主项目中的input,ouput,feature三个卷标用来表示报告中数据的种类,这些是报告描述符中最主要的项目,其他项目都是用来修饰这三种项目。

主要项目中其他二个卷标后面再作详细的介绍。

>>Input项:

表示设备操作输入到主机的数据模式。

这个数据格式就形成一个输入报告,虽然输入报告可以用控制型管线以getreport(input)来传输,但是通常用中断型输入管线来传输以确保在每一固定周期都能将更新的输入报告传给主机。

>>Output项:

表示由主机输出到装置操作的数据格式。

这个数据格式就形成一个输出报告。

输出报告通常不适用轮询的方式来传送给设备,而是由应用软件依实际需求以传令方式要求送出输出报告,所以大多用控制型管线以setreport(output)指令来将报告送到设备。

当然也可以选择用中断型输出管线来传送,只是通常不建议这样用。

>>Feature项:

表示由主机送到设备的组态所需数据的数据格式。

这个数据模式就形成一个特征报告。

特征报告只能用控制型管线以getreport(feature)和setreport(feature)指令分别来取得和设定设备的特征值。

>>例:

考虑一个2X16字的显示装置,它的列数、行数、字宽、和字高为固定值属于feature报告;显示状态例如“就绪”和“输入字错误”则属于input报告;光标位置和显示的字需可读写,所以属于另一个feature报告;更新显示的字则为output报告。

为了区别两个features,要用到全局项目中的reportID,每个feature报告有一个不同的reportID,因而主机请求指令要加上reportID的值:

getreport(feature,reportID)和Setreport(feature,reportID)。

主项目用来定义报告中数据的种类和格式,而说明主项目之意义与用途为全局项目和区域项目。

顾名思义,区域性项目只能适用于列于其下的第一个主项目,不适用于其他主项目,若一个主项目之上有几个不同的卷标的区域性项目,则这些区域性项目皆适用于描述该主项目。

相反,全局性项目适用于其下方的所有主项目,除非另一个相同卷标的全局性项目出现。

为了清楚说明报告描述符,将使用“项目状态表”(itemstatetable)用来表示在某位址处适用的全局性项目的组合。

图1显示全局性项目和区域性项目与所描述的主项目之对应关系。

区域性项目卷标:

简单地说,区域性项目(见表1)只是说明用途而已。

Designator是要搭配实体描述符使用的,这里不对实体描述符进行介绍,所以略过这些designator标签。

标签Usage实际上应该称作UsageID,它搭配全域项目的UsagePage卷标才形成前文所定义的用途{usage}﹔但是报告描述符允许在区域项目的Usage卷标直接用32位的方式来指定用途,这种方式称作扩充式用途指定法(extendedusage)以示区别。

例如:

Usage(GenericDesktop:

Mouse),UsageMinimum(Keyboard:

0),和UsageMaximum(Keyboard:

101)。

很明显的,扩充式用途指定法会取代『项目状态表』中的UsagePage。

还有,使用扩充式用途指定法时,数据的高16个位为用途类页UsagePage,低16个位则为用途识别名UsageID。

往往一个报告数据会对应到几个操作,因而会有几个用途,例如101按键的键盘利用不同代码代表不同的键,每一个键是一个操作,有自己的用途,要将所有UsageID列出不太现实,所以就需要UsageMinimum和UsageMaximum二个标签。

以键盘为例,主项目之上只要二个区域项目:

UsageMinimum(0),UsageMaximum(101)。

如此一来,则无键按下(UsageID为0)和101键中任一键被按下(UsageID为1至101)的用途都被赋于到一个报告数据上,后面会有一个例进一步解说。

卷标StringIndex类似卷标Usage,而卷标StringMinimum和StringMaximum则类似标签UsageMinimum和UsageMaximum。

如果希望某个操作对应到一个字串,则用StringIndex来描述该操控的报告数据,这个字符串在字符串描述符中,StringIndex(data)项目中的data是这个字符串在字符串描述符中的位置索引。

如果需要用到几个字符串,则可以使用StringMinimum来指向字符串描述符中被用到字符串的最先位置索引,和StringMaximum来指向最后位置索引。

标签Delimiter很少用到,请参考UniversalSerialBusHIDUsageTables文件中AppendixB的例详细说明。

全局项目卷标

全局项目的卷标事实上只要UsagePage,LogicalMinimum,LogicalMaximum,

ReportSize,ReportID,ReportCount就足够了。

表2列了二个音量操作的例子(音量增减键和音量旋钮)将用来辅助说明这些卷标,不过主项目括号的数据会在后文中再做说明。

表2、音量操作举例

音量减键

音量旋钮

UsagePage(consumer)

UsagePage(Consumer)

Usage(Volume)

Usage(Volume)

LogicalMinimum(-1)

LogicalMinimum(0)

LogicalMaximum

(1)

LogicalMaximum(100)

ReportSize

(2)

ReportSize(7)

ReportCount

(1)

ReportCount

(1)

Input(Data,Variable,Relative)

Input(Data,Variable,Absolute,NoWrap,Linear,NoRelative)

查阅UniversalSerialBusHIDUsageTables文档,这两个例子的用途需要令为(Consumer:

Volume)。

UsagePage前面已经介绍过了。

ReportSize用来设定主项目(Input,Output,Feature)的报告字段大小,它的单位是位。

主项目会对每个操作产生一个报告字段,字段大小则由ReportSize决定。

而ReportCount用来设定主项目之报告字段的数目,其等于操作的数目。

音量增减键的例子中ReportCount

(1)表示主项目Input只产生一个字段,所以可知只有一个音量增减键﹔而ReportSize

(2)表示这个字段为2位。

另一个音量旋钮例子也是只有一个旋钮,所以用ReportCount

(1)﹔但是因为ReportSize(7),所以该旋钮的数据字段为7位,可以表示0到127之数值。

再举一例,如果是鼠标的三个按键,每个按键占用一个一位的字段,则ReportSize

(1),ReportCount(3)﹔那么这个报告长度为三个位,可以同时呈现出三个按键的状态(原状或被按下)。

LogicalMinimum和LogicalMaximum在说明每个报告字段的数值围,这是纯数值所以称为逻辑数值(logicalvalue)。

音量增减键的例子中LogicalMinimum(-1),LogicalMaximum

(1)表示只会出现-1,0,1三种数值,所以用到二位(即ReportSize

(2)),0b11代表-1,0b00代表0,0b01代表1。

在音量旋钮例子中,虽然用7位作一字段,但是旋钮仅会产生0到100的数值,因为LogicalMinimum(0)和LogicalMaximum(100)。

假如实体程序错误产生超出逻辑数值的围,则主机将会忽略该数值,这种数值称作nullvalue。

当要将同一种报告分成数个部分,则每一个部分要给予一个识别值,这时就需用到卷标ReportID,其数据值必须从1起算,不可使用0。

没有赋予ReportID标签的报告,主机有可能会将其ReportID视为0,所以ReportID(0)被要求不能使用。

这个标签对控制型管线才有意义,因为它可以在请求报告时指定ReportID的值。

对于中断型管线,其为周期性传输报告,所以每次都会将所属报告传完,没有仅传输部分之必要,所以ReportID标签就无意义。

其它的全局项目卷标可分为辅助工具(Push和Pop)和物理量说明(PhysicalMinimum,PhysicalMaximum,UnitExponent,和Unit)。

Push卷标将『项目状态表』存放到缓存器(stack),而Pop卷标反过来将缓存器最顶层的『项目状态表』取回来取代目前之状态表。

这二个标签对很长的报告描述符才有用处,因为其可以节省多列一些全局项目。

读者当要使用到时,参考UniversalSerialBusHIDUsageTables文件AppendixA.7节中例则可获得正确使用方式。

不同厂家的鼠标有不同的分辨率,若要让主机知道鼠标的分辨率,就必须用到物理量的标签。

不使用也不会影响到鼠标的功能,只是使用者无法由主机的驱动程式得知分辨率而已。

但是量测装置(例如温度计)的应用程序必须知道物理量,则这些标签就必备了。

分辨率r的算法如下

    r=((lM-lm)/(PM-Pm))X10iUnit

其中lm=LogicalMinimum,lM=LogicalMaximum,pm=PhysicalMinimum,pM=PhysicalMaximum,i=UnitExponent。

以400-dpi的鼠标为例如表3。

表3:

解析度的例

LogicalMinimum(-127)

R=((127-(-127))/(3175-(-3175))X10-4

=400countsperinch

LogicalMinimum(127)

PhysicalMinimum(-3175)

PhysicalMinimum(3175)

给定Logical值,计算出physical值:

((PM-Pm)/2)/10i=((127-(-127))/400)/2=0.3173

à|PM|=|Pm|=3175,i=4

UnitExponent(-4)

Unit(inch)

注意,若是UnitExponent未定义,则视为i=0﹔若是PhysicalMinimum和PhysicalMaximum有一个以上未定义,则视为PM=lM和pm=lm。

所以标签PhysicalMinimum和PhysicalMaximum一定要同时定义,否则无意义。

这些卷标的括号数字为有符号的整数,可以是一个字节或二至四个字节,字节数目会在卷标代码的最低二位定义,详情后文会叙述。

卷标Unit的括号数据比较复杂,总共用了7个四位(nibbles)来描述,各个四位之意义如表4,其中第8个四位

未被使用到。

表4:

标签Unit的信息格式

Nibbe

7

6

5

4

3

2

1

0

0

LuminousIntensity

Current

Temperature

Time

Mass

Length

System

HID共享了四种单位系统,最低的四位就是决定使用的单位系统(System),不同的系统中当然物理量的单位也不一样。

单位和系统间的对应关系如表5。

 

表5:

物理量的单位之编码法

None

SILinear

SIRotation

EnglishLinear

EnglishRotation

System

0x0

0x1

0x2

0x3

0x4

Length

None

公分

径度

英寸

角度

Mass

None

公克

公克

Slug

Slug

Time

None

Temperature

None

凯氏(绝对温度)

凯氏(绝对温度)

华氏

华氏

Current

None

安培

安培

安培

安培

Luminousintensity

None

Candela

Candela

Candela

Candela

除了最低四位的值用来选择单位系统外,其余每个四位皆表示该单位的幂次方,每个四位(nibble)都是有符号的整数,可表示的围为-8至+7:

-8

-7

-6

-5

-4

-3

-2

-1

0

1

2

3

4

5

6

7

08h

09h

0ah

0bh

0ch

0dh

0eh

0fh

00h

01h

02h

03h

04h

05h

06h

07h

因此长度的单位若为公分则Unit(data)中data的码为0x11,若为英吋则为0x13,这二者中Length的四位值皆为1表示幕次方为1,即cm1或in1。

质量单位为公克之码为0x0101,加速度单位为公分除以平方秒之码为0xE011,其中E代表-2。

所以力量单位为质量(公克)乘于加速度(公分/平方秒)的码为0xE111。

能量单位焦尔为力量乘于长度之码为0xE121,其等义于s?

2gcm2和单位系统为SILinear。

主项目

主项目中产生报告数据格式的三个卷标(Input,Output,和Feature)具有共通的数据定义,这些数据和其代码列于表6中。

目前用到9个位来表示这些数据。

如果第九位(bit8)为0,则仅需用一个字节来表示该数据,即忽略第九位。

如果第九位为1,就需用到二个字节来表示该数据。

表6:

主项目的信息代码

Bit

8

7

6

5

4

3

2

1

0

0

BitField

NonVolatile

NoNullPosition

PreferredState

Linear

NoWrap

Absolute

Array

Data

1

BufferedBytes

Volatile

NullState

NoPreferred

NonLinear

Wrap

Relative

Variable

Constant

Data/Constant:

主项目之数据为可变值(设为Data),或为固定不可变值(设为Constant)。

Constant都用于Feature的报告,或是用于填充位(padding),使报告长度以字节为单位。

Array/Variable:

主项目之数据的每个字段可以表示几个不同的操作的其中一个被触发(设为Array),或是每个字段仅表示一个操作(设为Variable)。

如果是Variable,则ReportCount的数据值等于报告数据的字段数。

若是Array,则ReportCount的数据值表示可以同时被触发的最多操作数目。

后文中键盘之例会解说Array的用法。

Absolute/Relative:

主项目的数据是以相对于固定的基准点方式提供绝对数值(设为Absolute),或是提供相对于前次报告的相对值(设为Relative)。

【例说明】前文中的音量操控例,因为都是Data和Variable,二者的操作值皆为变化值,且一个字段仅表示一个操作。

但是音量增减键的例子为Relative,所以若报告值由0变成+1,则音量增大一个刻度,反之由0变作-1则音量减小一个刻度,因而音量大小因输入值而作相对的变化。

然而音量旋钮的例子为Absolute,当输入值为最小值0时,为静音,而输入值为最大值100时,为最大音量,其余值作百分比的音量调整,输入值和音量成绝对关系。

NoWrap/Wrap:

主项目的数据值达到极值后会转为极低值,反之亦同,称作卷绕(设为Wrap)。

例如一个转钮可以做360°旋转,输出值从0至10,若设定为Wrap,则值达10后,在同方向旋转则值变为0,反之若达到0,再转就得到10。

Linear/Nonlinear:

主项目的数据与操作刻度为线性关系(设为Linear),或为非线性(设为Nonlinear)。

PreferredState/NoPreferred:

主项目对应的操作再不被触发时会自动恢复到初始状态(设为PreferredState),或是不会恢复原状(设为NoPreferred)。

例如键盘的按键和会自动置中(self-centering)的游戏杆,皆为PreferredState。

【例说明】再以音量操作为例,音量增减键的例子都没标注NoWrap,Linear,PreferredState,但是没有标注即认定其属于默认值,所以等同于是这些设定,只是这些设定对此例的操作无意义,所以不标出。

音量旋钮的例子明确指出其为NoWrap,Linear,NoPreferred,可见旋钮不是循环旋转,输出值与旋转角呈线性关系,旋钮释放开时会停留在释放前位置(因为NoPreferred)。

NoNullPosition/NullState:

主项目对应的操和有一个状态,其不会送出有意义的数据,即数据将不在LogicalMinimum和LogicalMaximum之间,这种操控要标注NullState,否则为NoNullPosition。

例如几个按键,而无键被按下的用途没有声明在Usage之列,则可以在主项目的数据中设NullState,将无键被按下的状态排除在LogicalMinimum和LogicalMaximum区间之外,进一步请参看UniversalSerialBusHIDUsageTables文件的AppendixA.3节中例。

NonVolatile/Volatile:

主项目Feature的数据不允许被主机改变(设为NonVolatile),或是允许被主机改变(设为Volatile)。

注意主项目Input和Output,此标注设定无意义,所以bit7的代码必须为0。

BitField/BufferedBytes:

主项目的数据格式要以字节为单位,不足构成字节时自动填充成字节则设BufferedBytes。

最后来谈谈主项目的其它二个卷标:

Collection和EndColle

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2