当前位置: 首页 > news >正文

基于udev规则固定相机名称

我们使用 usb 相机时候,经常出现相机的名称改变,有时候是:/dev/video0 有时候是:/dev/video2,这时候我们可以修改 udev 规则,使用相同的名称来调用相机。

查询摄像头信息

  • 连接你的摄像头,并使用 lsusb 命令来找到摄像头的详细信息(如厂商 ID 和产品 ID)。
    例如我插了两个相机,lsusb 输出如下:
Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 004: ID 1bcf:2cd1 Sunplus Innovation Technology Inc. DECXIN CAMERA
Bus 002 Device 003: ID 0bda:c820 Realtek Semiconductor Corp. 802.11ac NIC
Bus 002 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 002: ID 1bcf:2cd1 Sunplus Innovation Technology Inc. DECXIN CAMERA
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

lsusb命令的输出提供了一个系统上所有 USB 设备的列表。每行代表一个设备,并包含了有关该设备的一些基本信息。

输出解析

  1. Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

    • Bus 006: 表示这是连接在总线编号为 6 上的设备。
    • Device 001: 设备编号,每个总线上的第一个设备通常是根集线器,编号从 1 开始。
    • ID 1d6b:0003: 前面的部分(1d6b)是供应商 ID(Vendor ID),表示 Linux Foundation;后面的部分(0003)是产品 ID(Product ID),具体指 3.0 版本的 USB root hub。
    • Linux Foundation 3.0 root hub: 描述了设备的身份和类型。
  2. Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

    • 类似上面的解释,但这里的设备是一个 2.0 版本的 USB root hub。
  3. Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

    • 这里描述的是一个 1.1 版本的 USB root hub。
  4. Bus 002 Device 004: ID 1bcf:2cd1 Sunplus Innovation Technology Inc. DECXIN CAMERA

    • Bus 002 Device 004: 表明这是连接在总线 2 上的第 4 个设备。
    • ID 1bcf:2cd1: 1bcf是 Sunplus Innovation Technology Inc.的供应商 ID,2cd1是 DECXIN CAMERA 的产品 ID。
    • Sunplus Innovation Technology Inc. DECXIN CAMERA: 指出这是一个由 Sunplus Innovation Technology 生产的 DECXIN 摄像头。
  5. Bus 002 Device 003: ID 0bda:c820 Realtek Semiconductor Corp. 802.11ac NIC

    • 这是一个 Realtek Semiconductor Corp.生产的 802.11ac 无线网络接口控制器(NIC),其供应商 ID 为0bda,产品 ID 为c820
  6. Bus 002 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub

    • 这是由 Terminus Technology Inc.制造的一个 USB 集线器,供应商 ID 为1a40,产品 ID 为0101
  7. Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

    • 和之前提到的类似,这是一台 2.0 版本的 USB root hub。
  8. Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

    • 又是一个 1.1 版本的 USB root hub。
  9. Bus 001 Device 002: ID 1bcf:2cd1 Sunplus Innovation Technology Inc. DECXIN CAMERA

    • 这是另一个 DECXIN 摄像头,与总线 2 上的设备相同,但位于不同的总线(总线 1)上。

可以看到 6 和 9 都是我插入的 USB 摄像头。

只有单一的摄像头

  • 创建一个新的 Udev 规则文件,例如/etc/udev/rules.d/99-camera.rules,并在其中添加一行描述你的摄像头的信息。格式可能如下:
    SUBSYSTEM=="usb", ATTRS{idVendor}=="xxxx", ATTRS{idProduct}=="yyyy", SYMLINK+="mycamera"
    
    xxxxyyyy替换为你从lsusb命令得到的厂商 ID 和产品 ID。
  • 保存文件并重新加载 Udev 规则:sudo udevadm control --reload-rules
  • 最后,重新插拔你的摄像头,应该可以在/dev目录下看到名为mycamera的链接。
  • 使用ls -l /dev/mycamera确认符号链接是否指向了正确的设备节点。

按照我查询的第 6 个数据,这个 udev 规则应该是这样的:

SUBSYSTEM=="usb", ATTRS{idVendor}=="1bcf", ATTRS{idProduct}=="2cd1", SYMLINK+="/dev/mycamera"

之后就可以使用/dev/mycamera来控制这个 USB 摄像头了。


多个相同的 USB 摄像头

可以看到我使用 lsusb 命令,我找到了两个相同的 USB 摄像头,厂商 ID 和产品 ID 都一样,如果仍然使用同一个规则,那么可能会导致多个相同的 USB 摄像头被分配相同的设备名称。

当两个摄像头拥有相同的厂商 ID(idVendor)和产品 ID(idProduct)时,仅靠这两个属性无法唯一标识每个设备。

SUBSYSTEM=="usb", ATTRS{idVendor}=="1bcf", ATTRS{idProduct}=="2cd1", SYMLINK+="mycamera"

这个规则的意思是:

  • 当系统识别到一个 USB 子系统中的设备
  • 并且它的 厂商 ID 是 1bcf
  • 并且它的 产品 ID 是 2cd1
  • 就为它创建一个符号链接 /dev/mycamera

但是,如果你有两个这样的设备(如你的情况),那么:

  • 系统会为第一个设备创建 /dev/mycamera
  • 然后也会为第二个设备创建 /dev/mycamera
  • 最终,只有最后一个插入的设备才会“占用”这个名字,或者出现冲突。

所以,这种规则在这种情况下 不能稳定地区分两个相同型号的摄像头


正确做法:添加更多区分条件

为了给两个相同型号的摄像头分配固定的、唯一的名称(比如 /dev/camera_left/dev/camera_right),需要在 Udev 规则中加入 更具体的属性来区分它们

常用的区分方式有:

属性是否常用说明
ATTRS{serial}✅ 推荐如果摄像头提供了序列号,这是最稳定的区分方法
KERNELSATTRS{devpath}✅ 推荐表示设备连接的物理 USB 端口路径
ATTRS{busnum} + ATTRS{devnum}⚠️ 可用但不稳定设备所在的总线号和设备号
ENV{ID_PATH}ENV{ID_SERIAL}✅ 推荐udev 自动解析出的设备路径或序列号

🔍 如何找到这些属性?

使用以下命令查看某个摄像头的详细信息:

udevadm info -a -n /dev/bus/usb/BBB/DDD

BBB 替换为总线号(Bus),DDD 替换为设备号(Device),例如:

udevadm info -a -n /dev/bus/usb/002/004
udevadm info -a -n /dev/bus/usb/001/002

你会看到类似下面的输出片段:

looking at device '/devices/platform/xhci-hcd.1.auto/usb2/2-1':KERNEL=="2-1"SUBSYSTEM=="usb"ATTR{configuration}==""ATTR{bNumInterfaces}==" 1"ATTR{bConfigurationValue}=="1"ATTR{bmAttributes}=="80"ATTR{bMaxPower}=="500mA"ATTR{idVendor}=="1bcf"ATTR{idProduct}=="2cd1"ATTR{bcdDevice}=="0100"ATTR{manufacturer}=="SunplusIT Inc"ATTR{product}=="DECXIN CAMERA"ATTR{serial}=="A1234567"   # <-- 这个很重要!如果有的话

✅ 示例:基于物理位置(KERNELS)的 Udev 规则

假设:

  • 左边摄像头连接在 KERNELS=="1-1"
  • 右边摄像头连接在 KERNELS=="2-1"

你可以创建如下规则文件(例如 /etc/udev/rules.d/99-camera.rules):

# 左边摄像头
SUBSYSTEM=="usb", ATTRS{idVendor}=="1bcf", ATTRS{idProduct}=="2cd1", KERNELS=="1-1", SYMLINK+="camera_left"# 右边摄像头
SUBSYSTEM=="usb", ATTRS{idVendor}=="1bcf", ATTRS{idProduct}=="2cd1", KERNELS=="2-1", SYMLINK+="camera_right"

✅ 示例:基于序列号(如果支持)

如果你发现摄像头有唯一的序列号,比如:

ATTR{serial}=="A1234567"

你可以这样写规则:

SUBSYSTEM=="usb", ATTRS{idVendor}=="1bcf", ATTRS{idProduct}=="2cd1", ATTRS{serial}=="A1234567", SYMLINK+="camera_left"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1bcf", ATTRS{idProduct}=="2cd1", ATTRS{serial}=="B7654321", SYMLINK+="camera_right"

最终我使用的 udev 规则是:


SUBSYSTEMS=="usb", KERNELS=="1-1", ATTR{index}=="0", ATTRS{idVendor}=="1bcf", ATTRS{idProduct}=="2cd1", SYMLINK+="leftCam"
SUBSYSTEMS=="usb", KERNELS=="2-1.2", ATTR{index}=="0", ATTRS{idVendor}=="1bcf", ATTRS{idProduct}=="2cd1", SYMLINK+="rightCam"
http://www.lryc.cn/news/581670.html

相关文章:

  • [netty5: WebSocketServerHandshaker WebSocketServerHandshakerFactory]-源码分析
  • 桥梁桥拱巡检机器人cad+【4张】设计说明书+绛重+三维图
  • 力扣 hot100 Day36
  • webUI平替应用,安装简单,功能齐全
  • LeetCode 75. 颜色分类(荷兰国旗问题)
  • 服务端向客户端主动推送数据的几种方法(Spring Boot 环境)
  • 11.进程间通信
  • VSCode+arm-none-eabi-gcc交叉编译+CMake构建+OpenOCD(基于Raspberry Pico RP2040)
  • 2.线性神经网络--Softmax回归
  • 算法分析与设计实验1:实现两路合并排序和折半插入排序
  • 3.8 java连接数据库
  • Vue2 day07
  • 工业相机和镜头
  • 基于Java+SpringBoot的医院信息管理系统
  • ARM 学习笔记(一)
  • 文心开源大模型ERNIE-4.5-0.3B-Paddle私有化部署保姆级教程及技术架构探索
  • 【学习笔记】4.1 什么是 LLM
  • 编程语言艺术:C语言中的属性attribute笔记总结
  • 程序员在线接单
  • 浅谈漏洞扫描与工具
  • 大型语言模型中的自动化思维链提示
  • 【数据分析】R语言多源数据的基线特征汇总
  • 玄机——第三章 权限维持-linux权限维持-隐藏练习
  • Dify+Ollama+QwQ:3步本地部署,开启AI搜索新篇章
  • 实现Spring MVC登录验证与拦截器保护:从原理到实战
  • 【机器学习深度学习】 如何解决“宏平均偏低 / 小类识别差”的问题?
  • HRDNet: High-resolution Detection Network for Small Objects论文阅读
  • mac中创建 .command 文件,执行node服务
  • Omi录屏专家 Screen Recorder by Omi 屏幕录制Mac
  • 【Linux】基础开发工具(1)