• 使用winUSB进行USB开发


    在这里插入图片描述

    什么是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 ;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119

    以上示例代码展示了如何使用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使用说明。
    在这里插入图片描述

  • 相关阅读:
    React + TypeScript 项目初始化配置
    4x4矩阵键盘设计Verilog矩阵式键盘控制,视频/代码
    C语言两个有序数组归并
    2022年中国饲料添加剂市场发展现状与下游需求分析
    PHP基于原生GD库, 获取图片中文字颜色, 匹配稀有度
    Python实例化方法、类方法、静态方法
    Moonbirds 是什么,为何公售后能迅速出圈 ?
    云原生nacos之服务发现SDK
    点云从入门到精通技术详解100篇-三维点云属性变换编码(中)
    js双向绑定
  • 原文地址:https://blog.csdn.net/qq_33471732/article/details/133843747