【udev重命名详细教程】放弃硬编码,从重命名开始

前言

  • 上一期我们在讲双雷达的时候使用过串口udev重命名,这一期我们详细讲一下背后的原理和具体查询过程

  • 本文包括:
    *

    1 串口udev重命名教程
    2 udev原理

1 串口udev重命名教程

1-1 串口查询
  • 查询串口
bash 复制代码
ls /dev/tty*
  • 通过插拔可以短暂确认本轮的临时串口号
1-2 串口信息确认
  • 查询串口的信息
bash 复制代码
dmesg | grep ttyUSB1
1-3 设备详细信息
  • 查询具体信息
    • -n /dev/ttyUSB1:代表 name(名称)
    • -a:代表"向上遍历设备树"
bash 复制代码
udevadm info -a -n /dev/ttyUSB1 | grep -E "{idVendor}|{idProduct}|KERNELS=="
  • 通过上述输出我们可以看到整个层级结构:
  • 第一层:软件虚拟层,这是 Linux 内核驱动(ch341 驱动)最终创建的设备节点名称。
bash 复制代码
KERNELS=="ttyUSB1"
  • 第二层:USB 接口层,代表 USB 设备的"配置1,接口0
bash 复制代码
KERNELS=="1-1.2.4:1.0"
  • 第三层:真正的目标硬件,KERNELS=="1-1.2.4"这是物理 USB 拓扑路径
    • 1a86:7523:这是南京沁恒(WCH)CH341 芯片的绝对唯一身份证号。不管你插在电脑的哪个口,这两个值都不会变。
bash 复制代码
KERNELS=="1-1.2.4"
ATTRS{idProduct}=="7523"
ATTRS{idVendor}=="1a86"
  • 第四层:上游 USB 集线器 Hub,这里我的32是经过拓展坞接到板子上的
bash 复制代码
KERNELS=="1-1.2"
ATTRS{idProduct}=="2813"
ATTRS{idVendor}=="2109"
KERNELS=="1-1"
ATTRS{idProduct}=="0610"
ATTRS{idVendor}=="05e3"
  • 第五层:主板根控制器(操作系统提供),这是你电脑主板上实际的 USB 控制器(根集线器)
bash 复制代码
KERNELS=="usb1"
ATTRS{idProduct}=="0002"
ATTRS{idVendor}=="1d6b"
  • 第六层:最底层的硬件总线(硬核底层)
bash 复制代码
KERNELS=="xhci-hcd.2.auto"
KERNELS=="35100000.usb"
KERNELS=="35100000.usb3"
KERNELS=="35000000.hsio_apb"
KERNELS=="soc"
KERNELS=="platform"
1-4 编写 udev 规则
  • 通过上一节的信息确认,我们得知了不会变的设备物理id
bash 复制代码
KERNELS=="1-1.2.4"
ATTRS{idProduct}=="7523"
ATTRS{idVendor}=="1a86"
  • 这时候我们只需要修改udev规则文件即可
bash 复制代码
sudo nano /etc/udev/rules.d/99-stm32-ch341.rules
  • 把下述代码粘贴进去
bash 复制代码
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="stm32", MODE="0666"
1-5 重新加载udev规则
bash 复制代码
sudo udevadm control --reload-rules
sudo udevadm trigger
1-6 插拔验证
  • 我们重新查找
bash 复制代码
ls /dev/st*

2 udev原理

2-1 为什么需要 udev?
  • 在早期的 Linux 中,/dev 目录下的设备节点是静态的。这就导致了一个致命问题:"插拔风暴"
  • 假设你只有一个串口设备,它永远是 /dev/ttyUSB0,这没什么问题。
  • 但在我们的机器人开发中(比如双雷达 + STM32 底盘),如果你先插雷达,雷达可能抢占 ttyUSB0ttyUSB1;如果你先插 STM32,STM32 就变成了 ttyUSB0设备的命名完全取决于你插线的先后顺序。
  • 这会导致我们的 ROS launch 文件或代码配置极其脆弱,每次重启或换 USB 口都要改代码。udev 就是为了解决这个问题而诞生的------它负责在用户层动态管理设备,实现"按硬件身份固定名字"。

2-2 udev 的工作机制
  • udev 并不是一直在后台轮询(死循环检测)USB 口,它是事件驱动 的。核心流程如下:
    1. 内核发现硬件:当你插入 USB 设备时,Linux 内核的驱动程序(如 ch341)会检测到这一物理动作。
    2. 发送 uevent:内核会通过 Netlink 套接字,向用户空间广播一个"设备变更事件"。
    3. udev 守护进程接单 :后台运行的 udevd(udev 守护进程)监听到这个事件,拿到设备的信息。
    4. 规则匹配udevd 会按照字典顺序,遍历 /etc/udev/rules.d/ 目录下的所有 .rules 文件。
    5. 执行动作 :一旦匹配到某条规则(比如我们写的 99-stm32-ch341.rules),udev 就会执行规则里指定的动作(创建软链接、修改权限等)。

2-3 规则文件的底层逻辑
  • 我们在 1-4 节写的这行代码
bash 复制代码
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="stm32", MODE="0666"
  • 它可以分为两类关键字:匹配键(条件)赋值键(动作)
  • 匹配键(用 == 表示,必须全部满足才会触发)
    • SUBSYSTEM=="tty":告诉 udev "我只关心串口类设备"。如果你插了个 CH341 的鼠标(也是 1a86:7523,但属于 input subsystem),这条规则不会拦截它,防止误杀。
    • ATTRS{idVendor}=="1a86"ATTRS{idProduct}=="7523":精准狙击,对照前面讲的"设备树第三层",直接锁定这个具体的硬件。
  • 赋值键(用 +== 表示,触发后执行的操作)
    • SYMLINK+="stm32"+= 的意思是"追加一个别名"。udev 会在 /dev/ 下创建一个名为 stm32 的快捷方式,指向真实的 ttyUSBx。(注意:它不会抹除系统原本生成的 ttyUSB1,两者共存)。
    • MODE="0666"= 的意思是"强制赋值"。把该设备的权限改为 0666(即所有用户可读可写)。这样我们的普通用户(比如运行 ROS 节点的用户)就不需要每次都加 sudo 才能打开串口了。

2-4 关于"设备树层级"与规则的避坑指南
  • 结合我们在 1-3 节看到的六层结构,udev 在匹配 ATTRS{} 时,是允许跨层级向上查找的。
  • 为什么不能匹配第四层(Hub)? 如果你把规则写成 ATTRS{idVendor}=="2109"(扩展坞的 ID),那么只要这个扩展坞一通电,或者你往扩展坞上插个 U 盘,udev 都会试图执行动作,导致系统混乱。
  • 最佳实践 :写 udev 规则时,匹配条件要尽量贴近设备树的底层(即目标硬件本身那一层,通常包含 idVendoridProduct 的那一层),这样才能保证规则的唯一性和稳定性。

总结

  • 本文系统讲解了如何彻底解决Linux系统中多串口设备(如STM32)因插拔顺序导致命名随机变化的痛点;通过演示使用udevadm命令向上遍历设备树以精准提取芯片唯一硬件ID的全流程,并深入剖析udev基于事件驱动的底层匹配与赋值机制,最终实现了为设备创建固定的软链接与权限配置,确保了开发环境的绝对稳定。
  • 如有错误,欢迎指出!
  • 感谢你的观看
相关推荐
studytosky2 小时前
【高并发内存池】线程缓存核心原理与实现
linux·服务器·git·缓存
lihao lihao2 小时前
Linux文件与fd
java·linux·算法
treacle田2 小时前
达梦数据库-DMDIS安装与基本使用-记录总结
linux·运维·服务器·达梦dmdis
lovep12 小时前
VLA系列RT-1: Robotics Transformer for Real-World Control 论文阅读和理解
机器人·具身智能·vla·rt-1
我星期八休息2 小时前
Linux 进程核心原理全解:从冯诺依曼体系到进程控制全链路深度剖析
大数据·linux·服务器·开发语言·数据结构·c++·散列表
Strange_Head2 小时前
补充知识点`makefile`、`config`、`GLP协议` 3/3 ——《驱动篇》《Linux历史发展》
linux·运维·服务器
Cando学算法2 小时前
回声服务器项目
linux·开发语言·c++·计算机网络·ubuntu
cui_ruicheng2 小时前
Linux库制作与使用(三):ELF加载与动态链接机制
linux·运维·服务器
seabirdssss2 小时前
闲置笔记本改造成 Ubuntu 开发测试服务器
linux·服务器·ubuntu