使用winUSB进行USB开发

使用winUSB进行USB开发_第1张图片

什么是winUSB

WinUSB是Windows操作系统提供的一种通用USB驱动程序,用于简化USB设备的开发和使用。它是一个用户模式驱动程序,可以在Windows XP及更高版本的操作系统上使用。WinUSB提供了一组API和工具,使开发人员能够与USB设备进行通信,包括数据传输和设备控制。

以下是WinUSB的一些主要特点和功能:

  1. 简化开发:WinUSB提供了一组易于使用的API,使开发人员能够更容易地与USB设备进行通信。它提供了基于异步I/O的数据传输接口,支持批量传输、中断传输和控制传输。开发人员可以使用标准的Win32编程技术(如C/C++)来编写应用程序,与USB设备进行交互。

  2. 无需驱动程序开发经验:使用WinUSB,开发人员无需具备深入的驱动程序开发知识。相比于传统的内核模式驱动程序开发,WinUSB的用户模式驱动程序更容易理解和使用。这使得USB设备的开发变得更加简单和快速。

  3. 驱动程序自动安装:当使用WinUSB驱动程序时,Windows操作系统可以自动安装所需的驱动程序,无需手动安装或配置驱动程序。这大大简化了使用USB设备的过程,减少了用户的繁琐操作。

  4. 兼容性:WinUSB驱动程序在Windows XP及更高版本的操作系统上都可以使用。这使得开发人员可以编写一次代码,并在不同版本的Windows系统上运行,提高了应用程序的兼容性。

需要注意的是,WinUSB适用于直接与USB设备进行通信的应用程序,而不适用于USB设备的传统功能,例如打印机、扫描仪等。对于这些设备,通常需要使用特定的设备类驱动程序或供应商提供的驱动程序。

举了例子

以下是一个使用WinUSB进行批量传输(Bulk Transfer)的示例代码:

#include 
#include 
#include 
#include 

// 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使用说明。
使用winUSB进行USB开发_第2张图片

你可能感兴趣的:(主流单片机开发(MCU),嵌入式硬件,网络,信息与通信,stm32,单片机)