You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux下USB设备通信:如何获取正确的设备路径?

正确获取USB HID设备通信路径的方法

你打开的/dev/bus/usb/001/078是USB设备的原始控制节点,仅能用于执行USB总线级别的操作(比如读取设备描述符、配置描述符),无法直接进行HID报告的收发。对于需要通过USB报告通信的设备(通常为HID类设备),你需要找到对应的HID设备节点,比如/dev/hidrawX或/dev/input/eventX,具体取决于设备的功能类型。

步骤1:确认设备的USB类别

通过lsusb命令查看设备的Class字段,若显示为Human Interface Device(HID类,代码03),则目标节点属于hidraw或input子系统。

步骤2:用udev获取正确的通信节点路径

调整udev枚举逻辑,匹配hidraw或input子系统而非usb子系统:

  • 针对hidraw节点(最适合HID报告收发,无需处理输入事件协议):

    1. 设置匹配子系统为hidraw:udev_enumerate_add_match_subsystem(enumerate, "hidraw")
    2. 添加vendor和product ID的匹配:
      udev_enumerate_add_match_property(enumerate, "ID_VENDOR_ID", "你的vendor ID(小写十六进制)");
      udev_enumerate_add_match_property(enumerate, "ID_MODEL_ID", "你的product ID(小写十六进制)");
      
    3. 枚举设备后,从udev设备对象中读取DEVNAME属性,即为通信路径(例如/dev/hidraw0)
  • 针对input节点(若设备作为输入设备,如键盘、鼠标类):

    1. 设置匹配子系统为input:udev_enumerate_add_match_subsystem(enumerate, "input")
    2. 同样匹配ID_VENDOR_ID和ID_MODEL_ID,然后读取DEVNAME属性(例如/dev/input/event10)

步骤3:验证与通信

  • 打开hidraw节点时,使用O_RDWR标志即可,直接用read()和write()收发HID报告。注意:若设备使用带报告ID的格式,发送数据的第一个字节需为报告ID,接收数据的第一个字节也会是报告ID。
  • 权限处理:默认情况下普通用户可能无访问hidraw/input节点的权限,可通过两种方式解决:
    • 将当前用户加入plugdev或input组:sudo usermod -aG plugdev $USER
    • 创建udev规则文件(如/etc/udev/rules.d/99-your-device.rules),设置节点权限:
      SUBSYSTEM=="hidraw", ATTRS{idVendor}=="xxxx", ATTRS{idProduct}=="yyyy", MODE="0666"
      

代码示例(简化版)

struct udev *udev = udev_new();
struct udev_enumerate *enumerate = udev_enumerate_new(udev);
udev_enumerate_add_match_subsystem(enumerate, "hidraw");
udev_enumerate_add_match_property(enumerate, "ID_VENDOR_ID", "1234");
udev_enumerate_add_match_property(enumerate, "ID_MODEL_ID", "5678");
udev_enumerate_scan_devices(enumerate);

struct udev_list_entry *devices = udev_enumerate_get_list_entry(enumerate);
struct udev_list_entry *entry;
udev_list_entry_foreach(entry, devices) {
    const char *path = udev_list_entry_get_name(entry);
    struct udev_device *dev = udev_device_new_from_syspath(udev, path);
    const char *devnode = udev_device_get_devnode(dev);
    if (devnode) {
        printf("通信路径:%s\n", devnode);
        // 此处可打开devnode进行通信
    }
    udev_device_unref(dev);
}

udev_enumerate_unref(enumerate);
udev_unref(udev);

内容的提问来源于stack exchange,提问作者valdo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 00:25:18