Udev 规则适用于看似无法区分的设备

Udev 规则适用于看似无法区分的设备

我正在尝试使用 udev 自动设置到 Intel RealSense D415 的符号链接。这是因为我在机器上使用多个摄像头,并且需要能够通过文件名可靠地引用它们(重新启动后不会更改)。

RealSense D415 在/dev.我为前两个设备设置符号链接没有问题,但据我所知,除了 和KERNEL属性之外,第一和第三个设备是相同的KERNELS,如果首先插入另一个相机,这些属性可能会发生变化。

如何使用 udev 规则来区分这些?

输出sudo udevadm info -ap /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.0/video4linux/video0

  looking at device '/devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.0/video4linux/video0':
    KERNEL=="video0"
    SUBSYSTEM=="video4linux"
    DRIVER==""
    ATTR{dev_debug}=="0"
    ATTR{index}=="0"
    ATTR{name}=="Intel(R) RealSense(TM) 415: Int"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.0':
    KERNELS=="2-1:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="uvcvideo"
    ATTRS{authorized}=="1"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{bInterfaceClass}=="0e"
    ATTRS{bInterfaceNumber}=="00"
    ATTRS{bInterfaceProtocol}=="00"
    ATTRS{bInterfaceSubClass}=="01"
    ATTRS{bNumEndpoints}=="01"
    ATTRS{iad_bFirstInterface}=="00"
    ATTRS{iad_bFunctionClass}=="0e"
    ATTRS{iad_bFunctionProtocol}=="00"
    ATTRS{iad_bFunctionSubClass}=="03"
    ATTRS{iad_bInterfaceCount}=="03"
    ATTRS{interface}=="Intel(R) RealSense(TM) 415 Depth"
    ATTRS{supports_autosuspend}=="1"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb2/2-1':
    KERNELS=="2-1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized}=="1"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bDeviceClass}=="ef"
    ATTRS{bDeviceProtocol}=="01"
    ATTRS{bDeviceSubClass}=="02"
    ATTRS{bMaxPacketSize0}=="9"
    ATTRS{bMaxPower}=="440mA"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bNumInterfaces}==" 5"
    ATTRS{bcdDevice}=="508f"
    ATTRS{bmAttributes}=="c0"
    ATTRS{busnum}=="2"
    ATTRS{configuration}==""
    ATTRS{devnum}=="2"
    ATTRS{devpath}=="1"
    ATTRS{idProduct}=="0ad3"
    ATTRS{idVendor}=="8086"
    ATTRS{ltm_capable}=="no"
    ATTRS{manufacturer}=="Intel(R) RealSense(TM) 415"
    ATTRS{maxchild}=="0"
    ATTRS{product}=="Intel(R) RealSense(TM) 415"
    ATTRS{quirks}=="0x0"
    ATTRS{removable}=="removable"
    ATTRS{serial}=="736613021813"
    ATTRS{speed}=="5000"
    ATTRS{urbnum}=="56"
    ATTRS{version}==" 3.10"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb2':
    KERNELS=="usb2"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized}=="1"
    ATTRS{authorized_default}=="1"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceProtocol}=="03"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bMaxPacketSize0}=="9"
    ATTRS{bMaxPower}=="0mA"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bcdDevice}=="0415"
    ATTRS{bmAttributes}=="e0"
    ATTRS{busnum}=="2"
    ATTRS{configuration}==""
    ATTRS{devnum}=="1"
    ATTRS{devpath}=="0"
    ATTRS{idProduct}=="0003"
    ATTRS{idVendor}=="1d6b"
    ATTRS{interface_authorized_default}=="1"
    ATTRS{ltm_capable}=="yes"
    ATTRS{manufacturer}=="Linux 4.15.0-36-generic xhci-hcd"
    ATTRS{maxchild}=="10"
    ATTRS{product}=="xHCI Host Controller"
    ATTRS{quirks}=="0x0"
    ATTRS{removable}=="unknown"
    ATTRS{serial}=="0000:00:14.0"
    ATTRS{speed}=="5000"
    ATTRS{urbnum}=="101"
    ATTRS{version}==" 3.00"

  looking at parent device '/devices/pci0000:00/0000:00:14.0':
    KERNELS=="0000:00:14.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="xhci_hcd"
    ATTRS{broken_parity_status}=="0"
    ATTRS{class}=="0x0c0330"
    ATTRS{consistent_dma_mask_bits}=="64"
    ATTRS{d3cold_allowed}=="1"
    ATTRS{dbc}=="disabled"
    ATTRS{device}=="0xa2af"
    ATTRS{dma_mask_bits}=="64"
    ATTRS{driver_override}=="(null)"
    ATTRS{enable}=="1"
    ATTRS{irq}=="123"
    ATTRS{local_cpulist}=="0-3"
    ATTRS{local_cpus}=="f"
    ATTRS{msi_bus}=="1"
    ATTRS{numa_node}=="-1"
    ATTRS{revision}=="0x00"
    ATTRS{subsystem_device}=="0x310c"
    ATTRS{subsystem_vendor}=="0x17aa"
    ATTRS{vendor}=="0x8086"

  looking at parent device '/devices/pci0000:00':
    KERNELS=="pci0000:00"
    SUBSYSTEMS==""
    DRIVERS==""

输出sudo udevadm info -ap /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.3/video4linux/video2

  looking at device '/devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.3/video4linux/video2':
    KERNEL=="video2"
    SUBSYSTEM=="video4linux"
    DRIVER==""
    ATTR{dev_debug}=="0"
    ATTR{index}=="0"
    ATTR{name}=="Intel(R) RealSense(TM) 415: Int"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.3':
    KERNELS=="2-1:1.3"
    SUBSYSTEMS=="usb"
    DRIVERS=="uvcvideo"
    ATTRS{authorized}=="1"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{bInterfaceClass}=="0e"
    ATTRS{bInterfaceNumber}=="03"
    ATTRS{bInterfaceProtocol}=="00"
    ATTRS{bInterfaceSubClass}=="01"
    ATTRS{bNumEndpoints}=="00"
    ATTRS{iad_bFirstInterface}=="03"
    ATTRS{iad_bFunctionClass}=="0e"
    ATTRS{iad_bFunctionProtocol}=="00"
    ATTRS{iad_bFunctionSubClass}=="03"
    ATTRS{iad_bInterfaceCount}=="02"
    ATTRS{interface}=="Intel(R) RealSense(TM) 415 RGB"
    ATTRS{supports_autosuspend}=="1"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb2/2-1':
    KERNELS=="2-1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized}=="1"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bDeviceClass}=="ef"
    ATTRS{bDeviceProtocol}=="01"
    ATTRS{bDeviceSubClass}=="02"
    ATTRS{bMaxPacketSize0}=="9"
    ATTRS{bMaxPower}=="440mA"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bNumInterfaces}==" 5"
    ATTRS{bcdDevice}=="508f"
    ATTRS{bmAttributes}=="c0"
    ATTRS{busnum}=="2"
    ATTRS{configuration}==""
    ATTRS{devnum}=="2"
    ATTRS{devpath}=="1"
    ATTRS{idProduct}=="0ad3"
    ATTRS{idVendor}=="8086"
    ATTRS{ltm_capable}=="no"
    ATTRS{manufacturer}=="Intel(R) RealSense(TM) 415"
    ATTRS{maxchild}=="0"
    ATTRS{product}=="Intel(R) RealSense(TM) 415"
    ATTRS{quirks}=="0x0"
    ATTRS{removable}=="removable"
    ATTRS{serial}=="736613021813"
    ATTRS{speed}=="5000"
    ATTRS{urbnum}=="56"
    ATTRS{version}==" 3.10"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb2':
    KERNELS=="usb2"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized}=="1"
    ATTRS{authorized_default}=="1"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceProtocol}=="03"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bMaxPacketSize0}=="9"
    ATTRS{bMaxPower}=="0mA"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bcdDevice}=="0415"
    ATTRS{bmAttributes}=="e0"
    ATTRS{busnum}=="2"
    ATTRS{configuration}==""
    ATTRS{devnum}=="1"
    ATTRS{devpath}=="0"
    ATTRS{idProduct}=="0003"
    ATTRS{idVendor}=="1d6b"
    ATTRS{interface_authorized_default}=="1"
    ATTRS{ltm_capable}=="yes"
    ATTRS{manufacturer}=="Linux 4.15.0-36-generic xhci-hcd"
    ATTRS{maxchild}=="10"
    ATTRS{product}=="xHCI Host Controller"
    ATTRS{quirks}=="0x0"
    ATTRS{removable}=="unknown"
    ATTRS{serial}=="0000:00:14.0"
    ATTRS{speed}=="5000"
    ATTRS{urbnum}=="101"
    ATTRS{version}==" 3.00"

  looking at parent device '/devices/pci0000:00/0000:00:14.0':
    KERNELS=="0000:00:14.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="xhci_hcd"
    ATTRS{broken_parity_status}=="0"
    ATTRS{class}=="0x0c0330"
    ATTRS{consistent_dma_mask_bits}=="64"
    ATTRS{d3cold_allowed}=="1"
    ATTRS{dbc}=="disabled"
    ATTRS{device}=="0xa2af"
    ATTRS{dma_mask_bits}=="64"
    ATTRS{driver_override}=="(null)"
    ATTRS{enable}=="1"
    ATTRS{irq}=="123"
    ATTRS{local_cpulist}=="0-3"
    ATTRS{local_cpus}=="f"
    ATTRS{msi_bus}=="1"
    ATTRS{numa_node}=="-1"
    ATTRS{revision}=="0x00"
    ATTRS{subsystem_device}=="0x310c"
    ATTRS{subsystem_vendor}=="0x17aa"
    ATTRS{vendor}=="0x8086"

  looking at parent device '/devices/pci0000:00':
    KERNELS=="pci0000:00"
    SUBSYSTEMS==""
    DRIVERS==""

答案1

这里似乎有一个区别因素:

ATTRS{interface}=="Intel(R) RealSense(TM) 415 Depth"

ATTRS{interface}=="Intel(R) RealSense(TM) 415 RGB"

为了区分多台相机,您可能需要这个:

ATTRS{serial}=="736613021813"

手册udev(7)页说:

如果在单个规则中指定了与父设备匹配的多个密钥,则所有这些密钥必须在同一台父设备上匹配。

使接口可区分的属性位于父块中,使相机可区分的属性位于祖父母块中。因此,您必须使用多个规则行。

对于每个相机,应该有一组如下规则:

SUBSYSTEM=="video4linux", ATTRS{serial}!="736613021813", GOTO="not_first_camera"
SUBSYSTEM=="video4linux", KERNEL=="video*", ATTRS{interface}=="Intel(R) RealSense(TM) 415 Depth", SYMLINK+="cam1_depth"
SUBSYSTEM=="video4linux", KERNEL=="video*", ATTRS{interface}=="Intel(R) RealSense(TM) 415 RGB", SYMLINK+="cam1_rgb"
LABEL="not_first_camera"

如果相机序列号不匹配,第一条规则将绕过以下两条规则。这样,在第一条规则和与其关联的标签之间,我们可以确定我们正在谈论的相机的身份,并可以集中精力区分接口。

每个块应该有一个唯一的LABEL=行和一个GOTO=与唯一标签匹配的语句。当然,您可以SYMLINK根据需要命名 s。

答案2

就我而言,我的 USB 集线器上有 4 个相同的摄像头。没有序列号。更糟糕的是,某些型号的相机在启动时显示为 video0..video3,而其他型号则显示为 video0..video6(每个相机两个)。我正在使用 fswebcam 拍照。如果摄像机占用两个视频编号,则只有一个可以工作。所以我收集的(相同)摄像机要么是视频 0-1-2-3,要么是视频 0-2-4-6

要识别工作视频编号,请运行循环 fswebcam -q - d /dev/videoX tpic.jpg - 其中 [X] 是 0-8 并记录哪些 X 值有效。

然后,对于每个有效的运行 udevadm info --attribute walk --name=/dev/videoX > a file

从文件中的大量输出(如上所列)中提取 (KERNEL==)[视频编号] 和 (KERNEL==)[USB 集线器端口地址] 字段。 KERNEL 和 KERNELS 之间的对应关系并不总是在重新启动后仍然存在 - 视频 0 的摄像机可能会变成视频 2 等等

因此,从提取的信息中制作一个列表,例如

内核==“video0”,子系统==“video4linux”,内核==“1-1.1.3:0”内核==“video1”,子系统==“video4linux”,内核==“1-1.1.1: 0"

ETC

最后对 KERNELS 字段上的列表进行排序,以便 KERNELS 编号(USB 集线器地址)始终位于列表中的同一位置

然后在排序列表中每行的末尾添加一个符号链接

内核==“video1”,子系统==“video4linux”,内核==“1-1.1.1:0”,SYMLINK+=“cam1”内核==“video0”,子系统==“video4linux”,内核==“ 1-1.1.3:0",SYMLINK+="cam2"

ETC

这会将摄像机编号(cam1-cam4 或任何您想要的名称)绑定到 USB 集线器端口并携带视频编号。

我写了一些 python 来完成这一切——大量的 os.system bash 调用。

一旦我有了一些有用的东西,我就失去了兴趣......如果有一种更简单的方法,那就很高兴知道。你也许可以用 bash 使用 grep 之类的东西来做到这一点

相关内容