天天看點

[HID]Spec簡讀

簡述

USB協定在計算機中使用非常廣泛,在外部有USB裝置插入時,就會檢測到并進行初始化和啟動,而後遵循USB協定傳輸資料,供應用擷取來使用。

USB裝置種類過于繁多,是以被劃分為了不同的裝置類(Device Class),而HID(Human Interface Device Class,人機互動裝置類)就是其中尤為重要的一類。當然也還有許多其他的常見的裝置類:

[HID]Spec簡讀

什麼是HID

人機互動?還是比較籠統,HID具體的定義是“HID裝置是指那些可被用來控制和操作計算機系統的裝置”。其常見的一些舉例如下:

  • 鍵盤與指針裝置—-如标準mouse,trackballs, joystick
  • 面闆控制裝置—-如knobs, switches, buttons, and sliders
  • 在類似手機,VCR遙控器上的控制裝置—-如data gloves, throttles, steering wheels, and rudder pedals
  • 一些可能并不需要人輸入但輸出資料的控制裝置—-如bar-code readers, thermometers, voltmeters

HID裝置管理

HID裝置的資訊被存于其ROM中,被稱為descriptor(描述符,還是用英文更貼切)的結構,是以在設計實作自己的HID裝置時,弄清楚或者定義好descriptor應該是最為關鍵的一步。如下所示,descriptors組成了information和data:

[HID]Spec簡讀

而在裝置的不同階段和狀态,會涉及到許多不同類别的descriptor:

[HID]Spec簡讀

這其中HID開發時接觸最多的還是Report Descriptor了,因為Report Descriptor都被用來傳輸各類應用資料。

HID之是以要使用Report Descriptor,主要是擴充性考慮,用Report來表示其傳輸的資料類型,這樣對于不同的HID裝置,就不需要針對每個定義一個SubClass了。HID裝置一被檢測到,Report Descriptor就會被加載和解析。

Report Descriptor Format

Report Descriptor的資料組織形式是一個個的資訊段,每個資訊段稱為Item:

[HID]Spec簡讀

Item Format

上面提到的Item的格式表示如下:

[HID]Spec簡讀

Item的第一個byte可表示Item的類型,是long item或short item,如下是一個long item示例:

[HID]Spec簡讀

Item Parser

Item parser會從接收到的Report Descriptor資料中,逐個進行Item的抽取,每抽取一個就放在Item state table的對應位置。這就是Item parser的過程了:

[HID]Spec簡讀

當一個Main item被找到時,就需要配置設定并初始化一個report結構,并将其中的Local item放到這個report結構下。而Global item是對于所有report結構都适用的,隻是Global item會對其後面的所有的report結構都會起作用。

對于Push和Pop item的了解:

item state table相當于一個全局變量,隻能暫存一個item state table(表示一個Report Descriptor的整體資料),而另外有一個stack,可以将某一時刻的item state table的快照放到該stack當中,當後面的item state table全局變量改變了,要使用之前的item state table内容時,這時候stack中暫存的item state table就要起作用咯。

Usages

用來表明Report Descriptor中資料的用途的,一個Report Descriptor中是會有多個usage的,因為其中資料本來就是分片的(items)。

Usage劃分為Page和ID組合的方式,這樣可以表示更多用途,即通過兩級來區分用途,首先是用途page,然後對應用途page下的用途ID:

[HID]Spec簡讀

Reports

Report是HID最終實際用來進行有用資料傳輸的,前面的Usage在HID裝置剛接入時,就會被讀取,而Report Descriptor被Host讀取後,HID Device可以向Host發送Reports,也可以從Host接收Reports。有三種Reports類别:

[HID]Spec簡讀

有些時候一個Report Descriptor隻描述了一個Report,這時候就不需要區分是哪一個Report的問題:

[HID]Spec簡讀

而有的時候,一個Report Descriptor中描述了好幾個Report,這時候就要引入一個Report ID來辨別是哪個Report的資料:

[HID]Spec簡讀

Strings

一般,在使用者自定義了某資料段用途,此時Strings的使用就有必要的,因為要進行比較詳細的描述。

Strings和Usage一樣,對一個item而言并不是必須的。

多位元組值格式

有些數值是可變的,即在一定的範圍之内,這個數值可能用多個byte區域來表示,這些bit的排列都是按照little endian來排列的,如下是一個執行個體:

[HID]Spec簡讀

Orientation

一些有方向性的資料表示時,HID裝置一般有統一的方向上的規定:

[HID]Spec簡讀

如上面就是坐标的方向正負規定,另外還有on(1)/off(0)表示和true(1)/false(0)的統一規定。

Null Values

HID裝置有忽略一個report中某些資料段的能力。這裡的意思是,通過聲明report中的某bit區域可以放置比實際control産生的資料要大的數值的(一個control就是一個控制,如鍵按下,用data來描述一個control的内涵的)。

當host或device收到這個超出實際control含義的資料時,也不會去改變這個資料。

如果每次發給device的report的某個資料段,Application都不會去改變它,這個資料段應當提供一個Null Value。

Null Value舉例:

比如一個8 bit的資料段,資料可以表示從0到0xFF的,但是該資料段已聲明有效範圍是0到0x7F,那接收到的在0x80到0xFF之間的數值都會被忽略掉。

HID裝置的Descriptor

[HID]Spec簡讀

三種Descriptor,HID Descriptor, Report Descriptor和Physical Descriptor。

HID Descriptor

[HID]Spec簡讀

Report Descriptor

[HID]Spec簡讀

Report Descriptor的意義:

隻要通過檢視Report Descriptor,App就可以知道詳細的HID裝置的資料的含義,進而進行對應的處理。

Global和Local item是對Main item内容的附加限定:

[HID]Spec簡讀

Control的再次說明:

一個HID device可能有多個control,一個control就是一個方面的控制功能,如一個按鍵控制功能,一個LED控制功能等。

Report必須具備的item

[HID]Spec簡讀

關于其中的Input(Output or Feature)類型的說明:

Feature item,是Host可以通過application來設定Device的一些特性,比如複位坐标原點,掃描頻率等,這些設定可能Device并不能很明顯的看到,是在Device内部的一些屬性特征的改變。

Physical Descriptor

繼續閱讀