HID报表描述符大全及实例分析
+ -

USB键盘与HID报表描述符关系

2021-05-07 3654 14

报告描述符确实非常复杂,要看懂协议真得比较难(因为只有英文的),我见到的国内教材也没有对这部分写得很详细的,有的也只是部分内容的翻译而已。

一般建议用示例报告描述符修改一下就可以了,《Hid Usage Table》里给出了一些常见应用的报告描述符。对于键盘类应用,通常用已有的示例已经够用了。

“如果是102键,一个8字节的输入数据报告怎么可能对应到102键(假如每一位对应一个键的ON/OFF,也只能对应64个键啊”,应该是你对键盘输入机制不理解造成的,包括传统PS2接口键盘是同样的机制。当键盘一个键按下到弹起过程,其实会发两个数据,一是按下时,会发送对应键按下的数据包,弹起时又会发一次此键没有按下的状态数据包。

为什么第一个字节对应这几个键呢,可以看报告描述符,第一个字节的用途定义(USAGE_MINIMUM)是:

    //用途最小值,这里为左ctrl键      
    0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)

    //用途最大值,这里为右GUI键,即window键      
    0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)

查查《Hid Usage Table》,是不是正好对应八个特殊功能键?

那为什么说用位来代表八个键呢,而不是一个字节代表呢,同样看报告描述符,由逻辑最小值(LOGICAL_MINIMUM)、逻辑最大值(LOGICAL_MAXIMUM)、报告大小(REPORT_SIZE0)、报告个数(REPORT_COUNT)决定的:

    //逻辑最小值为0      
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)      
    //逻辑最大值为1      
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)      
    //报告大小(即这个字段的宽度)为1bit,所以前面的逻辑最小值为0,逻辑最大值为1      
    0x75, 0x01,                    //   REPORT_SIZE (1)      
    //报告的个数为8,即总共有8个bits      
    0x95, 0x08,                    //   REPORT_COUNT (8)

因为逻辑最大值是1,最小值是0,而且报告大小是1个bit,而且报告数为8个,所以正好是一个字节,注意这里不能用八个字节来表示。如果报告大小REPORT_SIZE是8,即8位,报告数REPORT_COUNT为1,那就是一个字节,如果报告数REPORT_COUNT也是8,那就是八个字节。看一看报告里的对那一个字节的输出报告定义可以加强认识。

学习报告描述符应先理解报告描述符的结构组成。下面是提取出来的关于输入报告的定义,第一个字节:

    //表示用途页为按键      
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)      

    //用途最小值,这里为左ctrl键      
    0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)      
    //用途最大值,这里为右GUI键,即window键      
    0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)      
    //逻辑最小值为0      
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)      
    //逻辑最大值为1      
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)      
    //报告大小(即这个字段的宽度)为1bit,所以前面的逻辑最小值为0,逻辑最大值为1      
    0x75, 0x01,                    //   REPORT_SIZE (1)      
    //报告的个数为8,即总共有8个bits      
    0x95, 0x08,                    //   REPORT_COUNT (8)      
    //输入用,变量,值,绝对值。像键盘这类一般报告绝对值,      
    //而鼠标移动这样的则报告相对值,表示鼠标移动多少      
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)      
    //上面这这几项描述了一个输入用的字段,总共为8个bits,每个bit表示一个按键      
    //分别从左ctrl键到右GUI键。这8个bits刚好构成一个字节,它位于报告的第一个字节。      
    //它的最低位,即bit-0对应着左ctrl键,如果返回的数据该位为1,则表示左ctrl键被按下,      
    //否则,左ctrl键没有按下。最高位,即bit-7表示右GUI键的按下情况。中间的几个位,      
    //需要根据HID协议中规定的用途页表(HID Usage Tables)来确定。这里通常用来表示      
    //特殊键,例如ctrl,shift,del键等

注意,对于输入或输出都要规定用途页(USAGE_PAGE),上面规定的用途页是键盘。第二个字节:

    //这样的数据段个数为1      
    0x95, 0x01,                    //   REPORT_COUNT (1)      
    //每个段长度为8bits      
    0x75, 0x08,                    //   REPORT_SIZE (8)      
    //输入用,常量,值,绝对值      
    0x81, 0x03,                    //   INPUT (Cnst,Var,Abs)

由于报告有继承性,所以第二个字节的用途页、用途最大最小值、逻辑最大最小值是和第一个字节一样的,但最后那句,定义了第二个字节是个常量,所以它应该是不变的,所以这里没有实际意义。
后面6个字节:

    //报告个数为6      
    0x95, 0x06,                    //   REPORT_COUNT (6)      
    //每个段大小为8bits      
    0x75, 0x08,                    //   REPORT_SIZE (8)      
    //逻辑最小值0      
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)      
    //逻辑最大值255      
    0x25, 0xFF,                    //   LOGICAL_MAXIMUM (255)      
    //用途页为按键      
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)      
    //使用最小值为0      
    0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))      
    //使用最大值为0x65      
    0x29, 0x65,                    //   USAGE_MAXIMUM (Keyboard Application)      
    //输入用,变量,数组,绝对值      
    0x81, 0x00,                    //   INPUT (Data,Ary,Abs)      
    //以上定义了6个8bit宽的数组,每个8bit(即一个字节)用来表示一个按键,所以可以同时      
    //有6个按键按下。没有按键按下时,全部返回0。如果按下的键太多,导致键盘扫描系统      
    //无法区分按键时,则全部返回0x01,即6个0x01。如果有一个键按下,则这6个字节中的第一      
    //个字节为相应的键值(具体的值参看HID Usage Tables),如果两个键按下,则第1、2两个      
    //字节分别为相应的键值,以次类推

后面六个字节为什么是一个字节代表一个键呢,同样是由逻辑最小值(LOGICAL_MINIMUM)、逻辑最大值(LOGICAL_MAXIMUM)、报告大小(REPORT_SIZE0)、报告个数(REPORT_COUNT)决定的,用途最小值0和最大值对应hid usage table里的定义,参考表Table 12: Keyboard/Keypad Page。其实逻辑最大值和最小值之差为255,其实一个字节就可以表示255个键了。只不过一个字节不能同时表示所有键按下。

那么上面定义的报告描述符能用一个数据包表示多少个键按同时下呢,答案是8+6=14个,8个特殊功能键,用第一个字节的八个位表示,最后面的6个字节只能表示6个键同时按下。现在举几个例子来验证一下你对输入报告定义的8个字节的理解。

1、只按下左Shift时发送的八个字节:

按下时发送一次:0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00
弹起时发送一次:0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

2、只按下A键时:

按下时发送一次:0x00 0x00 0x04 0x00 0x00 0x00 0x00 0x00
弹起时发送一次:0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

3、同时按下A键和左Shift键时:

按下时发送一次:0x02 0x00 0x04 0x00 0x00 0x00 0x00 0x00
弹起时发送一次:0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

4、同时按下左Ctrl左Alt和A键时:

按下时发送一次:0x05 0x00 0x04 0x00 0x00 0x00 0x00 0x00
弹起时发送一次:0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

5、同时按下A键和B键时:

按下时发送一次:0x00 0x00 0x04 0x05 0x00 0x00 0x00 0x00
弹起时发送一次:0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
HID人机交互QQ群:564808376    UAC音频QQ群:218581009    UVC相机QQ群:331552032    BOT&UASP大容量存储QQ群:258159197    STC-USB单片机QQ群:315457461    USB技术交流QQ群2:580684376    USB技术交流QQ群:952873936   

0 篇笔记 写笔记

HID键盘设备数据抓包分析实践
本文使用 Bus Hound 工具对 USB HID 设备数据包进行分析,并结合官方手册及网上文章进行整理。在进行数据分析前,我们先回顾一下USB相关的基础知识。USB描述符USB 主机是通过各种描述符来识别设备的,有设备描述符,接口描述符,端点描述符,字符描述符,报告描述符(HID)等。和普通的......
USB键盘报告描述符数据格式分析
USB键盘HID报表描述符的内容参见下表。数据的输入端点为中断方式,当有键盘敲击事件时,会上报数据长度为8字节的数据报告。0x05,0x01,// Global Generic Desktop0x09,0x06,// Local KeyBoard 0xA1,0x01,// Main app col......
HID 报表描述符键盘实例
通过下面的报告描述符的定义,我们根据上面的注释可知,包含一个中断输入报表描述符和一个中断输出报告描述符。其中断输入报告描述符用于USB HID键盘中断输入端点,输出报表描述符用于USB HID键盘中断输出端点。USB HID键盘的中断输入报告对于中断输入端点,数据格式定义如下:BYTE0:该字......
BIOS下识别USB键盘
在BIOS下要识别一个USB键盘和在操作系统下识别一个USB键盘其实是有一些区别的:首先接口描述符中bInterfaceClass的值必须为0x03,bInterfaceSubClass的值为0或1,为1表示HID设备符是一个启动设备(Boot Device,一般对PC机而言才有意义,意思是BIO......
为什么Windows7重新安装系统后插在USB3.0端口的鼠标不能使用?
在 Windows 7 及更早版本的操作系统中,USB 3.0 驱动程序堆栈由第三方提供,操作系统不提供USB3.0驱动栈。 因此,Windows7重新安装系统后插在USB3.0端口上的所有设备都无法工作,需要安装第三方提供的USB控制器和集线器驱动,这样才能识别出挂接在该USB总线下的设备。从Wi......
USB键盘HID报表描述符关系
报告描述符确实非常复杂,要看懂协议真得比较难(因为只有英文的),我见到的国内教材也没有对这部分写得很详细的,有的也只是部分内容的翻译而已。一般建议用示例报告描述符修改一下就可以了,《Hid Usage Table》里给出了一些常见应用的报告描述符。对于键盘类应用,通常用已有的示例已经够用了。“如果是......
HID报表描述符与设备描述符、配置描述符、字符串描述符的通讯格式对比
报表描述符是USB HID规范中一个很重要的概念。USB HID设备报表描述符内容表述了该HID设备的功能及数据传输的格式。USB HID报表描述符在概念上和设备描述符,配置描述符,接口描述符,端点描述符和其它USB设备描述符类似,但是还是有一些细微的区别。我里我们做一个简要的区别:设备描述符、......
HID复合设备(键盘、鼠标)的实现
在使用一些USB键盘或鼠标的时候,特别是一些电竟高档HID设备时,经常发现这些设备会额外定义一些特别的快捷键,使得这些设备不仅有基础设备(如键盘,鼠标)的功能,也有一些特别的快捷功能(如系统声音的放大放小)。甚至更有一些复杂的设备,只需要一个USB接口,就同时支持鼠标键盘功能或在键盘的额外区域支持触......
USB HID键盘设备树及设备枚举过程分析
今天在本站USB中文网微信技术交流群有一个同学在问关于HID设备的报表描述符的东东。但是在问的过程中发现一个很严重的问题,那就是它的它设备是一个复合设备,导致设备树比较复杂,关于报表描述符与接口描述符等之间的相关对应关系不是很清楚。为此,本人手中刚好有一个本人认为USB HID设备中相对比较复杂的设......
Windows下通过USB虚拟的键盘鼠标总结
产品级详见:https://www.usbzh.com/article/detail-1182.html哐哐铛铛的,终于把以前搞的虚拟键盘、鼠标的驱动代码重新整理完成,并且在此基础上将USB虚拟的键盘和鼠标整合到一个驱动中。将键盘和鼠标的代码合并在一起的原因很简单:第一是为了验证自己写的这个虚......
USB键盘在Linux环境下一直返回NAK的输入端点和一直OUT数据的输出端点
群里有同学反馈,自己做的USB键盘在Windows下正常,但在Linux下就失败,想让帮忙分析一下原因。一个比较好的消息是他那边有USB总线分析仪,所以只需要抓包就可以进行分析了。最好开他给的抓包截图是样子的:从它的截图可以看到,USB键盘在获取了该键盘的HID报告描述符后,紧跟着一下发Report......
USB键盘HID设备示例
键盘是一个比较复杂的复合设备,其中接口0实现的是键盘功能,接口1又因为报告描述符分为三个HID设备。BUSHOUND下的设备ID关系:在BUSHOUND抓取该USB键盘的枚举过程:Device Length Phase Data ......
USB键盘鼠标芯片选型
型号协议功能时钟工作温度封装 CH93292.0 全速 Device串口转HID键盘/鼠标/自定义HID芯片,支持多种工作模式和串口通讯模式内置-40~+85℃SOP16 CH93282.0 全速 Device串口转HID键盘芯片,实现串口数据转US......
HID报表描述符原理解释
一个报表描述符主要是为了描述报表的结构以及用途。报表的结构主要由报表的字段的长度(size)、数量(count)、属性(输入、输出等)决定,而报表的用途则由 HID 用途表文档规定。下面我们还是从 Kinetis KL25 USB 例程指南—进阶篇中的 USB 鼠标的报表描述符入手,分析报表描述符......
USB键盘定义HID报告描述符一键关机、唤醒和睡眠功能
这是本人电脑的USB键盘复合设备中的一个HID功能,用于实现一键关机,唤醒机器和一键进入睡眠状态。使用USB标准请求及描述符在线分析工具http://www.usbzh.com/tool/usb.html 分析该报告描述符0x05, 0x01, // Usage Page (Gene......
关注公众号
  • HID人机交互
  • Linux&USB
  • UAC音频
  • TYPE-C
  • USB规范
  • USB大容量存储
  • USB百科
  • USB周边
  • UVC摄像头
  • Windows系统USB
  • 音视频博客
  • 取消
    感谢您的支持,我会继续努力的!
    扫码支持
    扫码打赏,你说多少就多少

    打开支付宝扫一扫,即可进行扫码打赏哦

    您的支持,是我们前进的动力!