多个相同 USB 设备问题

多个相同 USB 设备问题

我有一个 Arduino,有时会绑定到/dev/ttyUSB0,有时会绑定到/dev/ttyUSB1,使我的脚本失败。

我不想枚举我的设备可能位于的所有可能性,但我宁愿将其绑定在静态的地方,例如/dev/arduino

我该如何实现这一目标?

答案1

根据建议,您可以添加一些 udev 规则。我编辑了/etc/udev/rules.d/10-local.rules包含:

ACTION=="add", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="my_uart"

您可以通过运行来检查设备的变量

udevadm info -a -p  $(udevadm info -q path -n /dev/ttyUSB0)

您可以阅读更深入的指南http://www.reactivated.net/writing_udev_rules.html

答案2

上面的规则语法可能适用于某些发行版,但不适用于我的(Raspbian)。由于我从未找到一个文档来解释所有的来龙去脉,所以我编写了自己的文档,以便找到这里。这就是它的归结。

  1. 找出 ttyUSB 上有什么:

    dmesg | grep ttyUSB  
    
  2. 列出设备的所有属性:

    udevadm info --name=/dev/ttyUSBx --attribute-walk
    

    (当然,用您的设备编号而不是 x)。挑选一个唯一的标识符集,例如idVendor + idProduct。如果您有多个具有相同 idVendor 和 idProduct 的设备,您可能还需要 SerialNumber。每个设备的序列号应该是唯一的。

  3. 创建一个文件/etc/udev/rules.d/99-usb-serial.rules,其中包含类似以下行的内容:

    SUBSYSTEM=="tty", ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678", SYMLINK+="your_device_name" 
    

    假设您不需要那里的序列号,当然还有您在步骤 2 中找到的 idVendor 和 idProduct 的号码。

  4. 加载新规则:

    sudo udevadm trigger
    

    2021 年 7 月 6 日编辑:虽然这在当时(2015 年)、Archlinux 以及其他发行版上运行良好,但您可能需要第一的如果自动加载失败,请执行sudo udevadm control --reload

  5. 验证发生了什么:

    ls -l /dev/your_device_name  
    

    将显示符号链接所指向的 ttyUSB 编号。如果是/dev/ttyUSB1,则验证谁拥有它以及它属于哪个组:

    ls -l /dev/ttyUSB1   
    
  6. 然后只是为了好玩:

    udevadm test -a -p  $(udevadm info -q path -n /dev/your_device_name)
    

答案3

多个相同 USB 设备问题

我有一个带有四个摄像头的树莓派。我拍了照片,将fswebcam相机识别为/dev/video0......video3有时相机是video0vide02video4video6我们现在可以忘记这一点。

我需要一个持久的 ID 来识别摄像机编号,以便video0始终是同一台摄像机,因为我为图片添加了标题。不幸的是,这并不可靠地发生 - 在启动时,相机被枚举为video0..video3但并不总是以相同的方式。

这些相机都具有相同的 ID 和序列号。

这个问题的解决方案涉及 udev 规则,但其中也存在很多问题。

如果您发出命令

udevadm info –attribute-walk –path=/dev/video0

你会得到一堆输出,但最重要的是

KERNEL=”video0”, SUBSYSTEM=”video4linux” and KERNELS=”1:1.2.4:1.0”.

KERNELS 位是 USB 集线器端口。对于四个摄像头,其中有四个 - 它们在重新启动时不会更改,但video{x}与端口相关联。可能改变。

因此,我们需要一个 udev 规则将视频编号绑定到 USB 集线器端口 - 类似于:

KERNEL==”video0”,SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0”,SYMLINK+=”camera0” 

看起来很简单 – 使用以下命令访问相机

fswebcam –d  $realpath /dev/camera0

但它不起作用 - 如果您将其放入 udev 规则中并且系统已将 video0(启动时)分配给不同的端口,则 udev 规则将被忽略。符号链接/dev/camera0基本上是这样说的no such device。方一。

我们想要的是将符号链接绑定到 USB 集线器地址,而不是数字video{x}。它需要一个Python程序。

第一步是运行

fswebcam –d /dev/video${x}  tst.jpg

1 到 8之间。每次通话后的x的存在tst.jpg标识该视频号码上是否有摄像头。由此创建一个活动视频编号的列表。我的经验是,它要么0,1,2,3适用0,2,4,6于我使用过的相机。

其他人当然可以使用不同的过程来构建此列表。

然后对于列表中的每个视频编号运行

udevadm info –attribute-walk –path=/dev/videox > dd

KERNELS= line并从中提取dd.在此过程中,您最终会得到相机的 USB 端口地址列表。对此列表进行排序,以便在下一步中始终以相同的顺序处理它。将此称为“地址列表”。

再次运行该udevadm … > dd程序并制作一个看起来像这样的列表

KERNEL==”video0”, SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0 ”,SYMLINK+=”camerax”. Call this the “video list”.

现在逐步浏览地址列表 - 对于每个条目,从视频列表中查找相应的条目。创建一个看起来像行集合的新列表,例如

KERNEL==”video0”, SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0 ”,SYMLINK+=”camera2”

x(符号链接号)被地址列表中的序列号替换。

现在您有了一个有效的 udev 规则。与 USB 集线器地址绑定的符号链接,无论启动时分配给该端口的视频编号是什么。

将最终列表写入文件/etc/udev/rules.d/cam.rules。运行udevadm trigger激活它,工作就完成了。 /dev/camera2无论视频编号如何,都将是同一台摄像机(USB 端口)。

答案4

我还能够在 中找到一个独特的设备/dev/serial/by-id。我还没有尝试重新启动,但该目录中的文件只是指向相应设备文件 ( ttyACM[0-9]) 的链接。

我在 Raspberry Pi 上运行 arch linux,但我只是通过执行find包含“Arduino”的文件名来偶然发现它们。我的 python 程序运行良好,使用这些文件作为从我的 Arduino 读取/写入数据的设备(到目前为止,单个 Pi 上有两个)。

相关内容