USBディスクリプタは、USBデバイスがホストに自身の構成や機能を伝えるための重要な情報を含むデータ構造です。適切に設定されていないと、デバイスが正しく認識されない、または期待通りに動作しないことがあります。本記事では、USBディスクリプタに関するよくあるエラーとその対処法について詳しく解説します。
1. デバイスが認識されない
症状
デバイスを接続しても、ホストがデバイスを認識しない、または「不明なデバイス」として表示される。
原因
- デバイスディスクリプタの誤設定:
bLength
やbDescriptorType
が正しく設定されていない。 - 不正なベンダーID(VID)やプロダクトID(PID): VIDやPIDが正しく設定されていない。
対処法
struct device_descriptor {
uint8_t bLength = 18;
uint16_t idVendor = 0x1234; // ベンダーID
uint16_t idProduct = 0x5678; // プロダクトID
};
2. エンドポイントが動作しない
症状
デバイスは認識されるが、エンドポイントが期待通りにデータを転送しない。
原因
- エンドポイントディスクリプタの設定ミス:
bEndpointAddress
やbmAttributes
が正しく設定されていない。 - wMaxPacketSizeの不適切な設定: エンドポイントの最大パケットサイズが不正確。
対処法
- エンドポイントディスクリプタの設定を確認し、各フィールドが正しい値を持っているか確認する。
bEndpointAddress
が適切な方向(IN/OUT)を示し、bmAttributes
が正しい転送タイプを示していることを確認する。
struct endpoint_descriptor {
uint8_t bLength = 7;
uint8_t bEndpointAddress = 0x81; // エンドポイント1、IN方向
uint8_t bmAttributes = 0x02; // バルク転送
uint16_t wMaxPacketSize = 512; // 最大512バイト
uint8_t bInterval = 0;
};
3. デバイスクラスが正しく認識されない
症状
デバイスが認識されるが、正しいクラスドライバがロードされない。
原因
- デバイスディスクリプタの
bDeviceClass
設定ミス: クラスコードが正しく設定されていない。 - インターフェースディスクリプタの
bInterfaceClass
設定ミス: インターフェースクラスが正しく設定されていない。
対処法
- デバイスディスクリプタの
bDeviceClass
を確認し、正しいクラスコードが設定されているか確認する。 - インターフェースディスクリプタの
bInterfaceClass
を確認し、適切なクラスコードが設定されているか確認する。
struct device_descriptor {
uint8_t bLength = 18;
uint8_t bDescriptorType = 0x01;
};
struct interface_descriptor {
uint8_t bLength = 9;
};
. 言語IDストリングが正しく認識されない
症状
デバイスの言語IDストリングが正しく認識されない、または表示されない。
原因
対処法
- 言語IDストリングディスクリプタを確認し、
bDescriptorType
が0x03であることを確認する。 - 言語IDが正しい値(例: 英語の場合は0x0409)に設定されていることを確認する。
uint8_t langIDDescriptor[] = {
4, // bLength
0x03, // bDescriptorType
0x09, 0x04 // 言語ID(英語)
};
5. 設定ディスクリプタのエラー
症状
設定ディスクリプタが正しく認識されず、デバイスが期待通りに動作しない。
原因
- 設定ディスクリプタの長さが間違っている:
wTotalLength
が正しく計算されていない。 - bConfigurationValueが不正: 設定値が正しく設定されていない。
対処法
- 設定ディスクリプタの
wTotalLength
を確認し、全ての含まれるディスクリプタの長さが正しく計算されていることを確認する。 bConfigurationValue
が正しい値に設定されているか確認する。
struct configuration_descriptor {
uint8_t bLength = 9;
uint16_t wTotalLength = sizeof(configuration_descriptor) + sizeof(interface_descriptor) + sizeof(endpoint_descriptor);
uint8_t bNumInterfaces = 1;
uint8_t bConfigurationValue = 1;
uint8_t iConfiguration = 0;
uint8_t bmAttributes = 0x80; // バスパワー
uint8_t bMaxPower = 50; // 100mA
};
まとめ
USBディスクリプタの設定ミスは、デバイスが正しく認識されない原因となります。よくあるエラーを理解し、適切に対処することで、デバイスが期待通りに動作するようになります。デバイスディスクリプタ、エンドポイントディスクリプタ、インターフェースディスクリプタなどの設定を確認し、必要に応じて修正を行いましょう。このガイドを参考に、USBディスクリプタのトラブルシューティングを効果的に行い、デバイスの信頼性を向上させてください。