USB HID Keyboard 建立

  • USB HID ( Human interface device - 人类界面装置 )
  • HID 为许多USB定义的装置类别之一
  • HID协定中有两个实体:主机(host)和装置(device)。装置是直接与人类互动的实体,例如键盘或鼠标;主机则是负责与装置通信并接收人类在装置上输入的资料。
  • 装置定义它们的封包,然后向主机呈递“HID描述符”。HID描述符是描述装置的封包的写死位元组阵列。
  • USB HID - Keyboard 描述符
  • Device Descriptor
 

  • Configuration Descriptor
 

  • Interface Descriptor
根据 USB-IF 协定规范,将键盘归类在 HID 类,相关配置如下:
bInterfaceClass 设置为 0x03,HID 类
bInterfaceSubClass 设置为 0x01,支持 Root 启动
bInterfaceProtocol 设置为 0x01,键盘


  • HID Descriptor
 

  • EndpointDescriptor
 

  • Report Descriptor
一个标准键盘,标准键盘会包含 101 个按键、8 个组合键 (modifiers)、1 个保留键以及 5 个指示灯 ( LED )。也就是说,我们要送按键的资料给 host,这会需要:一个 byte 代表一个组合键,一个 byte 代表保留键,以及 1~6 个 byte 表示按键敲击。

组合键包括从键盘左边的 Ctrl、Shift、Alt、GUI (WIN 键) 到右边的 Ctrl、Shift、Alt、GUI (WIN 键):
1. 首先定义组合键
    USAGE_PAGE (Keyboard)
    USAGE_MINIMUM (Keyboard LeftControl)
    USAGE_MAXIMUM (Keyboard Right GUI)
2. 组合键状态不是 0 就是 1:
    LOGICAL_MINIMUM (0)
    LOGICAL_MAXIMUM (1)
3. 8 个组合键总共 8 个位元的资料要送给 hos:
    REPORT_SIZE (1)
    REPORT_COUNT (8)
    INPUT (Data,Var,Abs)
4. 一个 byte 的保留键 : 

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

五颗 LEDs ( Num Lock, Caps Lock, Scroll Lock, Compose 和 KANA 这 5 颗 LEDs )
1. 首先定义 LEDs
    USAGE_PAGE (LEDs)
    USAGE_MINIMUM (Num Lock)
    USAGE_MAXIMUM (Kana)
2. LED 状态不是 0 就是 1 :
    LOGICAL_MINIMUM (0)
    LOGICAL_MAXIMUM (1)
3. 送给 host 的资料 :
    REPORT_COUNT (5)
    REPORT_SIZE (1)
    OUTPUT (Data,Var,Abs)
4. 其它 3 个位元是填充位元 :
    REPORT_COUNT (1)
    REPORT_SIZE (3)
    OUTPUT (Cnst,Var,Abs)

接着 6 个按键的 keycodes,每个按键占 1 byte,总共 6 个
1. 按键 keycode 最小值为 0,最大值为 101 :
    LOGICAL_MINIMUM (0)
    LOGICAL_MAXIMUM (101)
    USAGE_PAGE (Keyboard)
2. 键盘包括从 "no event indicated" 到 "Keyboard Application" 这 101 颗键 :
    USAGE_MINIMUM (Reserved (no event indicated))
    USAGE_MAXIMUM (Keyboard Application)
3. 传送给 host 的阵列变数资料 :
    INPUT (Data,Ary,Abs)

下图为完整的 Keyboard Report Descriptor
 

  • 实际操作分析
  • Host 的轮询机制会对所有 USB Device 请求 Interrupt 传输,若此时 Keyboard 有需要 Interrupt 传输,便可开始以固定的速率传送少量资料。

  • 透过 counter 定时将 Key code A 和 Key code ENTER 的参数代入对应于 Report Descriptor 的 Key code 位置,并以 Interrupt 的形式回传给 Host

  • 由 USB analyzer 分析可看到对应于 Interrupt 所传送给 Host 的 Key A

※ 将 USB_DeviceHidKeyboardAction() 函式的内容改为 key scan 的结果,并将 key scan 的结果透过 USB_DeviceHidSend() 的 Interrupt 函式回报给 Host 即为一完整的 keyboard 应用

★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★博文作者未开放评论功能