Usb

WinUSBの操作方法は?



How Work With Winusb



解決:

WinUSBは2つの部分で構成されています。

  • WinUsb.sysは、USBデバイスのカーネルモードデバイススタックのプロトコルドライバーの上に、フィルターまたは関数ドライバーとしてインストールできるカーネルモードドライバーです。
  • WinUsb.dllは、WinUSBAPIを公開するユーザーモードDLLです。アプリケーションは、デバイスの関数ドライバーとしてインストールされている場合、このAPIを使用してWinUsb.sysと通信できます。 WinUSBAPI-WinUSB.dllによって公開されます。 WinUSBは、WinDDK BuildNumber Redist Winusbにある共同インストーラーパッケージWinUSBCoInstaller.dllの形式でWindowsDriver Kit(WDK)に含まれています。

アプリケーションでWinUSBAPIを使用するには:



  • WinUsb.hを含める
  • アプリケーションにリンクされているライブラリのリストにWinUsb.libを追加します。
  • Usb100.hには、いくつかの便利なマクロの宣言が含まれています。
  • デバイスインターフェイスGUIDを使用して、デバイスパスを取得します。正しいGUIDは、WinUsb.sysのインストールに使用されたINFで指定したGUIDです。
  • INFで定義したデバイスインターフェイスGUIDをSetupDiGetClassDevsに渡すことにより、デバイス情報セットへのハンドルを取得します。この関数はHDEVINFOハンドルを返します。
  • SetupDiEnumDeviceInterfacesを呼び出して、システムのデバイスインターフェイスを列挙し、デバイスインターフェイスに関する情報を取得します。
  • SetupDiGetDeviceInterfaceDetailを呼び出して、デバイスインターフェイスの詳細データを取得します。
  • GetDevicePath関数を呼び出して、デバイスパスを取得します。
  • デバイスパスをCreateFileに渡して、デバイスのファイルハンドルを取得します。使用する デバイスと通信するためのReadFileおよびWriteFile
  • ファイルハンドルをWinUsb_Initializeに渡して、WinUSBを初期化し、WinUSBハンドルを取得します。デバイスのファイルハンドルではなく、デバイスのWinUSBハンドルを使用して、WinUSBAPI関数を呼び出すときにデバイスを識別します。

より高度なソリューションの場合-関数を使用します。

  • WinUsb_QueryDeviceInformationを使用して、デバイスの速度を取得します。
  • WinUsb_QueryInterfaceSettingsを使用して、対応するインターフェイス記述子を取得します。 WinUSBハンドルは最初のインターフェースに対応します。
  • WinUsb_QueryPipeは、各エンドポイントに関する情報を取得します。
  • WinUsb_WritePipeはバッファをデバイスに書き込みます-デフォルトの動作:長さゼロの書き込みはスタックに転送されます。転送長が最大転送長よりも長い場合、WinUSBは要求を最大転送長の小さな要求に分割し、それらをシリアルに送信します。
  • その他の機能と情報:http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/winusb_howto.docx

デバッグの目的でおそらく必要なもの:winusbtrace_tool https://blogs.msdn.microsoft.com/usbcoreblog/2010/02/05/how-to-generate-and-view-a-winusb-debug-trace-log/; Wiresharkhttps://www.wireshark.orgとUSBPcapプラグイン。



その他の例:http://searchingforbit.blogspot.com/2012/04/winusb-communication-with-stm32-part-1.html。サンプルテンプレートはVisualStudioに付属しています。

また、.infファイルの作成に関する知識も必要です。

USBと通信するもう1つの簡単な方法-libusb-win32https://sourceforge.net/projects/libusb-win32/



私の簡単な例のコンソールアプリケーションは、データの小さな(キープアライブ用)チャンクをデバイスに送信します。

#include'stdafx.h '#include #include #include #include #include #pragma comment(lib、' hid.lib ')#pragma comment(lib、' setupapi.lib ')#pragma comment(lib、' winusb。 lib ')#include iString DevicePath; bool WinusbHandle_Open = false; bool DeviceHandle_Open = false; WINUSB_INTERFACE_HANDLE WinusbHandle; HANDLE DeviceHandle; UCHAR usb_out_buffer [64]; DEFINE_GUID(GUID_DEVCLASS_WINUSB、0x88bae032L、0x5a81、0x49f0、0xbc、0x3d、0xa4、0xff、0x13、0x82、0x16、0xd6); DEFINE_GUID(GUID_DEVCLASS_STL、0xf177724dL、0x74d3、0x430e、0x86、0xb5、0xf0、0x36、0x89、0x10、0xeb、0x23); GUID winusb_guid; GUID stl_guid; bool connectusb();ボイドdisconnectusb(); int main(){DWORD n; DWORD numEvents;ハンドルrHnd; WinusbHandle_Open = false; DeviceHandle_Open = false; winusb_guid = GUID_DEVCLASS_WINUSB; stl_guid = GUID_DEVCLASS_STL; usb_out_buffer [0] = 0; usb_out_buffer [1] = 1; usb_out_buffer [2] = 2; usb_out_buffer [3] = 3; ULONGバイト書き込み; ULONGタイムアウト;タイムアウト= 100; rHnd = GetStdHandle(STD_INPUT_HANDLE); WinUsb_SetPipePolicy(WinusbHandle、0x01、PIPE_TRANSFER_TIMEOUT、sizeof(ULONG)、&timeout);タイムアウト= TRUE; WinUsb_SetPipePolicy(WinusbHandle、0x01、AUTO_CLEAR_STALL、sizeof(ULONG)、&timeout);タイムアウト= TRUE; WinUsb_SetPipePolicy(WinusbHandle、0x01、RAW_IO、sizeof(ULONG)、&timeout); //キューイングとエラー処理をバイパスして、複数の読み取り要求のパフォーマンスを向上させます。 while(true){if((!WinusbHandle_Open)||(!WinusbHandle_Open)){if(!connectusb())Sleep(2000); } if((!WinusbHandle_Open)||(!WinusbHandle_Open))continue; bytesWritten = 0; if(!WinUsb_WritePipe(WinusbHandle、0x01、&usb_out_buffer [0]、2、&bytesWritten、NULL)){n = GetLastError();切断usb(); } Sleep(2000); } disconnectusb(); 0を返します。 } bool connectusb(){BOOL bResult = FALSE; HDEVINFO deviceInfo; SP_DEVICE_INTERFACE_DATA interfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL; DWORD n; SP_DEVINFO_DATA devinfo; BYTE devdetailbuffer [4096];ブール値が見つかりました。 deviceInfo = SetupDiGetClassDevs(&stl_guid、NULL、NULL、DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if(deviceInfo == INVALID_HANDLE_VALUE){falseを返す; } found = false; for(n = 0 ;; n ++){interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); if(!SetupDiEnumDeviceInterfaces(deviceInfo、NULL、&stl_guid、n、&interfaceData)){n = GetLastError();壊す; } detailData =(PSP_DEVICE_INTERFACE_DETAIL_DATA)devdetailbuffer; detailData-> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); devinfo.cbSize = sizeof(devinfo); if(!SetupDiGetDeviceInterfaceDetail(deviceInfo、&interfaceData、detailData、sizeof(devdetailbuffer)、NULL、&devinfo)){printf( 'SetupDiGetDeviceInterfaceDetail:%u  n'、GetLastError());壊す; } if(IsEqualGUID(devinfo.ClassGuid、winusb_guid)){if((-1!= iStrPos(detailData-> DevicePath、 'VID_0483'))||(-1!= iStrPos(detailData-> DevicePath、 'vid_0483') )){if((-1!= iStrPos(detailData-> DevicePath、 'PID_576B'))||(-1!= iStrPos(detailData-> DevicePath、 'pid_576b'))){DevicePath = detailData-> DevicePath;見つかった= true;壊す; }}}} SetupDiDestroyDeviceInfoList(deviceInfo); if(!found)return false; DeviceHandle = CreateFile(DevicePath.Buffer()、GENERIC_WRITE | GENERIC_READ、FILE_SHARE_WRITE | FILE_SHARE_READ、NULL、OPEN_EXISTING、FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED、NULL); if(INVALID_HANDLE_VALUE == DeviceHandle){n = GetLastError(); } if(INVALID_HANDLE_VALUE == DeviceHandle)はfalseを返します。 DeviceHandle_Open = true; if(!WinUsb_Initialize(DeviceHandle、&WinusbHandle)){n = GetLastError(); CloseHandle(DeviceHandle); DeviceHandle_Open = false; falseを返します。 } WinusbHandle_Open = true; trueを返します。 } voiddisconnectusb(){if(WinusbHandle_Open){WinUsb_Free(WinusbHandle); WinusbHandle_Open = false; } if(DeviceHandle_Open){CloseHandle(DeviceHandle); DeviceHandle_Open = false; }} 
  1. はい、USC CDCACMについて正しく説明しました。
  2. WinUSBは、特定のデバイスクラスを持たないデバイスをサポートするために存在します。デバイスがヒューマンインターフェイスデバイス、大容量記憶装置、通信デバイス(CDC)などのデバイスクラスを実装している場合は、オペレーティングシステムに付属のドライバーを使用してそのデバイスと通信できます。これらのクラスのいずれにも準拠しない、よりカスタマイズ可能で柔軟なUSBインターフェイスが必要な場合は、WinUSBを使用してデバイスと通信できます。必要に応じて独自のドライバーを作成することもできますが、それは大変な作業になるため、お勧めしません。 WinUSBの代替となるドライバーを作成した人もいます。たとえば、libusbK、libusb0.sys、UsbDKを検索できます。 WinUSBには、Windowsに付属しているという利点があるため、本当に必要な特定の機能がない限り、他のドライバーの1つを使用しません。
  3. 私は信じているWinUSB_WritePipeはデータを単一のUSBとして送信します 移行 。に 移行 USB仕様に特定の定義があります。転送の最後に短いパケットが届くので、転送がいつ終了するかがわかります。ショートパケットは、エンドポイントの最大パケットサイズよりも小さいパケットであり、長さがゼロである可能性があります。ただし、それが実際に正しいかどうかを再確認する必要があります。最大パケットサイズの倍数である転送を送信してみて、Windowsがその最後に長さゼロのパケットを送信することを確認してください。ちなみに、エンドポイント0での制御転送または一連の制御転送としてデータを送信することを検討する必要があります。制御転送には、要求と要求への応答の概念が組み込まれています。名前にもかかわらず、制御転送は大量のデータを転送するために使用できます。これらは一般的にUSBブートローダーで使用されます(DFUクラスを参照)。ゼロ以外のエンドポイントの代わりに制御転送を使用するもう1つの利点は、エンドポイント記述子を追加したり、ファームウェアでエンドポイントを初期化したりする必要がないことです。 USBスタックには、カスタム制御転送を処理するための機構が必要であり、いくつかのコールバック関数を記述するだけでカスタム制御転送を実行できる必要があります。
  4. デバイス側でWinUSBを実装するには、独自のUSB記述子を書き込んでから、低レベルのUSB転送コマンドを使用してエンドポイントからデータを読み書きするか、エンドポイント0でベンダー固有の制御転送を処理する必要があります。私はSTM32USBライブラリに精通していませんが、デバイスクラスに固有のことを何もしなくても、制御転送とINおよびOUTエンドポイントを実装するそのコアコンポーネントを識別できるはずです。これは、使用方法を学ぶために必要なコンポーネントです。
  5. デフォルトでは、USB CDCACMの代わりにWinUSBを使用する必要があります。 USB CDC ACMを使用する唯一の理由は、デバイスが実際にシリアルポートである場合、またはさまざまなプログラミング言語や環境でデバイスと簡単に会話できるようにする場合です。ほとんどのプログラミング言語はシリアルポートをサポートしていますが、ユーザーは特定のコマンド形式を生成するコードをその上に記述する必要があるため、実際にはそれほど多くは提供されません。 USB CDC ACMの問題の1つは、ハンドルを開いているときにデバイスが切断され、その後再接続されると、さまざまなUSB CDCACMドライバーが不良状態になることがよくあることです。特に、Windows 10より前のusbser.sysはこれをうまく処理できず、通常、COMポートを再び使用できるようにするには、デバイスのプラグを抜いてから再度差し込む必要があります。 USB CDC ACMは、データ転送にバルクエンドポイントを使用するため、遅延の保証はありません。 WinUSBでは、割り込みエンドポイントを使用するオプションがあり、USBフレームごとに常に1つのパケットが転送されることが保証されます。

私もあなたのまったく同じ要件をしなければなりません:PC STM
Microsoftには、WinUSBに関する多くのドキュメントがあります。これがあなたの質問に答える私が見たものです...

カスタムUSBデバイスのサンプル
https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/CustomUsbDeviceAccess

USBデバイス用のWindowsアプリケーションの開発-C#およびVB
https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/developing-windows-applications-that-c​​ommunicate-with-a-usb-device

USBデバイス用のWindowsデスクトップアプリ
https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/windows-desktop-app-for-a-usb-device

WinUSB機能を使用してUSBデバイスにアクセスする方法
https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/using-winusb-api-to-communicate-with-a-usb-device

USBホストコントローラー用のWindowsドライバーの開発
https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/developing-windows-drivers-for-usb-host-controllers

Windows.Devices.UsbWindows.Devices.Usb名前空間
https://docs.microsoft.com/en-us/uwp/api/windows.devices.usb