日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

vc2013 开发 winusb 简单测试程序 基于 nu_bridge

發布時間:2023/12/20 c/c++ 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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中的所有內容刪掉:
替換為如下內容:

// nu_bridge_simple.cpp : 定義控制臺應用程序的入口點。 // //#include "stdafx.h"#include "pch.h"#include <stdio.h>LONG __cdecl _tmain( LONG Argc, LPTSTR * Argv ) /*++Routine description:Sample program that communicates with a USB device using WinUSB--*/ {DEVICE_DATA deviceData;HRESULT hr;USB_DEVICE_DESCRIPTOR deviceDesc;BOOL bResult;BOOL noDevice;ULONG lengthReceived;UNREFERENCED_PARAMETER(Argc);UNREFERENCED_PARAMETER(Argv);//// Find a device connected to the system that has WinUSB installed using our// INF//hr = OpenDevice(&deviceData, &noDevice);if (FAILED(hr)) {if (noDevice) {printf("Device not connected or driver not installed\n");}else {printf("Failed looking for device, HRESULT 0x%x\n", hr);}return 0;}//// Get device descriptor//bResult = WinUsb_GetDescriptor(deviceData.WinusbHandle,USB_DEVICE_DESCRIPTOR_TYPE,0,0,(PBYTE)&deviceDesc,sizeof(deviceDesc),&lengthReceived);if (FALSE == bResult || lengthReceived != sizeof(deviceDesc)) {printf("Error among LastError %d or lengthReceived %d\n",FALSE == bResult ? GetLastError() : 0,lengthReceived);CloseDevice(&deviceData);return 0;}//// Print a few parts of the device descriptor//printf("Device found: VID_%04X&PID_%04X; bcdUsb %04X\n",deviceDesc.idVendor,deviceDesc.idProduct,deviceDesc.bcdUSB);getchar();CloseDevice(&deviceData);return 0; }

添加完文件之后,需要添加庫:

添加的庫的名稱是:
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中的所有內容刪掉:
替換為如下內容:

// nu_bridge_simple.cpp : 定義控制臺應用程序的入口點。 // //#include "stdafx.h"#include "pch.h"#include <stdio.h>int NU_SetDeviceSpiMasteMode(_In_ WINUSB_INTERFACE_HANDLE InterfaceHandle) {WINUSB_SETUP_PACKET SetupPacket;SetupPacket.RequestType = 0x42;SetupPacket.Request = 1;SetupPacket.Value = 0;SetupPacket.Index = 0;SetupPacket.Length = 0;WinUsb_ControlTransfer(InterfaceHandle, SetupPacket, 0, 0, NULL, 0);return 0; }int NU_SetDeviceLED(_In_ WINUSB_INTERFACE_HANDLE InterfaceHandle) {WINUSB_SETUP_PACKET SetupPacket;SetupPacket.RequestType = 0x40;SetupPacket.Request = 0;SetupPacket.Value = 0;SetupPacket.Index = 0;SetupPacket.Length = 0;printf("NU_SetDeviceLED\n");WinUsb_ControlTransfer(InterfaceHandle, SetupPacket, 0, 0, NULL, 0);return TRUE; }BOOL GetUSBDeviceSpeed(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pDeviceSpeed) {if (!pDeviceSpeed || hDeviceHandle == INVALID_HANDLE_VALUE){return FALSE;}BOOL bResult = TRUE;ULONG length = sizeof(UCHAR);bResult = WinUsb_QueryDeviceInformation(hDeviceHandle, DEVICE_SPEED, &length, pDeviceSpeed);if (!bResult){printf("Error getting device speed: %d.\n", GetLastError());goto done;}if (*pDeviceSpeed == LowSpeed){printf("Device speed: %d (Low speed).\n", *pDeviceSpeed);goto done;}if (*pDeviceSpeed == FullSpeed){printf("Device speed: %d (Full speed).\n", *pDeviceSpeed);goto done;}if (*pDeviceSpeed == HighSpeed){printf("Device speed: %d (High speed).\n", *pDeviceSpeed);goto done;}done:return bResult; }struct PIPE_ID {UCHAR PipeInId;UCHAR PipeOutId; };BOOL QueryDeviceEndpoints(WINUSB_INTERFACE_HANDLE hDeviceHandle, PIPE_ID* pipeid) {if (hDeviceHandle == INVALID_HANDLE_VALUE){return FALSE;}BOOL bResult = TRUE;USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;ZeroMemory(&InterfaceDescriptor, sizeof(USB_INTERFACE_DESCRIPTOR));WINUSB_PIPE_INFORMATION Pipe;ZeroMemory(&Pipe, sizeof(WINUSB_PIPE_INFORMATION));bResult = WinUsb_QueryInterfaceSettings(hDeviceHandle, 0, &InterfaceDescriptor);if (bResult){for (int index = 0; index < InterfaceDescriptor.bNumEndpoints; index++){bResult = WinUsb_QueryPipe(hDeviceHandle, 0, index, &Pipe);if (bResult){if (Pipe.PipeType == UsbdPipeTypeControl){printf("Endpoint index: %d Pipe type: Control Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId);}if (Pipe.PipeType == UsbdPipeTypeIsochronous){printf("Endpoint index: %d Pipe type: Isochronous Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId);}if (Pipe.PipeType == UsbdPipeTypeBulk){if (USB_ENDPOINT_DIRECTION_IN(Pipe.PipeId)){printf("Endpoint index: %d Pipe type: Bulk Pipe ID: %c.\n", index, Pipe.PipeType, Pipe.PipeId);pipeid->PipeInId = Pipe.PipeId;}if (USB_ENDPOINT_DIRECTION_OUT(Pipe.PipeId)){printf("Endpoint index: %d Pipe type: Bulk Pipe ID: %c.\n", index, Pipe.PipeType, Pipe.PipeId);pipeid->PipeOutId = Pipe.PipeId;}}if (Pipe.PipeType == UsbdPipeTypeInterrupt){printf("Endpoint index: %d Pipe type: Interrupt Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId);}}else{continue;}}}done:return bResult; }BOOL SendDatatoDefaultEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle) {if (hDeviceHandle == INVALID_HANDLE_VALUE){return FALSE;}BOOL bResult = TRUE;UCHAR bars = 0;WINUSB_SETUP_PACKET SetupPacket;ZeroMemory(&SetupPacket, sizeof(WINUSB_SETUP_PACKET));ULONG cbSent = 0;//Set bits to light alternate barsfor (short i = 0; i < 7; i += 2){bars += 1 << i;}//Create the setup packetSetupPacket.RequestType = 0;SetupPacket.Request = 0xD8;SetupPacket.Value = 0;SetupPacket.Index = 0;SetupPacket.Length = sizeof(UCHAR);bResult = WinUsb_ControlTransfer(hDeviceHandle, SetupPacket, &bars, sizeof(UCHAR), &cbSent, 0);if (!bResult){goto done;}printf("Data sent: %d \nActual data transferred: %d.\n", sizeof(bars), cbSent);done:return bResult;}BOOL NU_WritePipe(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID,UCHAR *buf, ULONG len) {printf("NU_WritePipe\n");ULONG nBytesSent = 0;if (hDeviceHandle == INVALID_HANDLE_VALUE || !pID ){return FALSE;}nBytesSent = 0;WinUsb_WritePipe(hDeviceHandle, *pID, buf, len, &nBytesSent, 0);if (nBytesSent != len){return FALSE;}return TRUE; }BOOL Nu_WriteCmd(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID) {UCHAR data[] = { 0x01,0x01,0x53 ,0x01 ,0x00 ,0x00 ,0x08 ,0x06 ,0x90 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x50 };NU_WritePipe(hDeviceHandle, pID,data,15);UCHAR tag[] = { 0x00, 0x01 };NU_WritePipe(hDeviceHandle, pID, tag, 2);return TRUE; }ULONG NU_ReadPipe(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID, UCHAR *buf, ULONG len) {ULONG nBytesRead = 0;printf("NU_ReadPipe\n");WinUsb_ReadPipe(hDeviceHandle, *pID, (unsigned char*)buf, len, &nBytesRead, 0);return nBytesRead; }BOOL Nu_ReadCmd(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID) { UCHAR data[64];int len;int i;memset(data, 0, 64);len = NU_ReadPipe(hDeviceHandle, pID, data,64);printf("Nu_ReadCmd len= %d\n", len);for (i = 0; i < len; i++){printf("%x,", data[i]);}printf("\n");return TRUE; }BOOL NuWriteToBulkEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID, ULONG* pcbWritten) {if (hDeviceHandle == INVALID_HANDLE_VALUE || !pID || !pcbWritten){return FALSE;}BOOL bResult = TRUE;UCHAR szBuffer[] = "Hello World";ULONG cbSize = strlen((const char *)szBuffer);ULONG cbSent = 0;bResult = WinUsb_WritePipe(hDeviceHandle, *pID, szBuffer, cbSize, &cbSent, 0);if (!bResult){goto done;}printf("Wrote to pipe %d: %s \nActual data transferred: %d.\n", *pID, szBuffer, cbSent);*pcbWritten = cbSent;done:return bResult;}BOOL WriteToBulkEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID, ULONG* pcbWritten) {if (hDeviceHandle == INVALID_HANDLE_VALUE || !pID || !pcbWritten){return FALSE;}BOOL bResult = TRUE;UCHAR szBuffer[] = "Hello World";ULONG cbSize = strlen((const char *)szBuffer);ULONG cbSent = 0;bResult = WinUsb_WritePipe(hDeviceHandle, *pID, szBuffer, cbSize, &cbSent, 0);if (!bResult){goto done;}printf("Wrote to pipe %d: %s \nActual data transferred: %d.\n", *pID, szBuffer, cbSent);*pcbWritten = cbSent;done:return bResult;}BOOL ReadFromBulkEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID, ULONG cbSize) {if (hDeviceHandle == INVALID_HANDLE_VALUE){return FALSE;}BOOL bResult = TRUE;UCHAR* szBuffer = (UCHAR*)LocalAlloc(LPTR, sizeof(UCHAR)*cbSize);ULONG cbRead = 0;bResult = WinUsb_ReadPipe(hDeviceHandle, *pID, szBuffer, cbSize, &cbRead, 0);if (!bResult){goto done;}printf("Read from pipe %d: %s \nActual data read: %d.\n", *pID, szBuffer, cbRead);done:LocalFree(szBuffer);return bResult;}int _tmain(int argc, _TCHAR* argv[]) {DEVICE_DATA deviceData;HRESULT hr;USB_DEVICE_DESCRIPTOR deviceDesc;BOOL noDevice;ULONG lengthReceived;BOOL bResult = TRUE;PIPE_ID PipeID;HANDLE hDeviceHandle = INVALID_HANDLE_VALUE;WINUSB_INTERFACE_HANDLE hWinUSBHandle = INVALID_HANDLE_VALUE;UCHAR DeviceSpeed;ULONG cbSize = 0;UNREFERENCED_PARAMETER(argc);UNREFERENCED_PARAMETER(argv);//// Find a device connected to the system that has WinUSB installed using our// INF//hr = OpenDevice(&deviceData, &noDevice);if (FAILED(hr)) {if (noDevice) {printf("Device not connected or driver not installed\n");}else {printf("Failed looking for device, HRESULT 0x%x\n", hr);}return 0;}hWinUSBHandle = deviceData.WinusbHandle;hDeviceHandle = deviceData.DeviceHandle;bResult = GetUSBDeviceSpeed(hWinUSBHandle, &DeviceSpeed);if(!bResult){goto done;}bResult = QueryDeviceEndpoints(hWinUSBHandle, &PipeID);if(!bResult){goto done;}#if 0bResult = NU_SetDeviceLED(hWinUSBHandle);if(!bResult){goto done;} #endifprintf("PipeID.PipeInId = %d\n", PipeID.PipeInId);printf("PipeID.PipeOutId = %d\n", PipeID.PipeOutId);NU_SetDeviceSpiMasteMode(hWinUSBHandle);Nu_WriteCmd(hWinUSBHandle, &PipeID.PipeOutId);Nu_ReadCmd(hWinUSBHandle, &PipeID.PipeInId);system("PAUSE");done:CloseHandle(hDeviceHandle);WinUsb_Free(hWinUSBHandle);return 0; }

運行效果:

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的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。