↓この続きです。
PC-88VA用USBキーボード変換器ですが、接続確認の試験では、ずっと安物のキーボードを使っていましたが、HUBを経由した複数キーボードの接続試験をするために、ちょっと高級(?)な別のキーボードも接続してみたところ、どうやら正常に動作していないことが判明しました。
接続時のログを調べてみたところ、このキーボードは、1つのUSBデバイス内に以下の2つのInterfaceを持っているようです。
-
Interface 0
HID Boot Keyboard (class=3, subclass=1, protocol=1) -
Interface 1
N-Keyロールオーバー キーボード + Consumer Control
Report ID付き
元々のUSBホストの実装は、
-
1デバイス = 1キーボード
という前提で処理していたため、同一USBデバイス内に存在する複数のインターフェイスを別々のキーボードとして登録してしまい、USBメッセージを奪い合っていたようです。
ログを見ると、同じUSBアドレスに対してキーボードオブジェクトを2個生成していました。
AIとお話して分かったのですが、このキーボードが特殊というわけではなく、そもそもUSB HIDデバイスでは
-
1つの物理USBデバイス
-
複数の論理入力デバイス
という構成が普通に存在するそうです。
以前に書いた記事で、USBキーボードは一定の時間間隔で、以下の8バイトのデータを垂れ流してくる、と書きました。
| ofs. | val. |
|---|---|
| 0 | modifier |
| 1 | reserved |
| 2 | usageID 0 |
| 3 | usageID 1 |
| : | |
| 7 | usageID 5 |
これは概ねウソではないのですが、すべてのキーボードが常に上記のプロトコルで動作しているわけではありません。
高級なゲーミングキーボード等では、たくさんのキーの同時押しを正しく処理するために、OS起動後は別のプロトコルに切り替えることがある、ということなのだそうです。
ただし、そういったゲーミングキーボードでも、BIOSブート等の為に上記のプロトコルもサポートする必要があるので、高級なキーボードほど、1つの物理USBデバイスに複数の論理入力デバイスという構成になりがちなのだそうです。
上記の表に書いた古典的なプロトコルをBoot Keyboardとか、BIOS Keyboard等と言ったりすようで、これを判別するにはデバイスインターフェイスプロトコルに書いてあるclass=3, subclass=1, protocol=1というのを判別すればよいそうなので、これを満たす Boot Keyboard Interface のみ処理するように変更したところ、問題なく動作するようになりました。
なかなか奥が深いですね。
