Udev 규칙은 겉보기에 구별할 수 없는 장치에 적용됩니다.

Udev 규칙은 겉보기에 구별할 수 없는 장치에 적용됩니다.

Intel RealSense D415에 대한 심볼릭 링크를 자동으로 설정하기 위해 udev를 사용하려고 합니다. 이는 컴퓨터에서 여러 대의 카메라를 사용하고 있고 파일 이름(재부팅 시 변경되지 않음)으로 카메라를 안정적으로 참조할 수 있어야 하기 때문입니다.

RealSense D415 in /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원하는 대로 이름을 지정할 수 있습니다.

답변2

제 경우에는 USB 허브에 동일한 카메라 4개가 있습니다. 일련번호가 없습니다. 설상가상으로 일부 카메라 모델은 시작 시 video0..video3으로 표시되는 반면 다른 카메라 모델은 video0..video6(카메라당 2개)로 표시됩니다. 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 > 파일

위에 나열된 파일의 대량 출력에서 ​​(KERNEL==)[비디오 번호] 및 (KERNEL==)[USB 허브 포트 주소] 필드를 추출합니다. KERNEL과 KERNELS 사이의 통신은 재부팅 후에도 항상 유지되지는 않습니다. 비디오 0이 있는 카메라는 비디오 2가 될 수 있습니다.

따라서 추출된 정보로 목록을 만드십시오.

커널 == "video0", 하위 시스템 == "video4linux", 커널 == "1-1.1.3:0" 커널 == "video1", 하위 시스템 == "video4linux", 커널 == "1-1.1.1: 0"

마지막으로 KERNELS 필드의 목록은 KERNELS 번호(USB 허브 주소)가 목록에서 항상 동일한 위치에 있도록 정렬됩니다.

그런 다음 정렬된 목록의 각 줄 끝에 심볼릭 링크를 추가합니다.

커널 == "video1", 하위 시스템 == "video4linux", 커널 == "1-1.1.1:0", Symlink+="cam1" 커널 == "video0", 하위 시스템 == "video4linux", 커널 == = "1-1.1.3:0",SYMLINK+="cam2"

이렇게 하면 카메라 번호(cam1-cam4 또는 원하는 대로)가 USB 허브 포트에 바인딩되고 비디오 번호가 전달됩니다.

나는 모든 일을 하기 위해 파이썬을 작성했습니다 - 많은 os.system bash 호출.

일단 효과가 있는 것이 있으면 흥미를 잃습니다. 알아두면 좋을 더 쉬운 방법이 있다면. grep과 같은 것을 사용하여 bash로 이 작업을 수행할 수 있습니다.

관련 정보