【usb】winusbインターフェース設計分析

インターフェイスハンドルを取得

  • まず、CreateFileを使用してデバイス操作ハンドルを取得しますDeviceHandle
  • 次に、WinUsb_InitializeGet Interface Operation Handle を使用して、デフォルトでデバイスの最初のインターフェイスの操作ハンドルを取得します。

コントロール転送

BOOL WinUsb_ControlTransfer(
  [in]            WINUSB_INTERFACE_HANDLE InterfaceHandle,
  [in]            WINUSB_SETUP_PACKET     SetupPacket,
  [out]           PUCHAR                  Buffer,
  [in]            ULONG                   BufferLength,
  [out, optional] PULONG                  LengthTransferred,
  [in, optional]  LPOVERLAPPED            Overlapped
);
  • InterfaceHandle上記でWinUsb_Initialize取得したインターフェース操作ハンドルです。
  • SetupPacketUSB プロトコルの Setup パッケージに相当します。
  • Bufferデータを送受信するバッファ。
  • BufferLengthバッファサイズ。
  • LengthTransferred実際に送受信されたデータの長さ。
  • Overlapped非同期送信に使用されます. このフィールドが設定されていない場合, インターフェイスは同期インターフェイスです. 関数は送信が完了するまで戻りません. それ以外の場合、関数はすぐに戻り、送信が完了すると、Overlappedメカニズムを介してコールバック通知が行われます。

重複メカニズムの紹介

エンドポイント情報を取得する

インターフェイス情報を取得する

BOOL WinUsb_QueryInterfaceSettings(
  [in]  WINUSB_INTERFACE_HANDLE   InterfaceHandle,
  [in]  UCHAR                     AlternateInterfaceNumber,
  [out] PUSB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor
);
  • USB_INTERFACE_DESCRIPTORUSB プロトコルの標準インターフェイス記述子に相当します。このパラメーターを通じて、インターフェイスにあるエンドポイントの数を知ることができます。

エンドポイント情報を取得する

BOOL WinUsb_QueryPipe(
  [in]  WINUSB_INTERFACE_HANDLE  InterfaceHandle,
  [in]  UCHAR                    AlternateInterfaceNumber,
  [in]  UCHAR                    PipeIndex,
  [out] PWINUSB_PIPE_INFORMATION PipeInformation
);

typedef struct _WINUSB_PIPE_INFORMATION {
    
    
  USBD_PIPE_TYPE PipeType;
  UCHAR          PipeId;
  USHORT         MaximumPacketSize;
  UCHAR          Interval;
} WINUSB_PIPE_INFORMATION, *PWINUSB_PIPE_INFORMATION;

エンドポイントの数がわかれば、エンドポイント情報を 1 つずつ取得できます。

  • WINUSB_PIPE_INFORMATIONこのパラメータにより、パイプの種類 (コントロール転送/バルク転送/インタラプト転送/アイソクロナス転送) と、パイプの方向 (ホストからデバイスまたはデバイスからホスト) を知ることができます。

バルク (bulk) 転送と割り込み (interrupt) 転送を実行する

  • 上記のエンドポイント情報により、エンドポイントがサポートする伝送タイプとそのデータ伝送の方向を知ることができます。その後、エンドポイントの情報に基づいてデータ送信を実行できます。
BOOL WinUsb_ReadPipe(
  [in]            WINUSB_INTERFACE_HANDLE InterfaceHandle,
  [in]            UCHAR                   PipeID,
  [out]           PUCHAR                  Buffer,
  [in]            ULONG                   BufferLength,
  [out, optional] PULONG                  LengthTransferred,
  [in, optional]  LPOVERLAPPED            Overlapped
);

BOOL WinUsb_WritePipe(
  [in]            WINUSB_INTERFACE_HANDLE InterfaceHandle,
  [in]            UCHAR                   PipeID,
  [in]            PUCHAR                  Buffer,
  [in]            ULONG                   BufferLength,
  [out, optional] PULONG                  LengthTransferred,
  [in, optional]  LPOVERLAPPED            Overlapped
);
  • インタラプト転送、バルク転送とも上記 2 つのインタフェースを使用してデータを転送します。エンドポイント情報により、パイプラインの伝送方向を知ることができます。方向がホストからデバイスへの場合、それは書き込みです。つまり、インターフェイスを使用してWinUsb_WritePipeデータをエンドポイントに書き込む必要があります。
  • 方向がデバイスからホストへの場合、WinUsb_ReadPipeインターフェイスを使用してエンドポイントからデータを読み取ることができます。
  • コントロール転送と同様に、これら 2 つのインターフェイスは、Overlapped同期転送または非同期転送を制御するメカニズムを提供します。

パイプライン戦略

  • いわゆるパイプライン戦略とは、エンドポイントの動作を必要に応じて制御できることを意味します。たとえば、送信タイムアウト時間を設定します。または、リクエストを送信するときに、リクエスト パケットのサイズがエンドポイントが送信できる最大長の整数倍である場合、長さ 0 のパケットを送信する必要がありますか。インターフェイスは次のとおりです。
BOOL WinUsb_SetPipePolicy(
  [in] WINUSB_INTERFACE_HANDLE InterfaceHandle,
  [in] UCHAR                   PipeID,
  [in] ULONG                   PolicyType,
  [in] ULONG                   ValueLength,
  [in] PVOID                   Value
);

BOOL WinUsb_GetPipePolicy(
  [in]      WINUSB_INTERFACE_HANDLE InterfaceHandle,
  [in]      UCHAR                   PipeID,
  [in]      ULONG                   PolicyType,
  [in, out] PULONG                  ValueLength,
  [out]     PVOID                   Value
);

要約する

  • コントロール送信とアイソクロナス送信については、winusb がそれぞれ送信インタフェースを提供します。WinUsb_ControlTransfer , WinUsb_ReadIsochPipe, WinUsb_WriteIsochPipe.
  • バルク転送とインタラプト転送では、一組のインターフェイスが一律に使用されます。WinUsb_ReadPipeWinUsb_WritePipe
  • 上記のインターフェースはすべて、Overlappedメカニズムを介して同期伝送または非同期伝送を制御します。
  • パイプライン ポリシーを変更することで、パイプラインの動作をパーソナライズできます。
  • 上記のインターフェースに加えて、winusb にはさまざまなリクエストも用意されており、柔軟に使用できます。たとえば、IOCTL_GENERICUSBFN_GET_INTERFACE_DESCRIPTOR_SETインターフェイスのすべてのエンドポイント情報を取得できます。

参考文献

WinUSB 関数を使用して USB デバイスにアクセスする
パイプライン ポリシーを変更するための WinUSB 関数

おすすめ

転載: blog.csdn.net/C2681595858/article/details/129171307