当前位置:文档之家› HID 报告描述符终极解析

HID 报告描述符终极解析

HID 报告描述符终极解析
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 0101

0000:Usage Page

01:bType,全局(bType = 0:主项目;bType = 1:全局项目;bType = 2:区域项目;)

01:bSize,1字节(BSize 用来指出项目的数据所需字节的数目,该数目仅可以为0(当bSize=0),1(当bSize=1),2(当bSize=2),和4(当bSize=3)﹔注意不可以为3个字节。大部分的卷标仅需一个字节的数据﹔全局项目的卷标Unit 比较特殊有可能最多用到4 个字节来表示其资料。)

0x01: Generic Desktop(查文档Universal Serial Bus HID Usage Tables,第三节Usage Pages)

0x09, 0x06, // USAGE (Keyboard)

0x09 = 00001001

根据HID短项目格式

0000:Usage

10:bType,区域项目

01:bSize,1字节

0x06:KeyBoard(查文档Universal Serial Bus HID Usage Tables,第四节)

0xa1, 0x01, // COLLECTION (Application)

0xa1:

0x01:

(卷标End Collection 没有跟随任何资料。但是卷标Collection 跟随一个字节的数据,例如指针的数据名为Physical,而鼠标的为Application。所有Collection的数据名称与代码如表7:表7:报告集合的名称与代码

Collection 的数据名称很难有一个准则来给定,Universal Serial Bus HID Usage Tables档中将各种用途的用途种类(usage type)列出,使用者必须依据用途种类来指定Collection 的数据名称,例如鼠标,键盘和游戏杆的用途种类为CA,所以要用Collection (Application),而指针为CP,所以用Collection (Physical)。)

0x05, 0x07, // USAGE_PAGE (Keyboard)

//分析

0x05 = 0000 0101

0000:Usage Page

01:bType,全局(bType = 0:主项目;bType = 1:全局项目;bType = 2:区域项目;)

01:bSize,1字节

0x07:KeyBoard(查文档Universal Serial Bus HID Usage Tables,第三节Usage Pages)

0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)

0x19= 0001 1001

0001: Usage Minimun

(

)

10: bType,区域项目(bType = 0:主项目;bType = 1:全局项目;bType = 2:区域项目;)

01:bSize,1字节

0xe0:Keyboard LeftControl(查文档Universal Serial Bus HID Usage Tables,10 Keyboard/Keypad Page (0x07))

0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)

// 分析同上“USAGE_MINIMUM (Keyboard LeftControl)”

0x15, 0x00, // LOGICAL_MINIMUM (0)

// 分析

0x15=0001 0101

0001 : LOGICAL_MINNUM(查报告描述符的标签中的全域项目Logical Minimum 01:bType,全局项目(bType = 0:主项目;bType = 1:全局项目;bType = 2:

区域项目;)

01:bSize,一个字节

0x00:最小值

0x25, 0x01, // LOGICAL_MAXIMUM (1)

// 分析同上“LOGICAL_MINIMUM (0)”

0x75, 0x01, // REPORT_SIZE (1)

// 分析

0x75 = 0111 0101

0111:Report Size(查报告描述符的标签中的全域项目Report Size)

01:bType,全局项目(bType = 0:主项目;bType = 1:全局项目;bType = 2:区域项目;)

01:bSize,一个字节

0x01:Report Size,单位bit。如Report Size(1),则表示报告的值只有一位,0或者1 如果Report Size(1),则报告的值有8bit,范围0~255.

0x95, 0x08, // REPORT_COUNT (8)

// 分析

0x95 = 1001 0101

1001:Report Count(查报告描述符的标签中的全域项目Report Count)

01:bType,全局项目(bType = 0:主项目;bType = 1:全局项目;bType = 2:区域项目;)

01:bSize,一个字节

0x08:Report Count,报告的字段。即报告多少个Report Size的大小。

如Report Size(1), Report Count(3),每次报告三个位的数据。

0x81, 0x02, // INPUT (Data,V ar,Abs)

//分析

0x81 = 1000 0001

这里要特别注意,这里要高6位和低2位拆分。

高6位含义:

01:字节数,1字节

0x02:参考附录一:主项目说明。

根据表格:

表6:主项目的信息代码

0x02 = 0000 0010

我们只关心最后三位INPUT (Data,V ar,Abs)

0:绝对值

1:变量

0:数据

以下分析与上面分析重复,在此略过。

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

//分析

Collection结束,不带任何数据

};

西伯利亚的风

2012/12/19

附件:

附录一:主项目说明

主项目

主项目中产生报告数据格式的三个卷标(Input,Output,和Feature)具有共通的数据定义,这些数据和其代码列于表6中。目前用到9个位来表示这些数据。如果第九位(bit 8)为0,则仅需用一个字节来表示该数据,即忽略第九位。如果第九位为1,就需用到二个字节来表示该数据。

表6:主项目的信息代码

Data/Constant:主项目之数据为可变值(设为Data),或为固定不可变值(设为Constant)。Constant 都用于Feature 的报告,或是用于填充位(padding),使报告长度以字节为单位。Array/V ariable:主项目之数据的每个字段可以表示几个不同的操作的其中一个被触发(设为Array),或是每个字段仅表示一个操作(设为V ariable)。如果是V ariable,则Report Count 的数据值等于报告数据的字段数。若是Array,则Report Count 的数据值表示可以同时被触发的最多操作数目。后文中键盘之例会解说Array 的用法。

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

【范例说明】前文中的音量操控范例,因为都是Data 和V ariable,二者的操作值皆为变化值,且一个字段仅表示一个操作。但是音量增减键的例子为Relative,所以若报告值由0 变成+1,则音量增大一个刻度,反之由0变作-1 则音量减小一个刻度,因而音量大小因输入值而作相对的变化。然而音量旋钮的例子为Absolute,当输入值为最小值0 时,为静音,而输入值为最大值100 时,为最大音量,其余值作百分比的音量调整,输入值和音量成绝对关系。No Wrap/Wrap:主项目的数据值达到极值后会转为极低值,反之亦同,称作卷绕(设为Wrap)。例如一个转钮可以做360°旋转,输出值从0 至10,若设定为Wrap,则值达10 后,在同方向旋转则值变为0,反之若达到0,再转就得到10。

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

Preferred State/No Preferred:主项目对应的操作再不被触发时会自动恢复到初始状态(设为Preferred State),或是不会恢复原状(设为No Preferred)。例如键盘的按键和会自动置中(self-centering)的游戏杆,皆为Preferred State。

【范例说明】再以音量操作为例,音量增减键的例子都没标注No Wrap,Linear,Preferred State,但是没有标注即认定其属于默认值,所以等同于是这些设定,只是这些设定对此例的操作无意义,所以不标出。音量旋钮的例子明确指出其为No Wrap, Linear, No Preferred,可见旋钮不是循环旋转,输出值与旋转角呈线性关系,旋钮释放开时会停留在释放前位置(因

为No Preferred)。

No Null Position/Null State:主项目对应的操和有一个状态,其不会送出有意义的数据,即

数据将不在Logical Minimum 和Logical Maximum 之间,这种操控要标注Null State,否则为No Null Position。例如几个按键,而无键被按下的用途没有声明在Usage 之列,则可以在主项目的数据中设Null State,将无键被按下的状态排除在Logical Minimum 和Logical Maximum区间之外,进一步请参看Universal Serial Bus HID Usage Tables 文件的Appendix A.3 节中范例。

Non V olatile/V olatile:主项目Feature 的数据不允许被主机改变(设为Non V olatile),或是允许被主机改变(设为V olatile)。注意主项目Input 和Output,此标注设定无意义,所以bit 7 的代码必须为0。

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

附录二

数据传输HID Report设置参考

1.code char MouseReportDescriptor[29] = {

2. 0x06,0x00,0xFF, //USAGE_PAGE (Vendor Defined Page 1)

3. 0x09,0x01, //USAGE (Vendor Usage 1)

4. 0xA1,0x01, //COLLECTION (Application)

5.

6. 0x19,0x01, //(Vendor Usage 1)

7. 0x29,0x08, //(Vendor Usage 1)

8. 0x15,0x00, //LOGICAL_MINIMUM (0)

9. 0x26,0xFF,0x00, //LOGICAL_MAXIMUM (255)

10. 0x75,0x08, //REPORT_SIZE (8)

11. 0x95,0x40, //REPORT_COUNT (64)

12. 0x81,0x02, //INPUT (Data,Var,Abs)

13.

14. 0x19,0x01, //(Vendor Usage 1)

15. 0x29,0x08, //(Vendor Usage 1)

16. 0x91,0x02, //OUTPUT (Data,Var,Abs)

17.

18. 0xC0 // END_COLLECTION

19.};

每次发送接收64Bytes。注意要设置端点的发送接收最大包长度为64.

相关主题
文本预览
相关文档 最新文档