什么是winUSB
WinUSB是Windows操作系统提供的一种通用USB驱动程序,用于简化USB设备的开发和使用。它是一个用户模式驱动程序,可以在Windows XP及更高版本的操作系统上使用。WinUSB提供了一组API和工具,使开发人员能够与USB设备进行通信,包括数据传输和设备控制。
以下是WinUSB的一些主要特点和功能:
-
简化开发:WinUSB提供了一组易于使用的API,使开发人员能够更容易地与USB设备进行通信。它提供了基于异步I/O的数据传输接口,支持批量传输、中断传输和控制传输。开发人员可以使用标准的Win32编程技术(如C/C++)来编写应用程序,与USB设备进行交互。
-
无需驱动程序开发经验:使用WinUSB,开发人员无需具备深入的驱动程序开发知识。相比于传统的内核模式驱动程序开发,WinUSB的用户模式驱动程序更容易理解和使用。这使得USB设备的开发变得更加简单和快速。
-
驱动程序自动安装:当使用WinUSB驱动程序时,Windows操作系统可以自动安装所需的驱动程序,无需手动安装或配置驱动程序。这大大简化了使用USB设备的过程,减少了用户的繁琐操作。
-
兼容性:WinUSB驱动程序在Windows XP及更高版本的操作系统上都可以使用。这使得开发人员可以编写一次代码,并在不同版本的Windows系统上运行,提高了应用程序的兼容性。
需要注意的是,WinUSB适用于直接与USB设备进行通信的应用程序,而不适用于USB设备的传统功能,例如打印机、扫描仪等。对于这些设备,通常需要使用特定的设备类驱动程序或供应商提供的驱动程序。
举了例子
以下是一个使用WinUSB进行批量传输(Bulk Transfer)的示例代码:
#include <Windows.h>
#include <SetupAPI.h>
#include <winusb.h>
#include <iostream>
// USB设备的Vendor ID和Product ID
#define VENDOR_ID 0x1234
#define PRODUCT_ID 0x5678
// 批量传输管道的端点地址
#define BULK_IN_ENDPOINT 0x81
#define BULK_OUT_ENDPOINT 0x02
int main()
{
// 初始化WinUSB库
BOOL result = WinUsb_Initialize(NULL, NULL, NULL, NULL);
if (!result)
{
std::cout << "Failed to initialize WinUSB." << std::endl;
return 1;
}
// 枚举USB设备
HDEVINFO deviceInfoSet = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
if (deviceInfoSet == INVALID_HANDLE_VALUE)
{
std::cout << "Failed to enumerate USB devices." << std::endl;
WinUsb_Free(NULL);
return 1;
}
// 遍历设备列表,查找指定的USB设备
SP_DEVINFO_DATA deviceInfoData = { 0 };
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (DWORD index = 0; SetupDiEnumDeviceInfo(deviceInfoSet, index, &deviceInfoData); ++index)
{
// 获取设备的USB描述符
SP_DEVICE_INTERFACE_DATA interfaceData = { 0 };
interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
if (!SetupDiEnumDeviceInterfaces(deviceInfoSet, &deviceInfoData, &GUID_DEVINTERFACE_USB_DEVICE, 0, &interfaceData))
{
continue;
}
// 获取设备路径
DWORD requiredSize = 0;
SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &interfaceData, NULL, 0, &requiredSize, NULL);
PSP_DEVICE_INTERFACE_DETAIL_DATA interfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(requiredSize);
interfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (!SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &interfaceData, interfaceDetailData, requiredSize, NULL, NULL))
{
free(interfaceDetailData);
continue;
}
// 打开设备
HANDLE deviceHandle = CreateFile(interfaceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (deviceHandle == INVALID_HANDLE_VALUE)
{
free(interfaceDetailData);
continue;
}
// 获取WinUSB接口句柄
WINUSB_INTERFACE_HANDLE winusbHandle = NULL;
result = WinUsb_Initialize(deviceHandle, &winusbHandle);
if (result)
{
// 获取USB设备的描述符
USB_DEVICE_DESCRIPTOR deviceDescriptor;
result = WinUsb_GetDescriptor(winusbHandle, USB_DEVICE_DESCRIPTOR_TYPE, 0, 0, (PUCHAR)&deviceDescriptor, sizeof(deviceDescriptor), NULL);
if (result)
{
// 检查Vendor ID和Product ID是否匹配
if (deviceDescriptor.idVendor == VENDOR_ID && deviceDescriptor.idProduct == PRODUCT_ID)
{
// 发送数据
UCHAR outBuffer[64] = { 0 }; // 要发送的数据
DWORD bytesTransferred = 0;
result = WinUsb_WritePipe(winusbHandle, BULK_OUT_ENDPOINT, outBuffer, sizeof(outBuffer), &bytesTransferred, NULL);
if (result)
{
std::cout << "Data sent successfully." << std::endl;
}
else
{
std::cout << "Failed to send data." << std::endl;
}
// 接收数据
UCHAR inBuffer[64] = { 0 }; // 用于接收数据
result = WinUsb_ReadPipe(winusbHandle, BULK_IN_ENDPOINT, inBuffer, sizeof(inBuffer), &bytesTransferred, NULL);
if (result)
{
std::cout << "Data received successfully." << std::endl;
}
else
{
std::cout << "Failed to receive data." << std::endl;
}
}
}
// 关闭WinUSB接口
WinUsb_Free(winusbHandle);
}
// 关闭设备句柄
CloseHandle(deviceHandle);
free(interfaceDetailData);
}
// 释放资源
SetupDiDestroyDeviceInfoList(deviceInfoSet);
WinUsb_Free(NULL);
return ;
}
以上示例代码展示了如何使用WinUSB进行批量传输(Bulk Transfer)。在示例代码中,我们首先初始化WinUSB库,然后通过SetupAPI枚举连接到计算机的USB设备,并查找与指定的Vendor ID和Product ID匹配的设备。
如果设备匹配成功,我们可以使用WinUsb_WritePipe函数发送数据,以及使用WinUsb_ReadPipe函数接收数据。在示例代码中,我们使用了BULK_OUT_ENDPOINT和BULK_IN_ENDPOINT来指定批量传输的输入和输出端点地址。
你可以根据自己的需求修改示例代码,例如更改发送和接收的数据缓冲区大小、使用异步传输等。
请注意,上述示例代码仅展示了WinUSB进行批量传输的基本用法。实际使用时,你需要根据具体设备的通信协议和要求进行适当的修改和扩展。此外,WinUSB还提供了其他功能和API,例如控制传输、同步传输等,可以根据需要进行进一步的学习和使用。
在实际开发中,建议参考Microsoft官方文档和示例代码,以获取更详细和全面的WinUSB使用说明。