【Linux】解决两个USB设备VID/PID/序列号全一样无法区分的问题 (udev物理端口绑定)

1. 问题描述

最近在搞机器人开发,买了一个 IMU 和一个 RTK 模块。插到电脑上发现一件很崩溃的事:

这俩货用的 USB 转串口芯片一模一样,导致:

  • idVendor 一样

  • idProduct 一样

  • Serial Number 也一样(全是空或者默认值)

这就导致没法用常规的 ATTRS{idVendor} 或 ATTRS{serial} 来写 udev rules 固定设备名(比如 /dev/ttyimu)。每次重启或重插拔,/dev/ttyUSB0 和 /dev/ttyUSB1 就会随机互换,程序经常读错设备。

2. 解决方案

既然软件层面的 ID 无法区分,只能使用 物理端口绑定 (Physical Port Binding)

也就是说:通过识别设备插在电脑的哪个 USB 孔上,来给它命名。

注意 :这种方法的缺点是,一旦配置好,USB 线就不能乱换插孔,也不能随便加减 USB Hub,否则规则会失效。

3. 操作步骤

第一步:物理连接(定死位置)

先把设备插好,决定好它们以后就在这不动了。

  • 比如:IMU 插在扩展卡的上口 ,RTK 插在下口

  • 此时系统分配了 ttyUSB0 和 ttyUSB1。

第二步:查找物理路径 (KERNELS)

我们需要找到代表那个 USB 物理孔的唯一编码。

在终端分别执行:

bash 复制代码
# 查看 ttyUSB0 的物理路径信息
udevadm info -a -n /dev/ttyUSB0 | grep KERNELS

# 查看 ttyUSB1 的物理路径信息
udevadm info -a -n /dev/ttyUSB1 | grep KERNELS

输出里会有很多 KERNELS,找第三行左右、类似 1-2 或 3-1:1.0 这种格式的

你会发现两个设备的这个值是不一样的。

  • 假设 IMU (ttyUSB0) 查到的是:KERNELS=="3-1"

  • 假设 RTK (ttyUSB1) 查到的是:KERNELS=="3-2"

第三步:编写 udev 规则文件

新建或修改规则文件:

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

写入以下内容(把 KERNELS 换成你刚才查到的实际值):

bash 复制代码
# ==========================================================
# 解决双胞胎设备问题:ID和序列号均相同,通过物理路径(KERNELS)绑定
# 警告:插孔位置一旦改变,规则将失效!
# ==========================================================

# 1. IMU 模块 (物理位置:3-1)
ACTION=="add", SUBSYSTEM=="tty", KERNELS=="3-1", MODE="0777", GROUP="dialout", SYMLINK+="ttyimu"

# 2. RTK 模块 (物理位置:3-2)
ACTION=="add", SUBSYSTEM=="tty", KERNELS=="3-2", MODE="0777", GROUP="dialout", SYMLINK+="ttyrtk"
第四步:重新加载生效

保存文件后,执行以下命令重载规则:

bash 复制代码
sudo udevadm control --reload && sudo udevadm trigger

此时查看 /dev 下应该就有固定的软链接了:

bash 复制代码
ls -l /dev/ttyimu /dev/ttyrtk

4. 总结

  • 首选方案:如果有序列号 (ATTRS{serial}),优先用序列号区分,那样不怕换插孔。

  • 备选方案 :如果序列号一样,只能用本文的 KERNELS 方法,但要记住线不能乱动

相关推荐
开心大爆炸7 小时前
xrdp 连接 登录对话框输入密码后闪退
linux·运维·服务器
oushaojun28 小时前
大厂 C++ 面试:深度剖析 Linux Signal 信号机制(转)
linux
苏生Susheng9 小时前
【软件实施】Linux系统Shell脚本教程
linux·运维·服务器·chrome·spring boot·学习·实施
2601_962304919 小时前
把出片接进自动化流水线:2026 年批量 AI 视频生成工具的脚本契约与同类项目对照
运维·人工智能·自动化
曹牧9 小时前
C#:文本文件读取
服务器·前端·c#
Ruiery9 小时前
Linux 6.6内核 IOMMU 深度解析(七):DMA API 与 IOMMU 集成 — 从 dma_map_single 到 iommu_map
linux·运维·服务器
分支预测失败9 小时前
RISC-V AIA 中断架构实战:从 PLIC 到 APLIC 与 IMSIC 的迁移
linux·后端
GeW9 小时前
RHCE学习拿证计划:锁定核心考点,实现备考效率最大化
linux
snow@li9 小时前
服务器运维:Alibaba Cloud Linux 4 LTS 64位 根目录全景深度解析文章
linux·运维·服务器
实战派K8S&DB9 小时前
《基于 Dify + FastAPI + PyTiDB 搭建大模型驱动的 TiDB 智能运维 Agent》
运维·数据库·分布式·云原生·tidb·fastapi