![]() |
libusb 1.0.24
USBデバイスにアクセスするためのクロス・プラットフォームのユーザー・ライブラリ
|
libusbは完全にスレッド・セーフになるように設計されていますが、他のAPIと同様に、意図的であろうとなかろうと、ユーザーが自分自身で妨害するのを防ぐことはできません。
以下の一般的なガイドラインに従ってください:
複数のスレッドと非同期入出力のルールについては、マルチ・スレッド・アプリケーションと非同期入出力 で詳しく説明しています。
libusbは、fork() 呼び出しが全体で機能するように設計されていません。 プラットフォームによっては、子プロセスが利用できないリソースが親プロセスにある場合があります(Linuxの活線挿抜監視スレッドなど)。 さらに、親プロセスと子プロセスはlibusbの内部ファイル・デスクリプターを共有するため、子プロセスから何らかの方法でlibusbを使用すると、親プロセスの libusb_context が不整合な状態になる可能性があります。
Linuxでは、libusbのファイル・デスクリプターはCLOEXECとしてマークされます。これは、子プロセスが状態をクリーン・アップする必要があることや、これらのファイル・デスクリプターにアクセスすることを心配せずに、 fork() および exec() を安全に実行できることを意味します。 他のプラットフォームはそれほど寛容ではないかもしれないので、各自ご注意下さい!
libusb_reset_device() 関数を使用すると、デバイスをリセットできます。 プログラムがそのような関数を呼び出さなければならない場合、リセットによってデバイスの状態が変化することをちゃんと認識しておく必要があります(たとえば、レジスタ値がリセットされる可能性があります)。
問題は、他のプログラムが、そのプログラムが動作しているデバイスをいつでもリセットする可能性があることです。 libusbは、これが発生したときに通知するメカニズムを提供していないため、他の誰かがデバイスをリセットした場合、そのデバイスの状態が変更された理由は自分のプログラムでは明確ではありません。
つまり、これはユーザー空間でのドライバーの書き込みの制限です。基盤となるカーネルのUSBスタックから分離すると、オペレーティング・システムがそのような通知をプログラムに配信することが困難になります。LinuxカーネルのUSBスタックでは、このようなリセット通知をカーネル内のUSBドライバーに配信できますが、ユーザー空間に存在するセカンド・クラスのドライバーにこのような通知を配信する方法は明確にはありません。
以下にリストされている機能は、同期のブロック機能を介してのみ使用できます。 非同期/非ブロッキングの代替手段はなく、これらを実装する明確な方法もありません。
libusbがデバイス・ハンドルをアプリケーションに提示すると、対応するデバイスが未構成の状態になる可能性があります。複数の構成を持つデバイスの場合、現在選択されている構成がアプリケーションで使用したい構成ではない可能性もあります。
明らかな解決策は、デバイスの初期化ルーチンの早い段階で libusb_set_configuration() への呼び出しを追加することですが、以下の注意事項があります:
上記の問題のいくつかに対する1つの解決策は、現在アクティブな構成を調べることです。必要な構成がすでにアクティブになっている場合は、構成を選択する必要はありません:
これはおそらくほとんどのシナリオに適していますが、本質的に際どいものです。なぜなら、 libusb_get_configuration() の呼び出し後に、別のアプリケーションまたはドライバーが選択した構成を変更する場合があるからです。
libusb_set_configuration() が成功した場合でも、あなたのアプリケーションが libusb_set_configuration() を呼び出した後、他のアプリケーションまたはドライバーが構成を変更する可能性があることを考慮してください。
デバイスを特定の構成にロックする方法の一つは以下のとおりです:
上記の方法が機能するのは、インターフェイスが要求されると、アプリケーションまたはドライバーは別の構成を選択できないためです。
注意: この節は現在Linuxを主眼に記述されています。これらの考慮事項のいずれがDarwinまたは他のプラットフォームに適用されるかどうかはわかりません。
転送が早期に完了すると(つまり、転送バッファーで許可されるよりも少ないデータが1つのパケットで送受信される場合)、libusbは転送をすぐに終了するように設計されており、他の転送がユーザーによってキューに入れられていない限り、それ以上データを転送または受信しません。
旧来のプラットフォームでは、libusbはすべての状況でこれを実行できるわけではありません。不完全なパケットが発生した後、"余剰" データが転送される場合があります。 libusbの最近のバージョンでは、この情報が保持され(転送のデータ長が更新されます)、デバイスからホストへの転送では、余分なデータがバッファーに追加されました。それでも、これは短いパケットの終わりに関する情報を失うため、良い解決策ではありません。ユーザーは、余ったデータが次の論理転送で到着することを望んでいた可能性があります。