Ubuntu udev 固定USB串口名称 + 串口low_latency低延迟配置
Ubuntu udev 固定USB串口名称 + 串口low_latency低延迟配置
适合嵌入式、机器人开发。解决USB转串口设备反复拔插、重启后
/dev/ttyUSBx序号漂移的经典痛点,同时附带实时场景的低延迟串口配置。
目录
- 问题概述
- 方案一:基于USB芯片ID绑定串口(推荐,芯片唯一时)
- 方案二:基于物理端口位置绑定串口(同芯片多USB转串口场景)
- 串口低延迟 low_latency 配置(机器人/传感器实时通信)
- udev规则生效、验证方法
- 常见注意事项与故障排查
1. 问题概述
在Ubuntu下使用USB转串口模块(PL2303、CH340、CP2102等)时,存在一个高频问题:
设备名称 /dev/ttyUSB0、/dev/ttyUSB1 不是固定的。重启、拔插顺序改变,串口号就会漂移。
程序写死 /dev/ttyUSB0 会出现:上次正常,重启后找不到串口、打开设备失败,在机器人、IMU、电机控制器等嵌入式项目里非常麻烦。
udev 是Linux的设备管理子系统,可以编写规则,为USB串口创建固定符号链接(symlink)。
之后应用程序不再直接使用ttyUSBx,统一访问我们自定义的名称,例如 /dev/imu、/dev/robot。
两种绑定策略:
- 芯片ID绑定:根据USB厂商ID+产品ID绑定,一个芯片对应固定名称;适合芯片唯一、不会多个相同芯片同时接入的场景。
- 物理端口绑定:根据USB物理位置
KERNELS匹配,多个一模一样的同型号USB串口芯片也能区分。
2. 方案一:基于USB芯片ID绑定串口(推荐,芯片唯一时)
原理:读取USB转串口芯片的 idVendor(厂商ID)、idProduct(产品ID),在udev规则中匹配这一组ID,创建固定符号链接。
步骤1:获取芯片VID/PID
- 先不插USB串口,执行:
lsusb
- 插入USB转串口,再次执行
lsusb
对比两次输出,多出那一行就是目标串口设备。
示例输出:
Bus 001 Device 018: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
067b → idVendor,2303 → idProduct。
步骤2:编写udev规则文件
udev规则放在 /etc/udev/rules.d/,文件名以99-开头,数字越大优先级越靠后,防止被其他规则覆盖。
sudo gedit /etc/udev/rules.d/99-serial.rules
写入规则(替换VID、PID、自定义设备名)
SUBSYSTEM=="tty", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", SYMLINK+="imu", MODE:="0666"
参数说明:
SUBSYSTEM=="tty":匹配tty串口子系统ATTRS{idVendor}/ATTRS{idProduct}:USB厂商、产品IDSYMLINK+="imu":自定义链接名,后续使用/dev/imu访问设备MODE:="0666":读写权限,所有用户可访问串口
3. 方案二:基于物理端口位置绑定串口(同芯片多USB转串口场景)
场景:多个完全相同CH340/PL2303,VID/PID全部一致,无法靠芯片ID区分,就用USB物理位置
KERNELS绑定。
同一USB口永远生成同一个名字,换USB口就失效。
步骤1:获取KERNELS物理端口标识
假设当前设备是 /dev/ttyUSB0
udevadm info -a -n /dev/ttyUSB0
在输出向上查找父设备,找到类似 KERNELS=="1-11.1:1.0" 的字符串,记录这个值。
步骤2:添加KERNELS匹配规则
打开同一个规则文件:
sudo gedit /etc/udev/rules.d/99-serial.rules
添加多条端口绑定规则示例:
SUBSYSTEM=="tty", KERNELS=="1-11.1:1.0", SYMLINK+="ttyUSB_test_front", MODE:="0666"
SUBSYSTEM=="tty", KERNELS=="1-11.2:1.0", SYMLINK+="ttyUSB_test_back", MODE:="0666"
插在主板USB 1-11.1口 →
/dev/ttyUSB_test_front;1-11.2口 →/dev/ttyUSB_test_back。
4. 串口低延迟 low_latency 配置(机器人/传感器实时通信)
Linux串口驱动默认会做缓冲,牺牲延迟降低CPU占用。IMU、运动控制器、机器人控制这类高实时场景,可以开启 low_latency。
low_latency:关闭驱动层缓冲,数据到达立刻通知应用程序,代价是CPU占用会略微上升。
安装工具 setserial
sudo apt-get install setserial
在udev规则里自动启用low_latency
通过 RUN+ 在设备挂载时自动执行setserial命令。
示例1:芯片ID绑定 + 低延迟
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="robot", MODE:="0666", RUN+="/bin/sh -c 'setserial /dev/robot low_latency'"
示例2:物理端口绑定 + 低延迟
SUBSYSTEM=="tty", KERNELS=="3-1.2", SYMLINK+="exo", MODE:="0666", RUN+="/bin/sh -c 'setserial /dev/exo low_latency'"
验证low_latency是否生效
setserial -a /dev/exo
输出里看到 low_latency: 1,代表配置成功。
⚠️ 普通串口调试场景不需要开启low_latency,仅实时控制场景推荐使用。
5. udev规则生效、验证方法
修改完规则文件,不需要重启电脑,不需要重新拔插设备,执行两条命令重载:
sudo udevadm control --reload-rules
sudo udevadm trigger --subsystem-match=tty
验证1:查看符号链接
ls -l /dev/imu /dev/exo
成功示例:
lrwxrwxrwx 1 root root 7 Nov 5 10:00 /dev/imu -> ttyUSB0
lrwxrwxrwx 1 root root 7 Nov 5 10:00 /dev/exo -> ttyUSB1
符号链接指向底层ttyUSB设备,代表创建成功。
验证2:查看设备列表
ls /dev/ttyUSB* /dev/imu /dev/exo
验证3:查看规则文本
cat /etc/udev/rules.d/99-serial.rules
6. 常见注意事项与故障排查
-
文件名规范
推荐固定命名99-serial.rules。99是最高优先级区间,避免被其他udev规则覆盖冲突。 -
串口权限选择
MODE:="0666":所有用户读写串口,开发调试方便。
生产环境需要更安全:MODE:="0660",并把当前用户加入dialout用户组
sudo usermod -aG dialout $USER
添加组后需要重新登录生效。
-
low_latency取舍
低延迟会增加CPU开销,日志打印、普通串口调试场景不要开启。 -
规则不生效排查
用udevadm test调试匹配过程,替换为你的tty设备:
udevadm test /sys/class/tty/ttyUSB0
看输出可以定位:规则有没有匹配、语法错误、属性不匹配等问题。
- 多规则共存
芯片ID规则 和 KERNELS物理端口规则可以写在同一个99-serial.rules文件,多条规则按顺序解析。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)