libusb  1.0.24
USBデバイスにアクセスするためのクロス・プラットフォームのユーザー・ライブラリ
Data Structures | Typedefs | 列挙型 | Functions
非同期デバイス入出力

このページでは、USBデバイス入出力用のlibusbの非同期(非ブロッキング)APIについて詳しく説明します。 このインターフェイスは非常に強力ですが、非常に複雑でもあります。このページを注意深く読んで、このインターフェイスの使用に関する必要な考慮事項と問題を理解する必要があります。単純なアプリケーションでは、代わりに 同期入出力API を検討することをお勧めします。詳細はコチラ

データ構造

struct  libusb_control_setup
 
struct  libusb_iso_packet_descriptor
 
struct  libusb_transfer
 

Typedef

typedef void(* libusb_transfer_cb_fn) (struct libusb_transfer *transfer)
 

列挙型

enum  libusb_transfer_type {
  LIBUSB_TRANSFER_TYPE_CONTROL = 0U, LIBUSB_TRANSFER_TYPE_ISOCHRONOUS = 1U, LIBUSB_TRANSFER_TYPE_BULK = 2U, LIBUSB_TRANSFER_TYPE_INTERRUPT = 3U,
  LIBUSB_TRANSFER_TYPE_BULK_STREAM = 4U
}
 
enum  libusb_transfer_status {
  LIBUSB_TRANSFER_COMPLETED, LIBUSB_TRANSFER_ERROR, LIBUSB_TRANSFER_TIMED_OUT, LIBUSB_TRANSFER_CANCELLED,
  LIBUSB_TRANSFER_STALL, LIBUSB_TRANSFER_NO_DEVICE, LIBUSB_TRANSFER_OVERFLOW
}
 
enum  libusb_transfer_flags { LIBUSB_TRANSFER_SHORT_NOT_OK = (1U << 0), LIBUSB_TRANSFER_FREE_BUFFER = (1U << 1), LIBUSB_TRANSFER_FREE_TRANSFER = (1U << 2), LIBUSB_TRANSFER_ADD_ZERO_PACKET = (1U << 3) }
 

関数

int libusb_alloc_streams (libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints, int num_endpoints)
 
int libusb_free_streams (libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints)
 
unsigned char * libusb_dev_mem_alloc (libusb_device_handle *dev_handle, size_t length)
 
int libusb_dev_mem_free (libusb_device_handle *dev_handle, unsigned char *buffer, size_t length)
 
struct libusb_transferlibusb_alloc_transfer (int iso_packets)
 
void libusb_free_transfer (struct libusb_transfer *transfer)
 
int libusb_submit_transfer (struct libusb_transfer *transfer)
 
int libusb_cancel_transfer (struct libusb_transfer *transfer)
 
void libusb_transfer_set_stream_id (struct libusb_transfer *transfer, uint32_t stream_id)
 
uint32_t libusb_transfer_get_stream_id (struct libusb_transfer *transfer)
 
static unsigned char * libusb_control_transfer_get_data (struct libusb_transfer *transfer)
 
static struct libusb_control_setuplibusb_control_transfer_get_setup (struct libusb_transfer *transfer)
 
static void libusb_fill_control_setup (unsigned char *buffer, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength)
 
static void libusb_fill_control_transfer (struct libusb_transfer *transfer, libusb_device_handle *dev_handle, unsigned char *buffer, libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout)
 
static void libusb_fill_bulk_transfer (struct libusb_transfer *transfer, libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *buffer, int length, libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout)
 
static void libusb_fill_bulk_stream_transfer (struct libusb_transfer *transfer, libusb_device_handle *dev_handle, unsigned char endpoint, uint32_t stream_id, unsigned char *buffer, int length, libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout)
 
static void libusb_fill_interrupt_transfer (struct libusb_transfer *transfer, libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *buffer, int length, libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout)
 
static void libusb_fill_iso_transfer (struct libusb_transfer *transfer, libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *buffer, int length, int num_iso_packets, libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout)
 
static void libusb_set_iso_packet_lengths (struct libusb_transfer *transfer, unsigned int length)
 
static unsigned char * libusb_get_iso_packet_buffer (struct libusb_transfer *transfer, unsigned int packet)
 
static unsigned char * libusb_get_iso_packet_buffer_simple (struct libusb_transfer *transfer, unsigned int packet)
 

詳細

このページでは、USBデバイス入出力O用のlibusbの非同期(非ブロッキング)APIについて詳しく説明します。 このインターフェイスは非常に強力ですが、非常に複雑でもあります。このページを注意深く読んで、このインターフェイスの使用に関する必要な考慮事項と問題を理解する必要があります。 単純なアプリケーションでは、代わりに 同期入出力API を検討することをお勧めします。

非同期インターフェースは、転送の送信と転送の完了の処理を分離するという考えに基づいて構築されています(同期モデルはこれらの両方を1つに結合します)。 送信から完了までに長い遅延が発生する可能性がありますが、非同期送信機能は非ブロッキングであるため、その潜在的に長い遅延の間にアプリケーションに制御を戻します。

転送の抽象化

非同期入出力の場合、libusbは、すべてのタイプの入出力(制御、バルク、割り込み、アイソクロナス)の汎用転送エンティティの概念を実装します。汎用転送オブジェクトは、それを使用して実行している入出力のタイプに応じて、多少異なる方法で処理する必要があります。

これは、 public libusb_transfer 構造体タイプで表されます。

非同期転送

非同期入出力は5ステップのプロセスと見なすことができます:

  1. 割り当て: libusb_transfer を割り当てます
  2. 情報入力: その libusb_transfer インスタンスに実行したい転送に関する情報を入力します
  3. 送信: libusbに送信(submit)を依頼する
  4. 完了処理: libusb_transfer 構造体で転送結果を調べます
  5. 割り当て解除: リソースをクリーンアップします

割り当て

このステップには、USB転送用のメモリの割り当てが含まれます。 これは、前述した一般的な転送オブジェクトです。この段階では、転送は「空白」であり、使用される入出力タイプに関する詳細はありません。

割り当ては、 libusb_alloc_transfer() 関数を使用して行われます。 あなた独自の転送の割り当てではなく、この関数を使用する必要があります。

情報入力

このステップでは、先程割り当てられた転送を取得し、メッセージ・タイプと方向(訳注:入力か出力か)、データ・バッファー、コールバック関数などの情報を入力します。

あなたは必要なフィールドに自分で入力するか、ヘルパー関数を使用できます: libusb_fill_control_transfer()libusb_fill_bulk_transfer()libusb_fill_interrupt_transfer()

送信

転送を割り当て、入力したら、 libusb_submit_transfer() を使用して送信できます。この関数はすぐに戻りますが、バックグラウンドで入出力要求を実行しています。

完了処理

転送データを送信開始した後、次の4つのいずれかが発生する可能性があります:

これらそれぞれに対してユーザー指定の転送コールバック関数が呼び出されます。上記のどれが実際に起こったかを判断し、それに応じて行動するのはコールバック関数次第です。

ユーザー指定のコールバックには、転送の情報入力時と送信時に使用された libusb_transfer 構造体へのポインタが渡されます。 完了時にlibusbはこの構造体に転送の結果(成功または失敗の理由、転送されたデータのバイト数など)を入力します。詳細については、 libusb_transfer 構造体の文書を参照してください。

重要: ユーザー指定のコールバックは、イベント処理コンテキストから呼び出されます。したがって、イベント処理を実行しようとするlibusbへの呼び出しが行われないことが重要です。このような関数の例としては、 同期API にリストされているものや、 USBデスクリプター を取得するブロッキング関数があります。

割り当て解除

転送が完了したら(つまり、コールバック関数が呼び出されたら)、その転送を解放することをお勧めします(再送信する場合を除き、以下を参照してください)。 転送は、 libusb_free_transfer() で割り当て解除されます。

完了していない転送を解放することは未定義の動作です。

再送信

これらを1つの操作に合理的に組み合わせることができるのに、割り当て・情報入力・送信がすべて分離されているのはなぜか疑問に思われるかもしれません。

分離してある理由は、毎回新しい転送を割り当てることなく、転送を再送信できるようにするためです。 これは、割り込みエンドポイントを扱う一般的な状況で特に役立ちます。1つの転送を割り当て、それを入力して送信し、結果が返されたら、次の割り込みのために再送信するだけです。

キャンセル

非同期インターフェースを使用するもう1つの利点は、まだ完了していない転送をキャンセルできることです。 これは、 libusb_cancel_transfer() 関数を呼び出すことで実行されます。

libusb_cancel_transfer() それ自体が非同期/非ブロッキングです。 キャンセルが実際に完了すると、転送のコールバック関数が呼び出され、コールバック関数は転送ステータスをチェックして、キャンセルされたことを確認する必要があります。

キャンセル後、キャンセルが完了する前に転送を解放すると、未定義の動作が発生します。

注意
転送がキャンセルされた場合、一部のデータが転送された可能性があります。 libusbは、転送コールバックでこれを通知します。 転送されたデータ無かったという想定はしないでください。

キャンセルによる部分的なデータ転送

上記のように、一部のデータは転送がキャンセルされたときに既に転送された可能性があります。 パケット・サイズが64バイトのエンドポイントへの一括転送を検討する場合、これがどのように可能であるかを確認すると役立ちます。このエンドポイントに512バイトの転送を送信すると、オペレーティング・システムは、この転送を8つの個別の64バイトフレームに分割し、ホスト・コントローラーがデバイスがデータを転送するようにスケジュールします。 デバイスがデータを転送しているときにこの転送がキャンセルされた場合、デバイスがホストへのデータの転送を完了する前に、これらのフレームの部分がホスト・コントローラーからスケジュール解除される可能性があります。

部分的なデータ転送でアプリケーションが行うべきことは、ポリシーの決定です。 すべてのアプリケーションの需要を満たす単一の答えはありません。 正常に転送されたデータは完全に有効であると見なす必要があります。しかし、アプリケーションは、転送されなかった残りのデータをどう処理するかを決定する必要があります。実行できる行動は以下のとおりです:

タイムアウト

転送がタイムアウトすると、libusbはこれを内部的に記録し、転送をキャンセルしようとします。 上述eされているように、一部のデータは実際に転送された可能性があります。アプリケーションは、転送が完了したら、常に実際に転送されたデータの量を確認し、それに応じて動作する必要があります。

デバイスからホスト方向のバルクまたは割り込みエンドポイントでのオーバーフロー

デバイスに推測可能な転送サイズがない場合(またはデバイスが誤動作する場合)、アプリケーションは、デバイスが送信したいデータよりも小さいINエンドポイントでデータの要求を送信する場合があります。状況によっては、これによりオーバーフローが発生し、対処するのが厄介な状態になります。この議論については、 パケットとオーバーフロー ページを参照してください。

制御転送に関する考慮

libusb_transfer 構造は汎用であるため、制御転送固有のセットアップ・パケット構造体の特定のフィールドは含まれていません。

制御転送を実行するには、8バイトのセットアップ・パケットをデータ・バッファの先頭に配置する必要があります。これを単純化するために、バッファ・ポインタを型 struct にキャストするか、ヘルパー関数 libusb_fill_control_setup() を使用できます。

セットアップ・パケットに配置されるwLengthフィールドは、セットアップ・パケットで送信されると予想される長さ、つまり後続のペイロードの長さ(または受信すると予想される最大バイト数)である必要があります。 ただし、 libusb_transfer オブジェクトのlengthフィールドは、データ・バッファの長さである必要があります。つまり、wLengthにセットアップ・パケットのサイズを加えたものである必要があります(LIBUSB_CONTROL_SETUP_SIZE)。

ヘルパー関数を使用する場合、これは以下のように単純化されます:

  1. サイズ値LIBUSB_CONTROL_SETUP_SIZEに、送信/要求するデータのサイズを加えて、バッファーを割り当てます。
  2. 転送要求のサイズをwLength値として使用して、データ・バッファーで libusb_fill_control_setup() を呼び出します(つまり、制御転送セットアップに割り当てた余分なスペースを含めないでください)。
  3. これがホストからデバイス方向の転送である場合は、オフセットLIBUSB_CONTROL_SETUP_SIZEから開始して、転送するデータをデータ・バッファーに配置します。
  4. libusb_fill_control_transfer() を呼び出して、データ・バッファーを転送に関連付けます(そして、コールバックやタイムアウトなどの残りの詳細を設定します)。
    • 注意: 転送の長さフィールドを設定するパラメータがないことに注意してください。 長さは、セットアップ・パケットのwLengthフィールドから自動的に推測されます。
  5. その転送を送信する。

マルチバイト制御セットアップ・フィールド( wValue と wIndex と wLength )は、リトル・エンディアンのバイト順序(USBバスのエンディアン)で指定する必要があります。エンディアン変換は、ホスト・エンディアン値を受け入れるように文書化されている libusb_fill_control_setup() によって透過的に処理されます。

コールバック関数で転送の完了を処理する場合は、さらに考慮が必要です。

セットアップパケットの解析と正しいオフセットからのデータの取得を簡素化するために、転送コールバック内で libusb_control_transfer_get_data() 関数と libusb_control_transfer_get_setup() 関数を使用することをお勧めします。

制御エンドポイントが停止しない場合でも、完了した制御転送にはLIBUSB_TRANSFER_STALLステータス・コードが含まれる場合があります。これは、制御要求がサポートされていなかったことを示します。

割り込み転送に関する考慮

すべての割り込み転送は、エンドポイント・デスクリプターのbInterval値によって示されるポーリング間隔を使用して実行されます。

アイソクロナス転送に関する考慮

アイソクロナス転送は、非アイソクロナス・エンドポイントへの転送よりも更に複雑です。

アイソクロナス・エンドポイントへの入出力を実行するには、適切な数のアイソクロナス・パケットを使用して libusb_alloc_transfer() を呼び出して転送を割り当てます。

情報入力で、 typeLIBUSB_TRANSFER_TYPE_ISOCHRONOUS をセットし、 num_iso_packets に割り当て中に要求したパケット数以下の値をセットします。 libusb_alloc_transfer() は、アイソクロナス・エンドポイントで転送を使用しない可能性があるため、これらのフィールドのどちらも設定しません。

次に、 iso_packet_desc 配列の最初のnum_iso_packetsエントリのlengthフィールドに入力します。 USB2仕様の5.6.3節(Section 5.6.3 of the USB2 specifications)では、エンドポイント・デスクリプターのwMaxPacketSizeフィールドによって最大アイソクロナス・パケット長がどのように決定されるかについて説明しています。ここで以下の2つの機能が役に立ちます:

こちらから相手への発信する転送の場合、すべてのデータが転送されることを期待して、あなたは確実にバッファを埋め、パケット・デスクリプターを入力します。逆に着信転送の場合、すべてのパケットが要求されたデータの全量を転送する状況に対して、バッファーに十分な容量があることを確認する必要があります。

完了処理には、追加の考慮事項が必要です。 転送の actual_length フィールドは無意味であるため、調べる必要はありません。 代わりに、個々のパケットの actual_length フィールドを参照する必要があります。

転送の status フィールドも少々誤解を招く可能性があります:

各パケットのデータは、その直前のパケットが完全に完了したはずの位置で見つかります。 libusb_get_iso_packet_buffer() 関数と libusb_get_iso_packet_buffer_simple() 関数が役に立つ事でしょう。

転送長さ制限

一部のオペレーティング・システムでは、転送データ・バッファの長さ、またはアイソクロナス転送の場合は個々のアイソクロナス・パケットの長さに制限を課す場合があります。このような制限はlibusbが検出するのが難しい場合があるため、ほとんどの場合、ライブラリはユーザーが設定した転送で送信しようとします。転送が大きすぎるために送信に失敗した場合、 libusb_submit_transfer()LIBUSB_ERROR_INVALID_PARAM を返します。

以下は、制御転送長の既知の制限です。この長さには、8バイトのセットアップ・パケットが含まれていることに注意してください。

メモリに関する警告

ほとんどの場合、転送バッファにスタック・メモリを使用することは安全ではありません。これは、非同期転送を開始した関数が、libusbがバッファーの使用を終了する前に戻る可能性があり、関数が戻ると、そのスタックは破棄されるためです。これは、ホストからデバイスへの転送とデバイスからホストへの転送の両方に当てはまります。

スタック・メモリを安全に使用できる唯一のケースは、バッファのスタック・スペースを所有する関数が、転送のコールバック関数が完了するまで戻らないことを保証できる場合です。それ以外の場合は、代わりにヒープ・メモリを使用する必要があります。

繊細な制御

この非同期インターフェースを使用すると、いくつかの簡単な操作を何度も繰り返すことに気付くかもしれません。転送でflagの特定のビットごとのORをセットして、特定の操作を単純化できます:

イベント処理

非同期モデルでは、libusbがさまざまな時点で作業を実行する必要があります。つまり、以前に送信された転送の結果を処理し、ユーザーが指定したコールバック関数を呼び出します。

これにより、libusbが機能するときにあなたのアプリケーションが呼び出す必要のある libusb_handle_events() 関数が生起されます。これにより、libusbは保留中の転送を取得したり、コールバックを呼び出したりすることができます。

注意
すべてのイベント処理は、 libusb_handle_events() 関数を呼び出すスレッドによって実行されます。 libusbは、このコンテキスト以外でコールバックを呼び出しません。したがって、コールバックはすべて、 libusb_handle_events() 関数を呼び出すスレッドで実行されます。

libusb_handle_events() 関数をいつ呼び出すかは、あなたのアプリケーションが使用することを決定したモデルによって異なります。2つの異なるアプローチがあります:

  1. 専用スレッドからブロッキング・モードで繰り返し libusb_handle_events() を呼び出します。
  2. libusbをアプリケーションのメイン・イベント・ループと統合します。 libusbは、これを可能にする一連のファイル・デスクリプターを公開します。

最初のアプローチには、選択/ポーリング統合用のlibusbのポーリングAPIが利用できない場合にWindowsでも機能するという大きな利点があります。 したがって、Windowsをサポートして非同期APIを使用する場合は、このアプローチを使用する必要があります。詳細については、以下の イベント処理スレッドの利用 を参照してください。

単一の中央イベント・ループを使用するシングル・スレッド・アプローチが必要な場合は、libusbをアプリケーションのメイン・イベント・ループに統合する方法について、 ポーリングとタイミング の節を参照してください。

単一のイベント処理スレッドの使用

まず、明白であることから言うと、libusbイベント処理に別のスレッドを使用する場合、コールバック関数はスレッド・セーフでなければなりません。

それ以外の場合、別のスレッドからイベント処理を行うのは割と簡単です。イベント・スレッド関数は以下のように使用できます:

void *event_thread_func(void *ctx)
{
while (event_thread_run)
return NULL;
}

ただし、注意点が1つあります。このスレッドを停止するには、event_thread_run変数を0に設定する必要があります。その後、 libusb_handle_events() は制御をevent_thread_funcに戻す必要があります。 ただし、何らかのイベントが発生しない限り、 libusb_handle_events() は処理を返しません。

アプリケーションがlibusbの 活線挿抜(hotplug) サポートを使用しているかどうかに応じて、これに対処する2つの異なる方法があります。

活線挿抜(hotplug)サポートを使用しないアプリケーションは、 libusb_open() を最初に呼び出した直後まで、イベント・スレッドを開始しないでください。また、以下のように最後、オープンしていたデバイスをクローズしたときにスレッドを停止する必要があります:

void my_close_handle(libusb_device_handle *dev_handle)
{
if (open_devs == 1)
event_thread_run = 0;
libusb_close(dev_handle); // This wakes up libusb_handle_events()
if (open_devs == 1)
pthread_join(event_thread);
open_devs--;
}

活線挿抜サポートを使用するアプリケーションは、 libusb_hotplug_register_callback() を正常に呼び出した後、プログラムのinitでスレッドを開始し、以下のとおりプログラムの終了時にスレッドを停止する必要があります:

void my_libusb_exit(void)
{
event_thread_run = 0;
libusb_hotplug_deregister_callback(ctx, hotplug_cb_handle); // This wakes up libusb_handle_events()
pthread_join(event_thread);
}

Typedef解説

◆ libusb_transfer_cb_fn

typedef void( * libusb_transfer_cb_fn) (struct libusb_transfer *transfer)

非同期転送コールバック関数型。非同期転送を送信するときは、 libusb_transfer 構造体の callback メンバーを介してこのタイプのコールバック関数へのポインタを渡します。 libusbは、転送が完了または失敗したときに、後でこの関数を呼び出します。 詳細については、 非同期デバイス入出力 を参照してください。

パラメーター
transferThe libusb_transfer 構造体は、コールバック関数に通知されます。

列挙型解説

◆ libusb_transfer_type

転送タイプ

列挙型
LIBUSB_TRANSFER_TYPE_CONTROL 

制御転送。

LIBUSB_TRANSFER_TYPE_ISOCHRONOUS 

アイソクロナス転送。

LIBUSB_TRANSFER_TYPE_BULK 

バルク転送。

LIBUSB_TRANSFER_TYPE_INTERRUPT 

割り込み転送。

LIBUSB_TRANSFER_TYPE_BULK_STREAM 

バルク・ストリーム転送

◆ libusb_transfer_status

転送ステータス・コード

列挙型
LIBUSB_TRANSFER_COMPLETED 

エラー無しで転送が完了した。

注意: これは、要求されたデータの全量が転送されたことを示すものではないことに注意してください。

LIBUSB_TRANSFER_ERROR 

転送が失敗した。

LIBUSB_TRANSFER_TIMED_OUT 

転送タイムアウト。

LIBUSB_TRANSFER_CANCELLED 

転送がキャンセルされた。

LIBUSB_TRANSFER_STALL 

バルク/割り込みエンドポイントの場合: 停止(halt)状態が検出されました(エンドポイントがストール(stall)しました)。

制御エンドポイントの場合: その制御要求はサポートされていません。

LIBUSB_TRANSFER_NO_DEVICE 

デバイスが切断された。

LIBUSB_TRANSFER_OVERFLOW 

デバイスが要求よりも多いデータを送信した。

◆ libusb_transfer_flags

libusb_transfer.flags values

列挙型
LIBUSB_TRANSFER_SHORT_NOT_OK 

短いフレームをエラーとして報告します。

LIBUSB_TRANSFER_FREE_BUFFER 

libusb_free_transfer() 中に転送バッファを自動的に free() します。

注意: libusb_dev_mem_alloc() で割り当てたバッファは、この方法で解放しようとしないでください。 free() はそのようなメモリを解放する適切な方法ではないためです。

LIBUSB_TRANSFER_FREE_TRANSFER 

コールバックから戻った後、 libusb_free_transfer() を自動的に呼び出します。

このフラグが設定されている場合、転送のコールバックから libusb_free_transfer() を呼び出すことは違法です。これは、このフラグが実行されたときに二重開放になるためです。

LIBUSB_TRANSFER_ADD_ZERO_PACKET 

エンドポイントのwMaxPacketSizeの倍数である転送を、長さがゼロの余分なパケットで終了します。

これは、デバイスのプロトコルが、各論理要求を不完全なパケットで終了することを要求している場合に役立ちます(つまり、論理要求が他の手段で分離されていない場合)。

このフラグは、バルク・エンドポイントと割り込みエンドポイントの、ホストからデバイスへの方向の転送にのみ影響します。 他の状況では、これは無視されます。

このフラグは、エンドポイントのwMaxPacketSizeの倍数である長さの転送にのみ影響します。 他の長さの転送では、このフラグは効果がありません。 したがって、論理要求の終わりがパケット境界に達するたびにZLPを必要とするデバイスを使用している場合は、全ての転送でこのフラグを設定するのが賢明です(境界で終了する転送にのみ設定する事を考慮する必要はありません)。

このフラグは現在、Linuxでのみサポートされています。 他のシステムでは、 libusb_submit_transfer() は、このフラグが設定されているすべての転送に対してLIBUSB_ERROR_NOT_SUPPORTEDを返します。

libusb-1.0.9以降で使用できます。

関数解説

◆ libusb_alloc_streams()

int libusb_alloc_streams ( libusb_device_handle dev_handle,
uint32_t  num_streams,
unsigned char *  endpoints,
int  num_endpoints 
)

指定のエンドポイントにnum_streams個のUSBバルク・ストリームを割り当てます。一部のプロトコルではエンドポイントを同じストリームIDでセットアップする必要があるため、この関数は単一のエンドポイントではなくエンドポイントの配列を取ります。渡されるすべてのエンドポイントは、同じインターフェースに属している必要があります。

注意: この関数は、要求よりも少ない数のストリームを返す可能性があることに注意してください。 また、エンドポイント配列の各エンドポイントにそれぞれ同じ数のストリームが割り当てられることに注意してください。

ストリームID 0 は予約済のため、デバイスとの通信には使用しないでください。 libusb_alloc_streams() が値Nを返した場合、ストリームID 1〜N を使用できます。

バージョン1.0.19以降。 LIBUSB_API_VERSION >= 0x01000103

パラメーター
dev_handleデバイス・ハンドル
num_streams割り当てを試みるストリームの数
endpointsストリームを割り当てるエンドポイントの配列
num_endpointsエンドポイント配列のサイズ
戻り値
割り当てられたストリームの数、また、失敗した場合はLIBUSB_ERRORコード

◆ libusb_free_streams()

int libusb_free_streams ( libusb_device_handle dev_handle,
unsigned char *  endpoints,
int  num_endpoints 
)

libusb_alloc_streams() で割り当てられたUSBバルク・ストリームを解放します。

注意: インターフェイスを解放すると、ストリームは自動的に解放されます。

バージョン1.0.19以降。 LIBUSB_API_VERSION >= 0x01000103

パラメーター
dev_handleデバイス・ハンドル
endpointsストリームを開放したいエンドポイントの配列
num_endpointsエンドポイント配列のサイズ
戻り値
LIBUSB_SUCCESS、または、失敗の場合はLIBUSB_ERRORコード

◆ libusb_dev_mem_alloc()

unsigned char* libusb_dev_mem_alloc ( libusb_device_handle dev_handle,
size_t  length 
)

特定のデバイスに対する転送に適した永続的なDMAメモリのブロックを割り当てようとします。 成功すると、このデバイスに対する libusb_transfer の "バッファ" として使用するのに適したメモリ・ブロックが返されます。通常のメモリの代わりにこのメモリを使用すると、ホスト・コントローラはDMAを直接バッファに使用してパフォーマンスを向上させることができ、カーネル・メモリの断片化が原因で転送が失敗することもなくなります。

注意:これは、転送の進行中にこのメモリ(または同じキャッシュ・ライン上のデータ)を変更してはならないことを意味しますが、同じメモリブロック内で複数の転送を実行することは合法です。

失敗するとNULLを返します。多くのシステムはそのようなゼロ・コピーをサポートしておらず、常にNULLを返します。この関数で割り当てられたメモリは、 libusb_dev_mem_free で解放する必要があります。 具体的には、これは、フラグLIBUSB_TRANSFER_FREE_BUFFERを使用して、この関数で割り当てられたメモリを解放できないことを意味します。

Since version 1.0.21, LIBUSB_API_VERSION >= 0x01000105

パラメーター
dev_handleデバイス・ハンドル
length必要なデータ・バッファのサイズ
戻り値
新しく割り当てられたメモリへのポインタ、または失敗した場合はNULL

◆ libusb_dev_mem_free()

int libusb_dev_mem_free ( libusb_device_handle dev_handle,
unsigned char *  buffer,
size_t  length 
)

libusb_dev_mem_alloc() で割り当てられたデバイス・メモリを解放します。

パラメーター
dev_handleデバイス・ハンドル
buffer以前に割り当てられたメモリへのポインタ
length以前に割り当てられたメモリのサイズ
戻り値
LIBUSB_SUCCESS、または、失敗の場合はLIBUSB_ERRORコード

◆ libusb_alloc_transfer()

struct libusb_transfer* libusb_alloc_transfer ( int  iso_packets)

指定された数のアイソクロナス・パケット・デスクリプターを使用してlibusb転送を割り当てます。返される転送は事前に初期化されています。最早新しい転送が不要になったら、 libusb_free_transfer() で解放する必要があります。

非アイソクロナス・エンドポイント(制御、バルク、割り込みなど)を対象とした転送では、iso_packetsカウントをゼロに指定すべきです。

アイソクロナス・エンドポイントを対象とした転送の場合、その転送の一部として割り当てられる適切な数のパケット・デスクリプターを指定します。 その戻される転送は、アイソクロナス入出力用に特別に初期化されてはいません。それでも、それに応じて num_iso_packets フィールドと type フィールドを設定する必要があります。

いくつかのアイソクロナス・パケットを使用して転送を割り当て、それを非アイソクロナス・エンドポイントで使用するのが安全です。これを行う場合は、送信時にnum_iso_packetsが0であり、そのtypeが適切に設定されていることを確認してください。

パラメーター
iso_packets割り当てるアイソクロナス・パケット・デスクリプターの数。負でない数値である必要があります。
戻り値
新しく割り当てられた転送、またはエラーの場合はNULL

◆ libusb_free_transfer()

void libusb_free_transfer ( struct libusb_transfer transfer)

転送構造体を解放します。これは、 libusb_alloc_transfer() で割り当てられたすべての転送に対して呼び出す必要があります。

LIBUSB_TRANSFER_FREE_BUFFER フラグが設定されていて、そして転送バッファーがNULL以外の場合、この関数は標準のシステム・メモリ割り当て機構(例: free() )を使用して転送バッファーも解放します。

NULL転送でこの関数を呼び出すことは合法です。この場合、関数は単に安全に戻ります。

アクティブな転送(送信(submit)され、まだ完了していない転送)を解放することは違法です。

パラメーター
transfer開放したい転送

◆ libusb_submit_transfer()

int libusb_submit_transfer ( struct libusb_transfer transfer)

転送を送信します。この関数は、USB転送を開始し、すぐに戻ります。

パラメーター
transfer送信する転送
戻り値
0ならば成功
LIBUSB_ERROR_NO_DEVICE: デバイスが切断されていた
LIBUSB_ERROR_BUSY: その転送がすでに送信されている(submitted)場合。
LIBUSB_ERROR_NOT_SUPPORTED: その転送フラグがオペレーティング・システムでサポートされていない場合。
LIBUSB_ERROR_INVALID_PARAM: 転送サイズがオペレーティング・システムやハードウェアでサポートできるサイズよりも大きい場合(転送の長さの制限 を参照)。
LIBUSB_ERRORコード: その他の障害

◆ libusb_cancel_transfer()

int libusb_cancel_transfer ( struct libusb_transfer transfer)

以前に送信された転送を非同期的にキャンセルします。この関数はすぐに戻りますが、それはキャンセルが完了したことを示すものではありません。後で、転送ステータスLIBUSB_TRANSFER_CANCELLEDでコールバック関数が呼び出されます。

パラメーター
transferキャンセルしたい転送
戻り値
0ならば成功
LIBUSB_ERROR_NOT_FOUND 転送が現在進行中でないか、または既に完了したか、または既にキャンセルされた場合。
LIBUSB_ERRORコード: 失敗の場合。

◆ libusb_transfer_set_stream_id()

void libusb_transfer_set_stream_id ( struct libusb_transfer transfer,
uint32_t  stream_id 
)

転送バルク・ストリームIDを設定します。この関数を直接呼び出すのではなく、 libusb_fill_bulk_stream_transfer() を使用することをお勧めします。

バージョン1.0.19以降。 LIBUSB_API_VERSION >= 0x01000103

パラメーター
transferストリームIDをセットしたい転送
stream_idセットしたいストリームID
これも参照下さい
libusb_alloc_streams()

◆ libusb_transfer_get_stream_id()

uint32_t libusb_transfer_get_stream_id ( struct libusb_transfer transfer)

転送バルク・ストリームIDを取得します。

バージョン1.0.19以降。 LIBUSB_API_VERSION >= 0x01000103

パラメーター
transferストリームIDを取得したい転送
戻り値
その転送のストリームID

◆ libusb_control_transfer_get_data()

static unsigned char* libusb_control_transfer_get_data ( struct libusb_transfer transfer)
inlinestatic

制御転送のデータ・セクションを取得します。この便利な関数は、セットアップ・パケットが最初に来るため、実際のバッファに8バイト入るまでデータが開始されないことを思い出させるためにここにあります。

この関数の呼び出しは、転送コールバック関数、または transfer-&gt; buffer で適切なサイズのバッファをすでに割り当てている状況からのみ意味があります。

パラメーター
transferとある一つの転送
戻り値
データ・セクションの最初のバイトへのポインタ

◆ libusb_control_transfer_get_setup()

static struct libusb_control_setup* libusb_control_transfer_get_setup ( struct libusb_transfer transfer)
inlinestatic

制御転送の制御セットアップ・パケットを取得します。 この便利な関数は、制御セットアップが転送データ・バッファの最初の8バイトを占めることを思い出させるためにここにあります。

この関数の呼び出しは、転送コールバック関数、または transfer-&gt; buffer で適切なサイズのバッファをすでに割り当てている状況からのみ意味があります。

パラメーター
transferとある一つの転送
戻り値
転送データバッファの開始へのキャストされたポインタ

◆ libusb_fill_control_setup()

static void libusb_fill_control_setup ( unsigned char *  buffer,
uint8_t  bmRequestType,
uint8_t  bRequest,
uint16_t  wValue,
uint16_t  wIndex,
uint16_t  wLength 
)
inlinestatic

制御転送用のセットアップ・パケット(データ・バッファの最初の8バイト)を設定するヘルパー関数。 wIndexとwValueとwLengthの値は、ホスト・エンディアンのバイト順序で指定する必要があります。

パラメーター
bufferセットアップ・パケットを出力するバッファこのポインタは、少なくとも2バイト境界に揃える必要があります。
bmRequestTypelibusb_control_setupbmRequestType フィールドを参照してください
bRequestlibusb_control_setupbRequest フィールドを参照して下さい
wValuelibusb_control_setupwValue フィールドを参照して下さい
wIndexlibusb_control_setupwIndex フィールドを参照して下さい
wLengthlibusb_control_setupwLength フィールドを参照して下さい

◆ libusb_fill_control_transfer()

static void libusb_fill_control_transfer ( struct libusb_transfer transfer,
libusb_device_handle dev_handle,
unsigned char *  buffer,
libusb_transfer_cb_fn  callback,
void *  user_data,
unsigned int  timeout 
)
inlinestatic

制御転送に必要な libusb_transfer フィールドに情報を入力するヘルパー関数。

この関数に転送バッファーを渡すと、最初の8バイトが制御セットアップ・パケットとして解釈され、wLengthフィールドを使用して転送の length フィールドに自動的に入力されます。したがって、推奨されるアプローチは以下のとおりです:

  1. (制御セットアップ用のスペースを含む)適切なサイズのデータ・バッファを割り当てます
  2. libusb_fill_control_setup() を呼び出します
  3. これがデータ・ステージを使用したホストからデバイスへの転送である場合は、セットアップ・パケットの後ろにデータを配置します
  4. この関数を呼び出します
  5. libusb_submit_transfer() を呼び出します。

この関数にNULLバッファーを渡すことも合法です。この場合、この関数はlengthフィールドにデータを入力しようとしません。 後でバッファ・フィールドとlengthフィールドにデータを入力する必要があることに注意してください。

パラメーター
transfer入力対象の転送
dev_handle転送を処理するデバイスのハンドル
bufferデータ・バッファ。 指定されている場合、この関数は最初の8バイトをセットアップ・パケットとして解釈し、そこから転送長を推測します。このポインタは、少なくとも2バイト境界に揃える必要があります。
callback転送完了時に呼び出されるコールバック関数
user_dataコールバック関数に渡すユーザー・データ
timeout転送のタイムアウト(ミリ秒単位)

◆ libusb_fill_bulk_transfer()

static void libusb_fill_bulk_transfer ( struct libusb_transfer transfer,
libusb_device_handle dev_handle,
unsigned char  endpoint,
unsigned char *  buffer,
int  length,
libusb_transfer_cb_fn  callback,
void *  user_data,
unsigned int  timeout 
)
inlinestatic

バルク転送に必要な libusb_transfer のフィールド群にデータを入力するヘルパー関数。

パラメーター
transfer入力対象の転送
dev_handle転送を処理するデバイスのハンドル
endpointこの転送を送るエンドポイントのアドレス
bufferデータ・バッファ
lengthデータ・バッファの長さ
callback転送完了時に呼び出されるコールバック関数
user_dataコールバック関数に渡すユーザー・データ
timeout転送のタイムアウト(ミリ秒単位)

◆ libusb_fill_bulk_stream_transfer()

static void libusb_fill_bulk_stream_transfer ( struct libusb_transfer transfer,
libusb_device_handle dev_handle,
unsigned char  endpoint,
uint32_t  stream_id,
unsigned char *  buffer,
int  length,
libusb_transfer_cb_fn  callback,
void *  user_data,
unsigned int  timeout 
)
inlinestatic

バルク・ストリームを使用したバルク転送に必要な libusb_transfer のフィールド群にデータを入力するヘルパー関数。

バージョン1.0.19以降。 LIBUSB_API_VERSION >= 0x01000103

パラメーター
transfer入力対象の転送
dev_handle転送を処理するデバイスのハンドル
endpointこの転送を送るエンドポイントのアドレス
stream_idこの転送のバルク・ストリームID
bufferデータ・バッファ
lengthデータ・バッファの長さ
callback転送完了時に呼び出されるコールバック関数
user_dataコールバック関数に渡すユーザー・データ
timeout転送のタイムアウト(ミリ秒単位)

◆ libusb_fill_interrupt_transfer()

static void libusb_fill_interrupt_transfer ( struct libusb_transfer transfer,
libusb_device_handle dev_handle,
unsigned char  endpoint,
unsigned char *  buffer,
int  length,
libusb_transfer_cb_fn  callback,
void *  user_data,
unsigned int  timeout 
)
inlinestatic

割り込み転送に必要な libusb_transfer のフィールド群にデータを入力するヘルパー関数。

パラメーター
transfer入力対象の転送
dev_handle転送を処理するデバイスのハンドル
endpointこの転送を送るエンドポイントのアドレス
bufferデータ・バッファ
lengthデータ・バッファの長さ
callback転送完了時に呼び出されるコールバック関数
user_dataコールバック関数に渡すユーザー・データ
timeout転送のタイムアウト(ミリ秒単位)

◆ libusb_fill_iso_transfer()

static void libusb_fill_iso_transfer ( struct libusb_transfer transfer,
libusb_device_handle dev_handle,
unsigned char  endpoint,
unsigned char *  buffer,
int  length,
int  num_iso_packets,
libusb_transfer_cb_fn  callback,
void *  user_data,
unsigned int  timeout 
)
inlinestatic

アイソクロナス転送に必要な libusb_transfer のフィールド群にデータを入力するヘルパー関数。

パラメーター
transfer入力対象の転送
dev_handle転送を処理するデバイスのハンドル
endpointこの転送を送るエンドポイントのアドレス
bufferデータ・バッファ
lengthデータ・バッファの長さ
num_iso_packetsアイソクロナス・パケットの数
callback転送完了時に呼び出されるコールバック関数
user_dataコールバック関数に渡すユーザー・データ
timeout転送のタイムアウト(ミリ秒単位)

◆ libusb_set_iso_packet_lengths()

static void libusb_set_iso_packet_lengths ( struct libusb_transfer transfer,
unsigned int  length 
)
inlinestatic

転送構造構造体のnum_iso_packetsフィールドに基づいて、アイソクロナス転送でのすべてのパケットの長さを設定する便利な関数。

パラメーター
transferとある一つの転送
length各アイソクロナス・パケット・デスクリプターに設定する長さ
これも参照下さい
libusb_get_max_packet_size()

◆ libusb_get_iso_packet_buffer()

static unsigned char* libusb_get_iso_packet_buffer ( struct libusb_transfer transfer,
unsigned int  packet 
)
inlinestatic

アイソクロナス転送のバッファ内でアイソクロナス・パケットの位置を特定するための便利な関数。

これは、先行するすべてのパケットに対して繰り返し作業を行い、それらの長さを足しこんで指定されたパケットの位置を見つける完全な関数です。通常、転送では各パケットに同じ長さを割り当てるため、この方法は最適とは言えません。代わりに libusb_get_iso_packet_buffer_simple() を使用することをお勧めします。

パラメーター
transferとある一つの転送
packetアドレスを知りたいパケット(訳注:パケットNo. 0〜)
戻り値
転送バッファ内のパケット・バッファのベース・アドレス。パケットが存在しない場合はNULL。
これも参照下さい
libusb_get_iso_packet_buffer_simple()

◆ libusb_get_iso_packet_buffer_simple()

static unsigned char* libusb_get_iso_packet_buffer_simple ( struct libusb_transfer transfer,
unsigned int  packet 
)
inlinestatic

各パケットが同じサイズの転送の場合、アイソクロナス転送のバッファ内でアイソクロナス・パケットの位置を特定するための便利な関数。

この関数は、その転送内のすべてのパケットが最初のパケットと同じサイズであるという仮定に依存しています。パケット・バッファの位置の計算は buffer + (packet_size * packet) という単純な計算です。

各パケットのパケット長が同じである転送以外の転送では、この関数を使用しないでください。

パラメーター
transferとある一つの転送
packetアドレスを知りたいパケット(訳注:パケットNo. 0〜)
戻り値
転送バッファ内のパケット・バッファのベース・アドレス。パケットが存在しない場合はNULL。
これも参照下さい
libusb_get_iso_packet_buffer()
int libusb_handle_events(libusb_context *ctx)
定義: io.c:2407
void libusb_exit(libusb_context *ctx)
定義: core.c:2385
libusb_device_handle * dev_handle
この転送が送信されるデバイスのハンドル。
定義: libusb.h:1224
void libusb_hotplug_deregister_callback(libusb_context *ctx, libusb_hotplug_callback_handle callback_handle)
定義: hotplug.c:404
void libusb_close(libusb_device_handle *dev_handle)
定義: core.c:1446
struct libusb_device_handle libusb_device_handle
定義: libusb.h:1015