Ubuntu 22.04 USB 设备固定命名配置文档

Ubuntu 22.04 USB 设备固定命名配置文档

一、问题背景

当多个相同的USB串口设备(相同 VID/PID)插入电脑时,系统会随机分配 ttyUSB0ttyUSB1 等名称,导致设备识别混乱。本文档提供通过 udev 规则为每个设备创建固定名称的方法。

二、解决方案原理

利用设备的唯一硬件信息(序列号或物理端口路径)创建 udev 规则,为每个设备生成固定的符号链接(如 /dev/device_A/dev/device_B),应用程序直接使用这些固定名称。

三、准备工作

3.1 查看系统已连接的USB设备

bash

ls -la /dev/ttyUSB*

3.2 安装必要工具(如未安装)

bash

sudo apt-get update
sudo apt-get install usbutils

四、两种绑定方法

方法A:使用序列号绑定(推荐,最稳定)

步骤1:获取设备序列号

bash

# 只插一个设备
udevadm info -a -n /dev/ttyUSB0 | grep -i serial | head -1
# 输出示例:ATTRS{serial}=="A1B2C3D4"

# 拔掉,插另一个设备,重复命令
udevadm info -a -n /dev/ttyUSB0 | grep -i serial | head -1
# 输出示例:ATTRS{serial}=="E5F6G7H8"
步骤2:编写规则

bash

sudo nano /etc/udev/rules.d/99-usb-serial.rules

添加:

text

ACTION=="add", SUBSYSTEM=="tty", ATTRS{serial}=="A1B2C3D4", MODE:="0666", SYMLINK+="device_A"
ACTION=="add", SUBSYSTEM=="tty", ATTRS{serial}=="E5F6G7H8", MODE:="0666", SYMLINK+="device_B"

方法B:使用物理端口绑定(当序列号不存在或相同时使用)

步骤1:获取物理端口路径

bash

# 设备A
udevadm info -a -n /dev/ttyUSB0 | grep -A 5 "looking at parent device.*usb" | grep KERNELS
# 输出示例:KERNELS=="1-4"

# 设备B  
udevadm info -a -n /dev/ttyUSB1 | grep -A 5 "looking at parent device.*usb" | grep KERNELS
# 输出示例:KERNELS=="1-13"
步骤2:编写规则

bash

sudo nano /etc/udev/rules.d/99-usb-serial.rules

添加:

text

ACTION=="add", SUBSYSTEM=="tty", KERNELS=="1-4", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0666", SYMLINK+="device_A"
ACTION=="add", SUBSYSTEM=="tty", KERNELS=="1-13", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0666", SYMLINK+="device_B"

注意idVendor 和 idProduct 值需根据实际设备修改,可通过 lsusb 查看。device_A或device_B修改为硬件名称,如myimu、myAstraPro等。

五、规则文件详解

5.1 规则文件位置

  • 目录:/etc/udev/rules.d/

  • 命名:[数字]-[名称].rules(如 99-usb-serial.rules

  • 数字越小越先执行,用户自定义建议用 99-

5.2 常用规则参数

参数说明示例
ACTION触发动作ACTION=="add"
SUBSYSTEM子系统SUBSYSTEM=="tty"
KERNEL内核名称KERNEL=="ttyUSB*"
KERNELS父设备内核名称(物理端口)KERNELS=="1-4"
ATTRS{idVendor}USB厂商IDATTRS{idVendor}=="1a86"
ATTRS{idProduct}USB产品IDATTRS{idProduct}=="7523"
ATTRS{serial}序列号ATTRS{serial}=="A1B2C3D4"
MODE权限模式MODE:="0666"(所有用户可读写)
SYMLINK创建的符号链接名SYMLINK+="my_device"

六、应用规则

6.1 重新加载规则

bash

sudo udevadm control --reload-rules

6.2 触发规则生效

bash

# 方法1:触发特定设备
sudo udevadm trigger --subsystem-match=tty --attr-match=idVendor=1a86

# 方法2:拔插USB设备(最可靠)
# 拔掉所有设备,等3秒,重新插上

# 方法3:重启 udev 服务
sudo systemctl restart systemd-udevd

# 方法4:重启系统(100%有效)
sudo reboot

6.3 验证规则

bash

# 查看创建的符号链接
ls -la /dev/device_* /dev/my_*

# 查看实际指向
ls -la /dev/ttyUSB*

# 测试权限
cat /dev/device_A 2>&1 | head -3

七、多设备配置示例

7.1 同一个文件管理多个设备

bash

sudo nano /etc/udev/rules.d/99-usb-serial.rules

text

# === USB转串口设备规则 ===

# CH340设备1 (端口1-4)
ACTION=="add", SUBSYSTEM=="tty", KERNELS=="1-4", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0666", SYMLINK+="imu_1"

# CH340设备2 (端口1-13)
ACTION=="add", SUBSYSTEM=="tty", KERNELS=="1-13", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0666", SYMLINK+="imu_2"

# FTDI设备 (使用序列号)
ACTION=="add", SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="FTDI12345", MODE:="0666", SYMLINK+="gps_device"

# Arduino (VID/PID直接匹配)
ACTION=="add", SUBSYSTEM=="tty", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="0043", MODE:="0666", SYMLINK+="arduino"

八、调试技巧

8.1 监控 udev 事件

bash

# 实时监控设备插拔事件
sudo udevadm monitor --property --subsystem-match=tty

8.2 测试规则匹配

bash

# 测试特定设备匹配的规则
sudo udevadm test $(udevadm info -q path -n /dev/ttyUSB0) 2>&1 | grep -E "SYMLINK|my_device"

8.3 查看设备详细信息

bash

# 查看完整设备树
udevadm info -a -n /dev/ttyUSB0

# 查看USB设备列表
lsusb
lsusb -t

8.4 查看系统日志

bash

# 查看 udev 相关日志
sudo journalctl -u systemd-udevd | tail -50

九、常见问题及解决

9.1 规则不生效

可能原因

  • 规则语法错误

  • 没有重新加载规则

  • KERNELS 值获取错误

解决方法

bash

# 重新获取 KERNELS 值
udevadm info -a -n /dev/ttyUSB0 | grep -A 5 "looking at parent device.*usb" | grep KERNELS

# 重新加载
sudo udevadm control --reload-rules
sudo udevadm trigger

9.2 符号链接未创建

检查

bash

# 手动测试规则
sudo udevadm test $(udevadm info -q path -n /dev/ttyUSB0)

# 拔插设备后查看
ls -la /dev/ | grep -E "ttyUSB|my_device"

9.3 权限问题

在规则中添加:

text

MODE:="0666"

或指定用户组:

text

GROUP:="dialout", MODE:="0660"

9.4 设备换口后失效(物理端口绑定)

解决方法:

  • 重新获取新端口的 KERNELS 值

  • 更新规则文件

  • 或改用序列号绑定

十、最佳实践建议

10.1 命名规范

  • 使用有意义的名称:imu_leftgps_rearlidar_front

  • 避免使用空格和特殊字符

  • 全部小写,用下划线分隔

10.2 规则文件管理

  • 所有USB设备规则写在同一文件:99-usb-serial.rules

  • 添加注释说明每个设备的用途

  • 备份重要规则:sudo cp /etc/udev/rules.d/99-usb-serial.rules ~/

10.3 优先级使用

  • 系统自带规则:00-79

  • 用户自定义:80-99

  • 推荐使用 99- 确保最后执行

十一、完整操作流程速查

bash

# 1. 插入设备,查看当前分配
ls -la /dev/ttyUSB*

# 2. 获取物理端口
udevadm info -a -n /dev/ttyUSB0 | grep -A 5 "looking at parent device.*usb" | grep KERNELS

# 3. 编辑规则文件
sudo nano /etc/udev/rules.d/99-usb-serial.rules
# 添加规则:ACTION=="add", SUBSYSTEM=="tty", KERNELS=="1-4", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0666", SYMLINK+="my_device"

# 4. 重新加载规则
sudo udevadm control --reload-rules
sudo udevadm trigger

# 5. 验证结果
ls -la /dev/my_device

十二、参考资料


文档版本:1.0
最后更新:2024-03-02
适用系统:Ubuntu 22.04 / 20.04 / Debian 系列

调试问题:

zhping@zhping-Legion:~$ ls -la /dev/ttyUSB* crw-rw-rw- 1 root dialout 188, 0 3月 3 20:11 /dev/ttyUSB0 crw-rw---- 1 root dialout 188, 1 3月 3 20:12 /dev/ttyUSB1 zhping@zhping-Legion:~$

看到问题了!两个设备的权限不一致

  • /dev/ttyUSB0crw-rw-rw- (666权限,所有用户可读写) ✅

  • /dev/ttyUSB1crw-rw---- (660权限,只有root和dialout组可读写) ❌

问题原因

你的规则文件里最后两行都有 MODE:="0666",但只对 ttyUSB0 生效了,ttyUSB1 没有正确应用权限设置。

解决方法

1. 检查当前规则文件

bash

cat /etc/udev/rules.d/*.rules | grep -E "1a86|7523|myimu|sc_mini"

2. 确保两条规则都完整且正确

bash

sudo nano /etc/udev/rules.d/99-usb-serial.rules

确认最后两行是:

text

ACTION=="add", SUBSYSTEM=="tty", KERNELS=="1-4", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0666", SYMLINK+="sc_mini"
ACTION=="add", SUBSYSTEM=="tty", KERNELS=="1-13", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0666", SYMLINK+="myimu"

3. 强制重新应用规则

bash

# 重新加载规则
sudo udevadm control --reload-rules

# 删除现有符号链接(如果存在)
sudo rm -f /dev/sc_mini /dev/myimu

# 重新触发所有ttyUSB设备
sudo udevadm trigger --action=add --subsystem-match=tty --attr-match=idVendor=1a86

# 或者直接重启 udev 服务
sudo systemctl restart systemd-udevd

4. 拔插设备

最简单可靠的方法:

bash

# 拔掉两个USB设备,等3秒,重新插上

5. 验证结果

bash

# 检查权限
ls -la /dev/ttyUSB*

# 检查符号链接
ls -la /dev/sc_mini /dev/myimu 2>/dev/null

应该看到两个设备都是 crw-rw-rw- 权限。

如果问题依旧,试试这个强力方法:

bash

# 1. 临时手动修改权限(临时解决)
sudo chmod 666 /dev/ttyUSB1

# 2. 完全删除规则文件并重建
sudo rm /etc/udev/rules.d/99-usb-serial.rules
sudo nano /etc/udev/rules.d/99-usb-serial.rules
# 重新粘贴规则

# 3. 重启系统
sudo reboot

验证最终结果:

bash

ls -la /dev/ttyUSB*

应该显示:

text

crw-rw-rw- 1 root dialout 188, 0 ... /dev/ttyUSB0
crw-rw-rw- 1 root dialout 188, 1 ... /dev/ttyUSB1

完成后告诉我结果!

zhping@zhping-Legion:~$ cat /etc/udev/rules.d/*.rules | grep -E "1a86|7523|myimu|sc_mini" ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", ENV{ID_MM_DEVICE_MANUAL_SCAN_ONLY}="1" ACTION=="add", SUBSYSTEM=="tty", KERNELS=="1-4", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0666", SYMLINK+="sc_mini" ACTION=="add", SUBSYSTEM=="tty", KERNELS=="1-13", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0666", SYMLINK+="myimu" zhping@zhping-Legion:~$ sudo nano /etc/udev/rules.d/99-usb-serial.rules

规则文件内容看起来是正确的!两条规则都有 MODE:="0666"。现在让我们强制重新应用规则:

完整修复步骤:

1. 先停止当前 udev 对这两个设备的处理

bash

# 删除现有的符号链接
sudo rm -f /dev/sc_mini /dev/myimu

2. 重新加载规则并强制触发

bash

# 重新加载所有规则
sudo udevadm control --reload-rules

# 删除内核中已有的设备状态
echo 'ACTION=="remove", SUBSYSTEM=="tty", KERNEL=="ttyUSB*", RUN+="/bin/true"' | sudo tee /etc/udev/rules.d/99-cleanup.rules
sudo udevadm control --reload-rules

3. 最简单可靠的方法:拔插设备

bash

# 1. 拔掉两个USB设备
# 2. 等待3秒
# 3. 重新插上两个设备

4. 检查结果

bash

ls -la /dev/ttyUSB*

如果还是不行,试试:

5. 重启 udev 服务

bash

sudo systemctl restart systemd-udevd
# 等待几秒
ls -la /dev/ttyUSB*

6. 终极方法:重启系统

bash

sudo reboot

重启后检查:

bash

ls -la /dev/ttyUSB*
ls -la /dev/sc_mini /dev/myimu 2>/dev/null

如果重启后还是只有 ttyUSB0 有 666 权限

可能是 ModemManager 在干扰。可以临时禁用 ModemManager 测试:

bash

# 暂停 ModemManager 服务
sudo systemctl stop ModemManager

# 拔插设备,检查权限
ls -la /dev/ttyUSB*

# 如果正常了,永久禁用
sudo systemctl disable ModemManager
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值