黎小葱 2025-06-26 20:55 采纳率: 97.6%
浏览 5
已采纳

如何正确使用libusb进行设备通信?

在使用 libusb 进行设备通信时,开发者常遇到“如何正确打开并识别目标 USB 设备?”这一关键问题。具体表现为:程序无法准确匹配指定的 Vendor ID 和 Product ID,或在多设备连接时无法区分目标设备。常见原因包括未正确遍历设备列表、未调用 `libusb_get_device_descriptor` 获取描述符,或未对设备进行引用计数管理(如漏掉 `libusb_ref_device`)。此外,权限配置不当也可能导致设备打开失败。掌握这些核心步骤是实现稳定通信的前提。
  • 写回答

1条回答 默认 最新

  • kylin小鸡内裤 2025-06-26 20:55
    关注

    如何正确使用 libusb 打开并识别目标 USB 设备

    在使用 libusb 进行 USB 设备通信开发时,开发者常常遇到“无法正确打开并识别目标设备”的问题。这种现象通常表现为程序无法准确匹配指定的 Vendor ID 和 Product ID,或在多设备连接时无法区分目标设备。

    1. 基本流程概述

    要成功打开一个 USB 设备,必须按照以下顺序执行:

    1. 初始化 libusb 上下文
    2. 获取所有连接的 USB 设备列表
    3. 遍历设备列表并获取每个设备的描述符
    4. 根据 Vendor ID 和 Product ID 匹配目标设备
    5. 调用 libusb_open() 打开设备
    6. 释放资源并退出

    2. 常见错误及原因分析

    错误类型可能原因
    无法找到设备未正确遍历设备列表,或未调用 libusb_get_device_descriptor
    多个设备混淆未对设备进行引用计数管理(如漏掉 libusb_ref_device
    权限不足导致打开失败系统权限配置不当,例如 udev 规则未设置

    3. 核心代码示例

    #include <libusb-1.0/libusb.h>
    #include <stdio.h>
    
    int main() {
        libusb_context *ctx = NULL;
        libusb_device **devs;
        ssize_t cnt = libusb_get_device_list(ctx, &devs);
        if (cnt < 0) {
            printf("Error getting device list\n");
            return -1;
        }
    
        for (ssize_t i = 0; i < cnt; i++) {
            libusb_device *dev = devs[i];
            struct libusb_device_descriptor desc;
            int r = libusb_get_device_descriptor(dev, &desc);
            if (r < 0) {
                continue;
            }
    
            // 替换为你的 VID 和 PID
            if (desc.idVendor == 0x1234 && desc.idProduct == 0x5678) {
                libusb_device_handle *handle;
                r = libusb_open(dev, &handle);
                if (r == 0) {
                    printf("Device opened successfully.\n");
                    libusb_close(handle);
                } else {
                    printf("Failed to open device: %d\n", r);
                }
            }
        }
    
        libusb_free_device_list(devs, 1);
        libusb_exit(ctx);
        return 0;
    }

    4. 引用计数与内存管理

    当需要在不同函数中传递设备指针时,应使用 libusb_ref_device() 来增加引用计数,避免设备被提前释放。例如:

    • 在设备匹配后调用 libusb_ref_device(dev)
    • 在不再需要该设备时调用 libusb_unref_device(dev)

    5. 权限配置问题排查

    如果程序运行时报错“Access denied”,请检查以下几点:

    • 是否以 root 权限运行?
    • 是否有对应的 udev 规则允许当前用户访问设备?
    • 是否加载了内核模块(如 hid、cdc_acm 等)导致设备被占用?

    6. 流程图总结

    graph TD A[初始化 libusb] --> B[获取设备列表] B --> C{遍历设备} C --> D[获取设备描述符] D --> E{匹配 VID/PID?} E -- 是 --> F[打开设备] E -- 否 --> G[继续下一个设备] F --> H[通信/操作设备] H --> I[关闭设备] I --> J[释放资源]
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 10月23日
  • 创建了问题 6月26日