SNSへはこちら

USB HIDレポートディスクリプタについて勉強

先のシリーズで USB に興味を持って、調べたり実際に実装してみたりしていますが、その過程で HID クラスのレポートディスクリプタをサボったなあということで、学んでいきたいと思っています。

本記事は、レポートディスクリプタをある程度解読できるようになることを目的としています。なるべく間違いは言わないように努力しますが、万が一見つけましたらコメントいただくと幸いです。まあ若干小手先のテクニック集みたいな記事になりますかね。

参考サイト

レポートディスクリプタの役割

レポートディスクリプタは、レポートとしてやり取りするデータのフォーマットを決める構造体であるという認識で良さそうです。例えば標準的なマウスの例だと、以下のようなデータを送る必要があります。

こちらの画像はこのサイトから引用しました。このビット/バイトごとにどのような情報が詰まっているのかをレポートディスクリプタという形でホストに教えてあげる役割があります。

NOTE:
では、レポートディスクリプタの順序等を変えれば、実際に送るレポート形式も変えていいということになるのでしょうか?
それとも「マウスはマウスだから、こういう構成にしなさい!」と予め決まっているものなのでしょうか。今後要検討です。

レポートディスクリプタの形式

僕自身まだそんなに見ていったわけではないので憶測になって申し訳ないのですが、分かることをつらつら述べます。
このディスクリプタは階層のある構造をしていて、ブロックごとで1つの意味を持っています。

このディスクリプタをややこしくも分かりやすくもしているこの構造ですが、多分こう見れば良いのだろうと思った見方をメモしておきます。
例としてマウスを取り上げます。枠囲いは下を読めば何となく分かると思うので、記事を読んでからもう一度見てみてください。

Usageで1つのセクションが始まる

Usage および Usage Page によって、レポートの形式を決めるブロックが1つできるというイメージ(あくまでもイメージ)だと思うと理解がしやすいのでは、と思います。

Usage Page というのはこれからどのような種類のレポート内容を述べるのかという大まかなカテゴリであり、一度選択したら選択されっぱなしです。そのカテゴリの中で、Usage によって更に詳細を述べるという感じですかね。例えるならば、機能の対応表が載っている本を見る感じ。その表はページごとに分かれていて(これが Usage Page)、まずそのページを開く(Usage Page の指定)必要があります。目的のページを開いたら、その中から更に詳細な機能を探します(Usage)。

その後、機能(に対するレポートの対応関係)の中身を記述します。どうやらルートには Collection というブロックを1つしか置けないようです。

中身 --- Input/Outputで締める

その中にはまた Usage Page と Usage があって、ここでもセクションが開始します。

Usage Maximum 等はレポートの内容を直接記述するものです。僕は以下のような認識です。

  • Usage Minimum/Maximum: 記述する要素数の最小・最大値
  • Logical Minimum/Maximum: 記述する値の最小・最大値
  • Report Count: 実際にレポートに要素を何個記述するか
  • Report Size: レポート1つあたりのビット幅

セクションの最後に Input あるいは Output を置きます。これによって中身を1つにまとめ、またその値の性質(絶対値/相対値、定数固定/変数)を同時に示します。

雑ですが、これで大体読めるんじゃないですかね。
次回は STM32 で自作したペリフェラルで、マウスのレポートディスクリプタを改造してその役割を実際に認識していきたいと思います。