如何在 USB HID 报告中发送 Unicode?

问题描述 投票:0回答:1

有一个问题,其几乎是一个确切的名字。答案表明,对于(一般)Unicode 字符,他的解决方案取决于操作系统。

但是,HID 使用表 1.5 文档有一个专用于 Unicode 的使用页面,即

Unicode Page (0x10)
,其中指出

The Unicode Page directly maps to the two-octet form defined in the Unicode Standard.

The Unicode Standard, Version 1.1, is the newest version of the Unicode™ Standard. Unicode 1.1 includes the changes and
additions that were made to Unicode 1.0 in the process of alignment with the international character encoding standard,
ISO/IEC 10646-1, which was approved by ISO/IEC as an International Standard in June 1992, and published in May
1993. The character content and encoding of Unicode 1.1 is thus identical to that of the ISO/IEC 10646-1 UCS-2 (the
two-octet form).

从中我了解到有一个独立于操作系统的解决方案,即。您可以发送编码为 16 位的原始 Unicode(又名 UCS-2?)。

在这种情况下,对于一般 Unicode 字符来说,8 字节 USB HID 报告会是什么样子?

例如,如果我想将单个字母小写

a
按键从USB HID设备(例如键盘)发送到USB HID主机(例如PC),我可以这样做:

uint8_t hid_report[0x08];
hid_report[0x00] = 0b00000000;
hid_report[0x01] = 0x00;
hid_report[0x02] = 0x04;
hid_report[0x03] = 0x00;
hid_report[0x04] = 0x00;
hid_report[0x05] = 0x00;
hid_report[0x06] = 0x00;
hid_report[0x07] = 0x00;

并且它可以工作(即 USB HID 主机驱动程序识别按键)。

现在,我认为主机驱动程序对 USB HID 报告的解释取决于设备发送到主机的 USB HID 报告描述符,在本例中为:

0x05,0x01,       // Usage Page: Generic Desktop Page (0x01), page HID Usage Tables 1.4
0x09,0x06,       // Usage:      Keyboard (0x06)
0xa1,0x01,       // Collection: Application
    0x05,0x07,       // Usage Page:      Keyboard/Keypad Page (0x07)
    0x19,0xe0,       // Usage Minimum:   0xe0: kbd lctrl
    0x29,0xe7,       // Usage Maximum:   0xe7: kbd rgui
    0x15,0x00,       // Logical Minimum: 0
    0x25,0x01,       // Logical Maximum: 1

    0x95,0x08,       // Report Count:    8  // 8 keys? mod mask
    0x75,0x01,       // Report Size:     1  // 1 bit each?
    0x81,0x02,       // Input:           Data,Var, Abs,No Wrap,Linear,Preferred State,No Null Position

    0x95,0x01,       // Report Count:    1  // 1 key? pad
    0x75,0x08,       // Report Size:     8  // 8 bits each?
    0x81,0x03,       // Input:           Const,Var, Abs,No Wrap,Linear,Preferred State,No Null Position

    0x05,0x07,       // Usage Page:      Kbrd/Keypad
    0x19,0x00,       // Usage Minimum
    0x29,0xff,       // Usage Maximum  // 0x65 is the max for a boot device?
    0x15,0x00,       // Logical Minimum
    0x26,0xff,0x00,  // Logical Maximum  // 0x65 is the max for a boot device?  // 0x25: int8? 0x26: int16?

    0x95,0x06,       // Report Count:    6  // 6 keys? 6 keys (6KRO)
    0x75,0x08,       // Report Size:     8  // 8 bits each?
    0x81,0x00,       // Input:           Data,Array, Abs,No Wrap,Linear,Preferred State,No Null Position
0xc0,            // End Collection

但我认为可以对 USB HID 按键/按键释放报告使用完全不同的二进制布局,例如一个大位掩码,其中键盘中的每个键对应于 USB HID 报告中的 1 位。在这种情况下,Unicode 字符的报告描述符也会发生变化。那么,如何在位掩码 USB HID 报告中发送 16 位编码的 Unicode 字符呢?

(请注意,此 USB HID 报告已包含前 8 位的位掩码表示;即修饰符被编码为 8 位位掩码。)

额外问题:如何发送 UCS-2 无法编码的 Unicode 字符?

unicode keyboard usb hid utf-16
1个回答
0
投票

让我分享一下我对你的问题的看法。

键盘使用页面

您设备的 USB HID 报告描述符显示两个不同的键盘使用页面 (0x07)。

第一页用于使用 ID 0xe0 到 0xe7,这将代表八个控制键。该设备可以同时发送全部 8 个。每个键的可能值:0 或 1(2 个值,一位)。

第二页用于使用 ID 0x00 到 0xff,这将代表 256 个“正常”密钥。该设备只能同时发送其中 6 个 (6KRO)。每个密钥的可能值:0x00 到 0x00ff(256 个值,八位)。

注 1:描述符使用 16 位值作为“逻辑最大值”(使用标签 0x26),但实际数据仍限制为 256 个值,并且“报告大小”仅为 8 位。

注 2:使用 ID 0xe0 至 0xe7 出现在两个键盘使用页面中。我知道第一页优先于此范围(即这八个代码将被解释为控制键的位图,而不是键代码)。

注3:对于第二页,256个值中的每一个都代表一个键位置,在规范中标记为美式键盘中该位置的字符。 (如有必要,本地键盘“重新解释”在主机上完成。)

Unicode 使用页面

Unicode 使用页面完全不同,它只发送 16 位值,这些值将被解释为 UCS-2 编码字符(16 位 Unicode 的旧的受限形式)。如果您的主机系统“理解”UCS-2,那么这应该可以顺利进行。

但是根据您发布的内容,您的设备不支持 Unicode 使用页面。

自定义使用页面

您可以在设备上定义自己的使用页面,以您喜欢的任何方式编码任何类型的数据。当然,您的主机应该理解这个自定义代码页。 (其他主机必须忽略它。)

但是,有一个限制。 《HID 使用表》(1.5 版)第 3.1 节明确指出:

使用 ID 值限制为 16 位

因此,即使使用您自己的页面/编码,您也无法识别超过 2^16 个单独的字符/实体。至少在一页中。

关于使用很长的位图同时发送大量(最多 2^16)个字符的可能性,我认为这可能会超出规范中的另一个限制。

© www.soinside.com 2019 - 2024. All rights reserved.