So-net無料ブログ作成

USBプロジェクト - HIDデバイス(5) [USB]このエントリーを含むはてなブックマーク#

1593486

複合USBデバイスが、できちゃいました。 まだ、何も仕事はしてくれません。

デスクリプタを整備する

要は、複合デバイスに見えるデスクリプタを記述して、ホストの要求に応じて適切なデスクリプタを返すだけでおしまいです。 記述したコンフィグレーション・デスクリプタは、こんな構成になっています。

  • コンフィグレーション・デスクリプタ
    • 自前インターフェース・デスクリプタ (#0)
      • 自前HIDデスクリプタ
      • 自前エンドポイント・デスクリプタ (IN-EP2)
      • 自前エンドポイント・デスクリプタ (OUT-EP2)
    • キーボード・インターフェース・デスクリプタ (#1)
      • キーボードHIDデスクリプタ
      • キーボードエンドポイント・デスクリプタ (IN-EP1)

そして、GET_DESCRIPTORリクエストの処理部分でwIndexの値により、該当するインターフェースのレポート・デスクリプタを返すようにswitch文を追加しました。

キーボードの実装は、無い

キーボードとして動作する部分の実装は、一切行っていません。 TX1Eさえ、アサートしていません。 そのため、トランザクションが到着しても、ひたすらNAKが返っているはずです。 特に文句も言われていないから、こんなもんでいいんだろう。

ついでに、キーボードのレポート・デスクリプタから、"OUTPUT"部分を取り除いてしまいました。 そもそも、SET_REPORTリクエストへの応答処理も書いていません。 果たして、SET_REPORTリクエストが来なかったのか、それともDATAステージのSTALL応答で十分なのか、深くは追求していません。

PCが認識したデバイス

PCがどのようにこのデバイスを認識したのかは、デバイスマネージャで見るとわかります。

WS000133.png

このように、「複合デバイス」という仮想デバイスの下に「ヒューマン・インターフェース・デバイス」がぶら下がり、それらが「HID自前デバイス」と「HIDキーボード・デバイス」であることがわかります。 何だ、こんなに簡単な事だったんだ。

HIDD_ATTRIBUTESには、インターフェースが無い

これを、VisualBASICのプログラムで操作すると、LCDに表示が現れます。 でも、このプログラムでは、インターフェース番号を指定している所がありません。 VendorIDとProductIDは、HIDD_ATTRIBUTES構造体に入っていますが、インターフェース番号は入っていません。 何か、他に指定方法があるのでしょうか?

プロジェクト・アーカイブ

いつものように、HID08.zipという名前で保存してお使いください。

付録 : USBプロジェクト索引

参考文献

USBハード&ソフト開発のすべて―USBコントローラの使い方からWindows/Linuxドライバの作成まで (TECHI―Bus Interface)

USBハード&ソフト開発のすべて―USBコントローラの使い方からWindows/Linuxドライバの作成まで (TECHI―Bus Interface)

  • 作者: インターフェース編集部
  • 出版社/メーカー: CQ出版
  • 発売日: 2006/07
  • メディア: 単行本

nice!(0)  コメント(3)  トラックバック(0)  このエントリーを含むはてなブックマーク#

nice! 0

コメント 3

Tsuneo

>何だ、こんなに簡単な事だったんだ。

いやいや、簡単に思えるのはこれまでの精進の成果です。
USBの実装の変更はそんなに大がかりなものではありません。しかし、どこをどういじれば良いかが自信を持って判るまでが大変なんです。


>でも、このプログラムでは、インターフェース番号を指定している所がありません。 VendorIDとProductIDは、HIDD_ATTRIBUTES構造体に入っていますが、インターフェース番号は入っていません。 何か、他に指定方法があるのでしょうか?

複合デバイスは、ホストアプリ側から見ると独立した複数のデバイスであるかの様に見えます。例えば、HIDとマスストレージの複合デバイスは、HIDなデバイスとマスストレージなデバイスがそれぞれに接続しているように見えます。実際、複合デバイスを構成する各インターフェースに一対一対応で、デバイスドライバのインスタンスが作成されます。これが複合デバイスのうまみですね。つまり、専用のデバイスドライバを開発しないでも、既存のデバイスドライバの組合わせで新たなドライバができてしまうのです。

もちろん元は一つのデバイスですから、完全に独立しているわけではありません。どの部分が独立していてどの部分が共通しているかは、ファームウェアでのデスクリプタの構造やリクエストの処理を見ていけば自ずと明らかになるでしょう。
デスクリプタ上では、
1)各インターフェースは完全に独立しています。
つまり、インターフェースを指定して送られてくるクラスリクエストやエンドポイントを通じた通信は完全に独立している、ということです。
2)デバイス・デスクリプタとコンフィギュレーション・デスクリプタは共通です。
デバイス自体に送られる標準デバイスリクエストは共通です。また、バスリセットやサスペンドなどのイベントも共通です。

さて、このHID x 2の複合デバイスでは、ベンダ仕様なHIDデバイスとキーボードなHIDデバイスが、それぞれに接続しているように見えています。キーボードはFeatureレポートしか直接アクセスすることは無いのですが、あえてホストアプリで捕まえることにしましょう。

ホストアプリでデバイスを捕まえるには、SetupDi-API を駆使します。
まず、HidD_GetHidGuid()で HIDな GUIDを持ってきて、SetupDiGetClassDevs()に喰わせます。すると接続しているHIDなデバイスを全てリストアップしてくれます。問題のベンダ仕様なHIDデバイスとキーボードなHIDデバイスは、それぞれ別のデバイスとしてこのリストにリストアップされているのです。
ループを回してSetupDiEnumDeviceInterfaces()で一つずつリストから取出して、SetupDiGetDeviceInterfaceDetail()でデバイスパスを拾い、さらにCreateFile()でちょっとだけ開けてHidD_GetAttributes()でベンダーID,プロダクトID(VID/PID)を取出します。このVID/PIDが目的のものと一致するば当たりです。この辺までは定型的なコードですね。

問題の2つのHIDデバイスはどちらも同じVID/PIDを持っています(デバイス・デスクリプタは共通)。なので、通常は一つ見つかったらループを抜けるのですが、さらにループをリストの最後まで回して該当するデバイスを全部見つけ出すのです。こうして2つのHIDデバイスを取出すことができます。

では、この2つをどうやって区別するのか。
実はデバイスパスの一部としてインターフェース番号が含まれています。
USB\VID_vvvv&PID_pppp&MI_mm
vvvv: VID、HEXで4桁
pppp: PID、HEXで4桁
mm: インターフェース番号、HEXで2桁

このインターフェース番号を抽出して、区別します。

デバイスパスは、msinfo32.exe(Windowsの組込みコマンド)で見ることができます。
msinfo32 については、例えば、この記事などを見て下さい。
HIDデバイスは、コンポーネント > 入力 の下に居ます。

”トラブル対策のためのコンピュータ情報を効率よく収集する”
http://www.atmarkit.co.jp/fwin2k/win2ktips/787msinfo32/msinfo32.html

Tsuneo
by Tsuneo (2008-04-30 22:54) 

noritan

Tsuneoさん、いつもありがとうございます。

デバイスのリストを取り出すところまでは、わかるのですが、お目当てのデバイスを選択する部分がどうしてもわかりませんでした。デバイスパスを解析する必要があるんですか?何だか、美しくないな。

オペレーティングシステムは、デバイスのインターフェイス番号を当然知っているはずだから、属性を取り出す方法がわかれば解決と考えていました。デバイスパスの解析は最後の手段かと思っていました。

他の方法として考えたのは、二つのインターフェースに別々の名前を付けてインターフェイス・デスクリプタのiInterfaceにそれぞれ入れておく方法です。こうすると、インターフェイス番号にかかわらず対応することが出来ます。 msdn によると、 iInterface にゼロ以外の値を入れておくと、HidD_GetProductString 関数で名前を取り出す事ができるらしい。試してみるか。

by noritan (2008-05-02 08:59) 

Tsuneo

HidD_GetProductString は見落としてました。使えそうですね。

というか、以前のWinDDKの解説では、
The HidD_GetProductString routine returns the embedded string of a top-level collection that identifies the manufacturer's product.
としか書いてなかったので、確かめもせずデバイス・デスクリプタが指定するproduct stringを返すものと思っていました。今のMSDNのは随分詳しく改訂されていますね。これはもう一度WDKのUSB周りを端から端まで読み直せってことですか...

USB-IFで同様の回答をしましたが誰も何も言わなかったので、まだあまり知られていないのでしょう。
http://www.usb.org/phpbb/viewtopic.php?t=13799

Tsuneo
by Tsuneo (2008-05-03 15:47) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

トラックバックの受付は締め切りました

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。