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 應用

★博文內容均由個人提供,與平台無關,如有違法或侵權,請與網站管理員聯繫。

★博文作者未開放評論功能