USB的报告描述符(2)

这节主要就是分析一些报告描述符

下面就是我们游戏操作杆的报告描述符

       上面的游戏操作杆一来就是定义了一个油门加速器(Throttle),也可以是个旋钮,主机根据用户的调节程度控制游戏,其逻辑范围是-127~127,所以需要一个字节来表示。既然已经是按字节方式对齐,所以也就不需要位填充了。然后我们再定义一个指针实体,它对应方向舵的方向控制,相应的逻辑值范围就还是之前的-127到127.

        接下来我们定义了一个控制角度的苦力帽开关,他的逻辑值为0~3,然后使用Physical Minimum与Physical Maximum 定义了实体范围为0~270,紧接着又使用了Unit标签,那这个是什么意思呢。这就是报告描述符的量纲系统了

我们曾经在音量系统的时候定义了相应的逻辑范围,他们只能从逻辑上代表音量调节的范围,但是每次调整操作具体对应改变多大的音量呢?假设这个音箱的音量实际可调节范围为0~100dB值,而报告描述符定义的逻辑值为0~100,那是不是代表我们逻辑值50就是对应音量50呢,实际是不一定的,这是因为本身我们的逻辑值本身并没有单位而引起的。Physical Minimum与Physical Maximum还有Unit就是用来定义度量单位的物理量标签。

如果我们定义逻辑值时候使用了Physical Minimum与Physical Maximum两个标签,就是给我们的逻辑值增加了一个单位,具体每个逻辑值对应多大实际音量。其实可以把它当成分辨率。他有个计算公式,如下:

这上面有个Unit Exponent表示单位指数,它表达了逻辑值和实体值的对应关系,范围是-8~7,半个字节。如果没用Unit Exponent标签定义单位数据,就默认为0,分辨率越大,逻辑值影响的越小,如下图,成线性对应关系:

有一个注意的,就是我们必须同时定义Physical Minimum与Physical Maximum两个标签,如果其中任意一个没有被定义,或者它们都被定义为0,则表示实体值范围与逻辑值范围相同(Physical Minimum =Logic Minimum  与Physical Maximum = Logic Maximum 

指定单位的就是Unit,我们指定的实体值到底是时间,长度,角度还是其他属性呢,具体如下图:

某鼠标标签如下图:

这两个应该是搞反了,计算得到的分辨率为

(127-(-127))/(3175-(-3175)✖10^-4)= 400dpi;(dpi,指的是每一英寸长度中取样)

当我们使用HID编辑工具的时候,双击UINTS就会弹出以下东西,

Angle为1度,表示一个单位的实体值代表1度,Physical Minimum(0)与Physical Maximum(270)定义的角度为0~270.其实单位的定义并不是必须的,至少游戏操作杆驱动程序会对设备返回的逻辑值范围内给您处理的。

后面回到游戏操作杆的报告描述符,在定义完苦力帽开关后又定义了4个按钮,然后Unit(none)和Unit Exponent(0)表示取消单位指数(逻辑值与实体值为线性对应关系)。

最后的输入报告如下图:

下面再看一个比较复杂的带显示装置的设备,它可以显示2✖16个字符。

这个报告描述符虽然有点复杂,但是理解的关键在于Report ID和Feature标签。

首先我们看Report ID标签。

假设一个设备可以工作于多种模式,虽然每种模式发送数据比较少,但是一旦模式多了,这数据以下也就多起来了,由于设备仅会处于一种工作模式,这就意味着每次传输中的大部分数据是无效的,为了更有效率地进行数据传输,我们可以把原来的长报告分解成多个短报告,它们就是对应每种模式,这样每个短报告就不会存在过多的资源浪费。

下图有两种不同的报告规划方案:

我们为了在同一个端点传输多个不同的报告,我们需要使用Report ID标签给每个报告赋予一个唯一的值,其是从1开始的正整数,并且总是处于报告(含Input,Output,Feature)的第一个字段。如果报告描述符中没有使用Report ID标签,则表示只有一个报告,相应的报告ID就是0。如果我们决定使用报告ID,那么应该至少在第一个Input,Output,Feature标签前定义非0的报告ID,因为每个报告都要求有一个报告ID。另外,在同一个报告描述符中,相同的报告ID可以在不同的地方多次使用,但是它们仍然代表同一个报告。

我们主机获取或设置相应的报告,对于HID设备,我们可以使用“获取报告(GET_REPORT)”或“设置报告(SET_REPORT)”特定类请求,其中wValue字段的高字节对应报告类型,低字节则对应报告ID,如果没有使用Report ID标签,可以将报告ID设备为0.

接下来我们看看Feature标签可以用来生成什么字段:用来描述可以发送给设备的配置信息

这是什么意思呢?

我们以鼠标为例,单机,右击,中键等操作都会产生输入报告,这些都是我们正常使用的时候产生的报告,但是我们鼠标本身也有一些属性可以在操作系统的控制面板中调整。比如我们的光标大小,形状,颜色,双击速度,轨迹长度等等,这些都不是正常使用鼠标的过程中可以正常改变的,而Feature标签就可以用来描述这些属性(要记住哈,我们鼠标这些特征都是从操作系统层面实现的,并没有在报告描述符中指定,仅仅用来方便理解特征),相当于另外开辟了一个通道来改变设备的特征了。 

有玩过一些几百块的机械键盘的,它们的上位机就是通过这个Feature标签来改变底下键盘的。

这些应用程序,可以对配套设备的一些参数(特征)进行配置,主机可以通过使用“设置报告(SET_REPORT)”请求给设备发送特征报告的方式来完成。

HID用途表 将用途分为控制,数据,集合三个类别,上一章说了控制和集合,现在说一下数据:

数据类用途用于定义设备与主机之间传输的(除控制类用途外)特征信息,实际使用的时候需要特别注意生成数据字段时使用的标记,

“选择符”用于从一个集合选出一个,多个或任意个值。

举个例子,对于显示装置来说,它在刚上电时需要进行初始化过程,此时这个显示装置是处在还没装备好的状态(Not Ready),直到初始化完成以后才进入已准备好状态(Stat Ready),这两个状态就是设备的特征并且它们是相斥的,一个设备不可能同时处在未准备好,准备好的状态,这时候我们可以使用Array定义一个输入数据字段来向主机报告该状态,就算不是互斥的也可以使用Array定义多个数据字段。

“静态值”用于声明设备的固定特征,它声明的字段是不可以修改的。

对于我们的显示设备来说,显示的字符,高度,水平间距,垂直间距等特征是不变的,所以它们被声明为静态值数据类用途。

“静态标记”用来声明设备存在某个固定特征

如果我们的报告描述符中使用了“静态标记”,那么相应的字段必须由主机读取以确定相应的特征是否存在(0表示不存在,1表示存在)。

“动态标记”声明设备中存在一个可以由主机控制的特征。

对于我们的显示装置来说,光标的模式,使能,以及闪烁都是可以改变的。

“动态值”则是一个包含与某个控制相关的多位数据字段

相关的主标签应该设置Data与Variable标记,它与“动态标记”一样,必须声明成数据(而不是常量),例如我们显示装置中的显示数据和代表光标位置的行与列信息

接下来让我们回到显示设备的报告描述符,我们一个一个来看:

第一段 ,第一个Report ID(1),

”Display Attributes Report“属于逻辑集合(CL)用途类型,所以我们使用Collection(Logic),

在这个逻辑集合中我们定义了显示行数,显示列数,字符宽度,字符高度,共四个用途,逻辑值范围为0~31,所以需要定义4个五位数据,它们都是表示绝对状态的常数。然后我们又定义了3个一位逻辑值范围为0~1的字段,它们分别代表了ASCII设置,垂直卷动,数据读回三个特征,前面已经定义了23位,不是字节对齐的所以我们再定义了一位填充字段。

“Character Attributes”逻辑集合中定义了三个一位逻辑范围为0~1的字段,分别代表显示装置支持反白显示,下画线,闪烁三个特征,

下图就是上面的相应特征报告

接下来我们定义了一个输入报告,如下图

由于Report ID是全局标签,只要还没改变,下面ID就还是1

他是一个八位的数据,逻辑值最大定义2,这是一个输入装置,当我们的显示装置状态发生改变的时候,中断端点会产生输入报告,它包含未准备好状态已准备好,不可加载字符错误,相应报告如下。

然后又定义了 两个用于设置与获取当前光标位置的特征报告

其报告ID为2,包含了各占用4位的行数与列数字段。相应的特征如下图

主机与显示设备之间可以有多种数据传输方式。例如,一次一字节,多个字节,或32字节(整屏数据),所以又进一步定义了连续写入到设备的4个显示数据与4个字符属性的缓冲字段,相应报告如下:

报告 4如下

最后就是简单说一下Push和Pop,它们分别用于将当前标签状态复制到栈空间保存,然后可以用Pop取出,假如我们一开始定义了一些全局状态,后面结果要用这个全局状态定义其他字段,就可以用Push标签保存起来,然后再用Pop出来,如果还要用,就在Pop后面马上接着Push就好了。

用的不多 了解一下就好。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值