HID/CDCデバイス向けUSBディスクリプタのデバッグ
ドライバエラーから推測するのではなく、ディスクリプタと転送の証拠を観察することで、ファームウェアチームがHID/CDCデバイスを診断する方法を解説します。
HID/CDCデバイスがよく使われるのは、ホストごとに独自ドライバを書かなくても実用的なUSBインターフェースを出せるからです。ただ、その便利さは「ディスクリプタが正確であること」が前提。HIDキーボード、センサ、シリアルブリッジ、複合デバイスがうまく動かないとき、根本原因はアプリ側に現れるよりも前にディスクリプタの証拠に表れていることがほとんどです。
ディスクリプタのデバッグは派手さはありませんが、USBサポート案件を最短で解決する手段のひとつです。
HID:レポートディスクリプタが「契約」そのもの
HIDデバイスでは、ホストはエンドポイント情報だけでは足りず、HIDレポートディスクリプタを必要とします。このディスクリプタがReport ID、Usage、サイズ、カウント、論理的な範囲、そして「バイトをどう解釈するか」を定義します。
よくあるHIDのミス:
- レポート長が実際のInterruptペイロードと合っていない
- ファームウェアはReport IDを使っているが宣言が一貫していない
- 論理Min/Maxがデータの表現と合っていない
- Usage Page/Usageがホストの期待と合わない
- エンドポイントのIntervalがデバイスの挙動に対して非現実的
- Boot Protocolの前提とReport Protocolの挙動が衝突
ホスト側エラーは曖昧に見えることがあります。ディスクリプタバイトとInterrupt転送を併記したキャプチャなら、ミスマッチを一目瞭然にできます。
CDC:インターフェース配置が重要
CDC ACMデバイスは通常、Communication InterfaceとData Interfaceを公開します。ホストは「一貫したディスクリプタ一式」と「クラス固有リクエスト」を期待します。Functional Descriptorの欠落、誤ったインターフェースアソシエーション、エンドポイントの不一致があれば、仮想シリアルポートが現れない原因になります。
確認する証拠:
- インターフェースのclassとsubclass
- CDC Header、ACM、Union、Call Managementの各Functional Descriptor
- Notificationエンドポイント
- バルクIN/OUTエンドポイント
SET_LINE_CODINGSET_CONTROL_LINE_STATE- コンフィギュレーション後のデータ転送
シリアルポートは現れるがバイトが流れないなら、エンドポイント挙動かアプリ層プロトコルが疑わしい。シリアルポート自体が現れないなら、ディスクリプタとクラスリクエストが最初のチェックポイントです。
複合デバイスはより慎重な設計が必要
複合デバイスでは、HID、CDC、マスストレージ、ベンダー固有インターフェースなどを組み合わせられます。これは便利ですが、失敗モードも掛け算的に増えます。1つのインターフェースでのディスクリプタミスが、デバイス全体のホストバインドを壊すことがあります。
複合デバッグで確認すべきポイント:
- コンフィギュレーションのトータル長
- インターフェース番号
- IAD(Interface Association Descriptor)
- エンドポイントの一意性
- クラス固有ディスクリプタの配置
- インターフェースごとのホストリクエスト
「ファームウェアが正しいバイトを送っている」と思うのは、キャプチャが「ホストが正しい構造を受け取った」ことを証明するまで保留にしてください。
生バイトとクラス解釈、両方が必要な理由
生バイトが「グラウンドトゥルース」、クラス解釈が「それを使いやすくするもの」。優れたUSB診断ツールは両方を表示できるべきです。エンジニアは何かが壊れたときに正確なディスクリプタバイトを見たいし、日常的にはオフセットを手計算せずに済むようデコード済みのフィールドも必要。
最良のワークフローは次のとおりです。
- デコード済みのディスクリプタツリーを確認する
- 怪しいフィールドに遭遇したら生バイトにジャンプする
- ホストのリクエストとファームウェアの応答を突き合わせる
- コンフィギュレーション後のエンドポイント転送を確認する
- 再現やサポート引き継ぎのためセッションを保存する
この流れなら、診断が「証拠」に紐づいたまま保たれます。
Bus Scopeが活きる場面
Bus Scopeは、USBトラフィックの失敗理由を「再現可能な答え」として必要とする、ファームウェアチーム/ハードウェアラボ/デバイスベンダー向けに設計されています。デバイスエクスプローラのコンテキスト、パケット詳細、生バイト、ディスクリプタ、クラス観察結果、フィルタ、保存済み .bscope セッションを1つの作業台にまとめます。
HID/CDCのケースでは、Bus Scopeが次の問いに答えてくれます。
- 列挙は完了したか?
- ディスクリプタは意図したクラスと一致していたか?
- ホストは期待どおりのクラスリクエストを送ったか?
- エンドポイント転送はレポートやラインコーディングの期待と一致していたか?
- これはファームウェア/ホストドライバ/アプリプロトコルのどれの問題か?
「ドライバが失敗した」という表面的な見え方から、「どのUSB契約が壊れたか」まで掘り下げられる——そこに価値があります。