【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 底盘),如果你先插雷达,雷达可能抢占 ttyUSB0 和 ttyUSB1;如果你先插 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 规则时,匹配条件要尽量贴近设备树的底层(即目标硬件本身那一层,通常包含 idVendor 和 idProduct 的那一层),这样才能保证规则的唯一性和稳定性。

总结

  • 本文系统讲解了如何彻底解决Linux系统中多串口设备(如STM32)因插拔顺序导致命名随机变化的痛点;通过演示使用udevadm命令向上遍历设备树以精准提取芯片唯一硬件ID的全流程,并深入剖析udev基于事件驱动的底层匹配与赋值机制,最终实现了为设备创建固定的软链接与权限配置,确保了开发环境的绝对稳定。
  • 如有错误,欢迎指出!
  • 感谢你的观看
相关推荐
天树星智源3 分钟前
静态物理满分、交互 11.54%:3D 场景生成系统的幻觉
论文阅读·人工智能·3d·机器人
咬代码的兽6 分钟前
智元创新日拆解:机器人开始按工时结算,Token之后有了Worken
机器人
趣味科技v12 分钟前
具身智能从“演示”走向“部署”:智元把机器人送进真实工位
机器人·具身智能·智元
Wanda121425 分钟前
机器人与机电一体化3D数字孪生机器-Day9
人工智能·3d·unity·机器人·数字孪生
一技安身32 分钟前
MySQL 8.4.13 LTS 通用二进制包(Linux免安装版)完整教程
linux·mysql·adb
迷途之人不知返36 分钟前
【动态库与静态库】-3-静态链接与加载
linux
超级架构师1 小时前
让 Fortran 模型自己调用 Agent:原生 Fortran 2008 实现深度剖析
人工智能·python·架构·机器人·开源·fortran
谙弆悕博士1 小时前
debian快速换源
linux·运维·windows·debian·下载·换源·网络问题
.道阻且长.1 小时前
Linux基本开发工具:编译器gcc/g++
linux·运维·服务器·职场和发展
Industio_触觉智能1 小时前
瑞芯微RK系列调试工具与量产测试手册-上|串口日志打通与JTAG兜底调试
linux·sdk·jtag·瑞芯微·调试工具·rk3576·量产调试