Ubuntu udev 固定USB串口名称 + 串口low_latency低延迟配置

适合嵌入式、机器人开发。解决USB转串口设备反复拔插、重启后 /dev/ttyUSBx 序号漂移的经典痛点,同时附带实时场景的低延迟串口配置。

目录

  1. 问题概述
  2. 方案一:基于USB芯片ID绑定串口(推荐,芯片唯一时)
  3. 方案二:基于物理端口位置绑定串口(同芯片多USB转串口场景)
  4. 串口低延迟 low_latency 配置(机器人/传感器实时通信)
  5. udev规则生效、验证方法
  6. 常见注意事项与故障排查

1. 问题概述

在Ubuntu下使用USB转串口模块(PL2303、CH340、CP2102等)时,存在一个高频问题:
设备名称 /dev/ttyUSB0、/dev/ttyUSB1 不是固定的。重启、拔插顺序改变,串口号就会漂移。

程序写死 /dev/ttyUSB0 会出现:上次正常,重启后找不到串口、打开设备失败,在机器人、IMU、电机控制器等嵌入式项目里非常麻烦。

udev 是Linux的设备管理子系统,可以编写规则,为USB串口创建固定符号链接(symlink)。
之后应用程序不再直接使用ttyUSBx,统一访问我们自定义的名称,例如 /dev/imu、/dev/robot。

两种绑定策略:

  1. 芯片ID绑定:根据USB厂商ID+产品ID绑定,一个芯片对应固定名称;适合芯片唯一、不会多个相同芯片同时接入的场景。
  2. 物理端口绑定:根据USB物理位置KERNELS匹配,多个一模一样的同型号USB串口芯片也能区分。

2. 方案一:基于USB芯片ID绑定串口(推荐,芯片唯一时)

原理:读取USB转串口芯片的 idVendor(厂商ID)、idProduct(产品ID),在udev规则中匹配这一组ID,创建固定符号链接。

步骤1:获取芯片VID/PID

  1. 先不插USB串口,执行:
lsusb
  1. 插入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厂商、产品ID
  • SYMLINK+="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. 常见注意事项与故障排查

  1. 文件名规范
    推荐固定命名 99-serial.rules。99是最高优先级区间,避免被其他udev规则覆盖冲突。

  2. 串口权限选择
    MODE:="0666":所有用户读写串口,开发调试方便。
    生产环境需要更安全:MODE:="0660",并把当前用户加入dialout用户组

sudo usermod -aG dialout $USER

添加组后需要重新登录生效。

  1. low_latency取舍
    低延迟会增加CPU开销,日志打印、普通串口调试场景不要开启。

  2. 规则不生效排查
    用udevadm test调试匹配过程,替换为你的tty设备:

udevadm test /sys/class/tty/ttyUSB0

看输出可以定位:规则有没有匹配、语法错误、属性不匹配等问题。

  1. 多规则共存
    芯片ID规则 和 KERNELS物理端口规则可以写在同一个99-serial.rules文件,多条规则按顺序解析。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐