Site Overlay

USB HID Report Descriptors – HID 报告描述符

它是什么, 有什么用?

首先我们了解一下什么是 HID 设备. HID 的全称是 Human Interface Device, 字面上看就可以知道 HID 设备就是人机交互设备. 例子: 鼠标, 键盘, 手写笔, 扫码枪.

USB HID 报告描述符(USB HID Report Descriptors)可以告诉宿主(操作系统)如何处置 HID 设备发来的数据. HID 设备和宿主通信自然要靠数据包, HID 报告描述符的作用, 就是描述数据包的数据结构. 我们看 eleccelerator 给的这个例子:

image-20200109205955845.png

假设数据包是上面这个格式, 那么它的结构体就是:

struct mouse_report_t
{
    uint8_t buttons;
    int8_t x;
    int8_t y;
}

实际发送的时候, 发送的数据就相当于三个整数拼起来的二进制. 所以你得让宿主知道这串二进制是什么意思.

于是我们开始描述二进制的意思, 下面描述的是右上角的三个bit

image-20200109210313398.png

USAGE_PAGE (Button)//开始一串 byte
USAGE_MINIMUM (Button 1)//最小值
USAGE_MAXIMUM (Button 3)//最大值
LOGICAL_MINIMUM (0)//逻辑最小值
LOGICAL_MAXIMUM (1)//逻辑最大值
REPORT_COUNT (3)//报告的总数量
REPORT_SIZE (1)//报告数量
INPUT (Data,Var,Abs)//提交报告

还有五个是填充的字节

image-20200109210738896.png

, 如此报告:

REPORT_COUNT (1)
REPORT_SIZE (5)
INPUT (Cnst,Var,Abs)

接下来报告 X 轴移动:

USAGE_PAGE (Generic Desktop)
USAGE (X)
LOGICAL_MINIMUM (-127)
LOGICAL_MAXIMUM (127)
REPORT_SIZE (8)
REPORT_COUNT (1)
INPUT (Data,Var,Rel)

Y 轴同理:

USAGE_PAGE (Generic Desktop)
USAGE (Y)
LOGICAL_MINIMUM (-127)
LOGICAL_MAXIMUM (127)
REPORT_SIZE (8)
REPORT_COUNT (1)
INPUT (Data,Var,Rel)

这两个可以合并写, 节省字节:

USAGE_PAGE (Generic Desktop)
USAGE (X)
USAGE (Y)
LOGICAL_MINIMUM (-127)
LOGICAL_MAXIMUM (127)
REPORT_SIZE (8)
REPORT_COUNT (2)
INPUT (Data,Var,Rel)

所以完整的报告就是这样的:

0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
0x09, 0x02,                    // USAGE (Mouse)
0xa1, 0x01,                    // COLLECTION (Application)
0x09, 0x01,                    //   USAGE (Pointer)
0xa1, 0x00,                    //   COLLECTION (Physical)
0x05, 0x09,                    //     USAGE_PAGE (Button)
0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
0x29, 0x03,                    //     USAGE_MAXIMUM (Button 3)
0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
0x95, 0x03,                    //     REPORT_COUNT (3)
0x75, 0x01,                    //     REPORT_SIZE (1)
0x81, 0x02,                    //     INPUT (Data,Var,Abs)
0x95, 0x01,                    //     REPORT_COUNT (1)
0x75, 0x05,                    //     REPORT_SIZE (5)
0x81, 0x03,                    //     INPUT (Cnst,Var,Abs)
0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
0x09, 0x30,                    //     USAGE (X)
0x09, 0x31,                    //     USAGE (Y)
0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
0x75, 0x08,                    //     REPORT_SIZE (8)
0x95, 0x02,                    //     REPORT_COUNT (2)
0x81, 0x06,                    //     INPUT (Data,Var,Rel)
0xc0,                          //   END_COLLECTION
0xc0                           // END_COLLECTION

有了这个报告, 当电脑读取到:0000 0011 0000 0100 0000 1000, 他就会知道你表达的意思是同时按下中键和右键(11), 并且 X 轴移动是 4(100), y 轴移动是 8(1000).

cf: https://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/

https://www.usb.org/hid

https://docs.microsoft.com/zh-cn/windows-hardware/design/component-guidelines/windows-precision-touchpad-sample-report-descriptors?redirectedfrom=MSDN

https://www.microchip.com/forums/m681090.aspx

3 thoughts on “USB HID Report Descriptors – HID 报告描述符

发表评论

电子邮件地址不会被公开。 必填项已用*标注