先记录下来:
http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/drivers/usb/input/hid-core.c?v=2.6.11.8#L640
625 /* 626 * Parse a report description into a hid_device structure. Reports are 627 * enumerated, fields are attached to these reports. 628 */ 629 630 static struct hid_device *hid_parse_report(__u8 *start, unsigned size)
参考HID_11 spec,APPENDIX D AND HID USAGE TABLE SPEC, P134 for push/pop usage.
246 /* 247 * This is the global environment of the parser. This information is 248 * persistent for main-items(my comment : save env in current collection, purpose is to remove duplicated global item). The global environment can be saved and 249 * restored with PUSH/POP statements. 250 */ 251 252 struct hid_global { 253 unsigned usage_page; 254 __s32 logical_minimum; 255 __s32 logical_maximum; 256 __s32 physical_minimum; 257 __s32 physical_maximum; 258 __s32 unit_exponent; 259 unsigned unit; 260 unsigned report_id; 261 unsigned report_size; 262 unsigned report_count; 263 };
结合 http://group.chinaaet.com/122/8005
code char MouseReportDescriptor[63] = {
/*
Unsigned integer specifying the current Usage
Page. Since a usage are 32 bit values, Usage
Page items can be used to conserve space in a
report descriptor by setting the high order 16 bits
of a subsequent usages. Any usage that follows
which is defines 16 bits or less is interpreted as a
Usage ID and concatenated with the Usage Page
to form a 32 bit Usage.
*/
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
// 0x9 = 0000 10 01 -> type is local type, go to local items section in HID spec,
// 0000 means USAGE tag, 01 means 1 byte data which is usage id, data is 6 meaning "Keyboard" in HID usage table spec.
0x09, 0x06, // USAGE (Keyboard)
//0xa1 = 1010 00 01 -> type (00) is main type, go to main items section in HID spec,
// 1010 means Collection tag, data 0x01 means "Application (mouse, keyboard)"
0xa1, 0x01, // COLLECTION (Application)
// 0x5 = 0000 01 01, type is global item, 0000 means usage page, 0x07 means Keyboard/Keypad Page in HID usage table spec
0x05, 0x07, // USAGE_PAGE (Keyboard)
// 0x19 = 0001 10 01, type is local type, go to local items section in HID spec, 0001 means Usage Minimum, 0xe0
//means USAGE_MINIMUM in HID spec, in HID usage table spec, it means Keyboard LeftControl.
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,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x03, // INPUT (Cnst,Var,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,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x03, // REPORT_SIZE (3)
0x91, 0x03, // OUTPUT (Cnst,Var,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
};
一般的,网文多是如上的报告描述符,据说是用一个工具产生的,有一些还配上了中文的说明,但也多是描述性的,而不是拆分解释这些字符所代表的含义,比如,数组第一行的 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
我们一眼就能看出双斜线后面的文字,是对前面数字的说明,即0x05,0x01所表达的是USAGE_PAGE (Generic Desktop) 的含义,但是,为何如此表达,则描述的不太清楚,对于熟悉的人而言,这自然不是问题,但对于新手,可就要费点功夫了。
0x05, 0x01,代表USAGE_PAGE (Generic Desktop) 的功能,是由《device class definition for human interface device (HID)》第24页的Report Descriptors 规定的。
分两部分,0x05为一部分,表示前缀,0x01为数据部分。
0x05转换成二进制,就是0000 01001,按照HID类协议5.3 generic item format的定义,这个字节被分成3个部分,bit0~bit1代表的是这个前缀后面跟的数据长度,两位可以表示最大4字节的数据,即bsize;bit2~bit3代表的是这个前缀的类型,总共可以有三种类型:0=main,1=global,2=local,3=reserved;bit4~bit7代表前缀的tag,一般分为input(二进制的1000 00 nn,即bit4~bit7=1000,代表一个tag,bit2~bit3=00,代表main,bit0~bit1=nn,代表这个前缀后面还有nn所代表的数据),output(二进制的 1001 00 nn),feature(1011 00 nn),collection(1010 00 nn),end collection(1100 00 nn),遵照这个原则,我们就可以解析0x05所表达的含义。
0x05转换为二进制就是0000 0101,其高4位全为0,表示的tag为usage page tag(协议45页),bit2~bit3=01,表示的是类型,从协议中可以知道,这是一个全局类型的item(协议36页),bit0~bit1=01,表示的是这个前缀后面跟着的数据长度为1字节,即0x05后面,有0x01作为这个前缀的数据部分,而0x01表示的是general desktop page(《universal serial bus HID usage table》第五页,目录),因此,这两个数字合起来就是USAGE_PAGE (Generic Desktop)的含义。
总之,要了解报告描述符,需要两份资料:《device class definition for human interface device (HID)》, 《Universal Serial Bus HID Usage Tables》