如何在静态名称下绑定 USB 设备?

k0p*_*kus 59 linux arch-linux usb serial-port arduino

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

我不想列举我的设备可能在哪里的所有可能性,但我宁愿将它绑定在某个静态的地方,例如/dev/arduino.

我如何做到这一点?

Kot*_*tte 57

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

ACTION=="add", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="my_uart"
Run Code Online (Sandbox Code Playgroud)

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

udevadm info -a -p  $(udevadm info -q path -n /dev/ttyUSB0)
Run Code Online (Sandbox Code Playgroud)

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


Rol*_*Bly 42

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

  1. 找出 ttyUSB 上的内容:

    dmesg | grep ttyUSB  
    
    Run Code Online (Sandbox Code Playgroud)
  2. 列出设备的所有属性:

    udevadm info --name=/dev/ttyUSBx --attribute-walk
    
    Run Code Online (Sandbox Code Playgroud)

    (当然,使用您的设备号而不是 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" 
    
    Run Code Online (Sandbox Code Playgroud)

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

  4. 加载新规则:

    sudo udevadm trigger
    
    Run Code Online (Sandbox Code Playgroud)

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

  5. 验证发生了什么:

    ls -l /dev/your_device_name  
    
    Run Code Online (Sandbox Code Playgroud)

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

    ls -l /dev/ttyUSB1   
    
    Run Code Online (Sandbox Code Playgroud)
  6. 然后只是为了好玩:

    udevadm test -a -p  $(udevadm info -q path -n /dev/your_device_name)
    
    Run Code Online (Sandbox Code Playgroud)


小智 13

多个相同的 USB 设备问题

我有一个带四个摄像头的 Rasperry Pi。我拿PIX与fswebcam识别摄像机作为/dev/video0.. video3。有时相机video0vide02video4video6,但我们可以有关忘记了。

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

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

这个问题的解决方案涉及到 udev 规则,但也有很多鱼钩。

如果你发出命令

udevadm info –attribute-walk –path=/dev/video0
Run Code Online (Sandbox Code Playgroud)

你会得到一些输出,但最重要的部分是

KERNEL=”video0”, SUBSYSTEM=”video4linux” and KERNELS=”1:1.2.4:1.0”.
Run Code Online (Sandbox Code Playgroud)

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

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

KERNEL==”video0”,SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0”,SYMLINK+=”camera0” 
Run Code Online (Sandbox Code Playgroud)

看起来很简单 - 访问相机

fswebcam –d  $realpath /dev/camera0
Run Code Online (Sandbox Code Playgroud)

除非它不起作用——如果你把它放在 udev 规则中并且系统已经将 video0(在启动时)分配到不同的端口,则 udev 规则将被忽略。的符号链接/dev/camera0基本上说no such device。方一。

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

第一步是运行

fswebcam –d /dev/video${x}  tst.jpg
Run Code Online (Sandbox Code Playgroud)

x1到8之间。tst.jpg每次通话后的存在标识此视频号上是否有摄像头。由此制作活动视频号码列表。我的经验是,它要么是0,1,2,30,2,4,6用于相机我都用过。

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

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

udevadm info –attribute-walk –path=/dev/videox > dd
Run Code Online (Sandbox Code Playgroud)

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

udevadm … > dd再次运行这个东西并制作一个看起来像的列表

KERNEL==”video0”, SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0 ”,SYMLINK+=”camerax”. Call this the “video list”.
Run Code Online (Sandbox Code Playgroud)

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

KERNEL==”video0”, SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0 ”,SYMLINK+=”camera2”
Run Code Online (Sandbox Code Playgroud)

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

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

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