vc2013 开发 winusb 简单测试程序 基于 nu_bridge
nu_bridge是新唐的牛橋,借助該USB工具,pc端可以方便的調試外部的SPI, I2C設備。
新唐提供的驅動包中已經包含了winusb的驅動。
在測試下面的程序之前需要安裝驅動。
這里是用vs2013 開發一個簡單的winUSB控制臺測試程序,幫助入門winUSB的API。
新建一個控制臺工程:nu_bridge_simple
點擊完成
添加文件:
文件:device.cpp
#include "pch.h"#include <SetupAPI.h>HRESULT RetrieveDevicePath(_Out_bytecap_(BufLen) LPTSTR DevicePath,_In_ ULONG BufLen,_Out_opt_ PBOOL FailureDeviceNotFound);HRESULT OpenDevice(_Out_ PDEVICE_DATA DeviceData,_Out_opt_ PBOOL FailureDeviceNotFound) /*++Routine description:Open all needed handles to interact with the device.If the device has multiple USB interfaces, this function grants access toonly the first interface.If multiple devices have the same device interface GUID, there is noguarantee of which one will be returned.Arguments:DeviceData - Struct filled in by this function. The caller should use theWinusbHandle to interact with the device, and must pass the struct toCloseDevice when finished.FailureDeviceNotFound - TRUE when failure is returned due to no devicesfound with the correct device interface (device not connected, drivernot installed, or device is disabled in Device Manager); FALSEotherwise.Return value:HRESULT--*/ {HRESULT hr = S_OK;BOOL bResult;DeviceData->HandlesOpen = FALSE;hr = RetrieveDevicePath(DeviceData->DevicePath,sizeof(DeviceData->DevicePath),FailureDeviceNotFound);if (FAILED(hr)) {return hr;}DeviceData->DeviceHandle = CreateFile(DeviceData->DevicePath,GENERIC_WRITE | GENERIC_READ,FILE_SHARE_WRITE | FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,NULL);if (INVALID_HANDLE_VALUE == DeviceData->DeviceHandle) {hr = HRESULT_FROM_WIN32(GetLastError());return hr;}bResult = WinUsb_Initialize(DeviceData->DeviceHandle,&DeviceData->WinusbHandle);if (FALSE == bResult) {hr = HRESULT_FROM_WIN32(GetLastError());CloseHandle(DeviceData->DeviceHandle);return hr;}DeviceData->HandlesOpen = TRUE;return hr; }VOID CloseDevice(_Inout_ PDEVICE_DATA DeviceData) /*++Routine description:Perform required cleanup when the device is no longer needed.If OpenDevice failed, do nothing.Arguments:DeviceData - Struct filled in by OpenDeviceReturn value:None--*/ {if (FALSE == DeviceData->HandlesOpen) {//// Called on an uninitialized DeviceData//return;}WinUsb_Free(DeviceData->WinusbHandle);CloseHandle(DeviceData->DeviceHandle);DeviceData->HandlesOpen = FALSE;return; } //下面的OSR_DEVICE_INTERFACE是從牛橋的pc端軟件copy過來的 static const GUID OSR_DEVICE_INTERFACE ={ 0x1f4911f2, 0xc55d, 0x4561, { 0x98, 0x7a, 0xbc, 0xfa, 0x74, 0xd5, 0xbb, 0x6d } };HRESULT RetrieveDevicePath(_Out_bytecap_(BufLen) LPTSTR DevicePath,_In_ ULONG BufLen,_Out_opt_ PBOOL FailureDeviceNotFound) /*++Routine description:Retrieve the device path that can be used to open the WinUSB-based device.If multiple devices have the same device interface GUID, there is noguarantee of which one will be returned.Arguments:DevicePath - On successful return, the path of the device (use with CreateFile).BufLen - The size of DevicePath's buffer, in bytesFailureDeviceNotFound - TRUE when failure is returned due to no devicesfound with the correct device interface (device not connected, drivernot installed, or device is disabled in Device Manager); FALSEotherwise.Return value:HRESULT--*/ {BOOL bResult = FALSE;HDEVINFO deviceInfo;SP_DEVICE_INTERFACE_DATA interfaceData;PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL;ULONG length;ULONG requiredLength=0;HRESULT hr;if (NULL != FailureDeviceNotFound) {*FailureDeviceNotFound = FALSE;}printf("RetrieveDevicePath \n");//// Enumerate all devices exposing the interface///*deviceInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USBApplication1,NULL,NULL,DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);*/deviceInfo = SetupDiGetClassDevs(&OSR_DEVICE_INTERFACE,NULL,NULL,DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);if (deviceInfo == INVALID_HANDLE_VALUE) {hr = HRESULT_FROM_WIN32(GetLastError());return hr;}interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);//// Get the first interface (index 0) in the result set//bResult = SetupDiEnumDeviceInterfaces(deviceInfo,NULL,&OSR_DEVICE_INTERFACE,0,&interfaceData);if (FALSE == bResult) {//// We would see this error if no devices were found//if (ERROR_NO_MORE_ITEMS == GetLastError() &&NULL != FailureDeviceNotFound) {*FailureDeviceNotFound = TRUE;}hr = HRESULT_FROM_WIN32(GetLastError());SetupDiDestroyDeviceInfoList(deviceInfo);return hr;}//// Get the size of the path string// We expect to get a failure with insufficient buffer//bResult = SetupDiGetDeviceInterfaceDetail(deviceInfo,&interfaceData,NULL,0,&requiredLength,NULL);if (FALSE == bResult && ERROR_INSUFFICIENT_BUFFER != GetLastError()) {hr = HRESULT_FROM_WIN32(GetLastError());SetupDiDestroyDeviceInfoList(deviceInfo);return hr;}//// Allocate temporary space for SetupDi structure//detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LMEM_FIXED, requiredLength);if (NULL == detailData){hr = E_OUTOFMEMORY;SetupDiDestroyDeviceInfoList(deviceInfo);return hr;}detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);length = requiredLength;//// Get the interface's path string//bResult = SetupDiGetDeviceInterfaceDetail(deviceInfo,&interfaceData,detailData,length,&requiredLength,NULL);if(FALSE == bResult){hr = HRESULT_FROM_WIN32(GetLastError());LocalFree(detailData);SetupDiDestroyDeviceInfoList(deviceInfo);return hr;}//// Give path to the caller. SetupDiGetDeviceInterfaceDetail ensured// DevicePath is NULL-terminated.//hr = StringCbCopy(DevicePath,BufLen,detailData->DevicePath);LocalFree(detailData);SetupDiDestroyDeviceInfoList(deviceInfo);return hr; }其中下面這句話比較關鍵是和驅動配合使用的:
//下面的OSR_DEVICE_INTERFACE是從牛橋的pc端軟件copy過來的 static const GUID OSR_DEVICE_INTERFACE ={ 0x1f4911f2, 0xc55d, 0x4561, { 0x98, 0x7a, 0xbc, 0xfa, 0x74, 0xd5, 0xbb, 0x6d } };文件:device.h
// // Define below GUIDs // #include <initguid.h>// // Device Interface GUID. // Used by all WinUsb devices that this application talks to. // Must match "DeviceInterfaceGUIDs" registry value specified in the INF file. // cce59234-f9f6-43c8-9007-a61e760fb59f ////DEFINE_GUID(GUID_DEVINTERFACE_USBApplication1, // 0xcce59234,0xf9f6,0x43c8,0x90,0x07,0xa6,0x1e,0x76,0x0f,0xb5,0x9f);//下面這句話沒有用到 DEFINE_GUID(GUID_DEVINTERFACE_USBApplication1,0x1f4911f2, 0xc55d, 0x4561, 0x98, 0x7a, 0xbc, 0xfa, 0x74, 0xd5, 0xbb, 0x6d);typedef struct _DEVICE_DATA {BOOL HandlesOpen;WINUSB_INTERFACE_HANDLE WinusbHandle;HANDLE DeviceHandle;TCHAR DevicePath[MAX_PATH];} DEVICE_DATA, *PDEVICE_DATA;HRESULT OpenDevice(_Out_ PDEVICE_DATA DeviceData,_Out_opt_ PBOOL FailureDeviceNotFound);VOID CloseDevice(_Inout_ PDEVICE_DATA DeviceData);文件:pch.h
#include <Windows.h> #include <tchar.h> #include <strsafe.h> #include <winusb.h> #include <usb.h>#include "device.h"將nu_bridge_simple.cpp中的所有內容刪掉:
替換為如下內容:
添加完文件之后,需要添加庫:
添加的庫的名稱是:
winusb.lib
setupapi.lib
將牛橋插入PC 的usb端口,然后編譯程序,然后執行
運行效果如下:
RetrieveDevicePath Device found: VID_0416&PID_3101; bcdUsb 0110然后按下鍵盤任意鍵,退出程序。
參考內容:
1.How to Access a USB Device by Using WinUSB Functions
https://docs.microsoft.com/zh-cn/windows-hardware/drivers/usbcon/using-winusb-api-to-communicate-with-a-usb-device
2.Write a Windows desktop app based on the WinUSB template
https://docs.microsoft.com/zh-cn/windows-hardware/drivers/usbcon/how-to-write-a-windows-desktop-app-that-communicates-with-a-usb-device
3.How to Access a USB Device by Using WinUSB Functions
https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/using-winusb-api-to-communicate-with-a-usb-device
參考軟件:
[0508] NuBridge SW/NuBridge.exe 源碼 vs2008 MFC
繼續:
將nu_bridge_simple.cpp中的所有內容刪掉:
替換為如下內容:
運行效果:
RetrieveDevicePath Device speed: 1 (Low speed). Endpoint index: 0 Pipe type: Bulk Pipe ID: Endpoint index: 1 Pipe type: Bulk Pipe ID: PipeID.PipeInId = 132 PipeID.PipeOutId = 5 NU_WritePipe NU_WritePipe NU_ReadPipe Nu_ReadCmd len= 10 1,0,6,0,ff,ff,ff,ff,51,14, 請按任意鍵繼續. . .End
總結
以上是生活随笔為你收集整理的vc2013 开发 winusb 简单测试程序 基于 nu_bridge的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android基础字符串String.m
- 下一篇: [BZOJ1669][Usaco2006