在 Linux 上通过 udev 规则绑定 ttyUSB 设备的相对地址

news2024/9/29 13:18:25

文章目录

    • 问题描述
    • 解决方案
      • 1. 分辨当前 USB 设备的绝对地址
      • 2. 使用绝对地址查看设备属性
      • 3. 使用 udev 规则绑定设备到相对地址
        • 3.1. 区分多个不同型号 USB 设备
        • 3.2. 区分多个相同型号 USB 设备

问题描述

Linux 系统开机时会随机为连接的 USB 设备随机分配 /dev/ttyUSB* 这样的绝对地址。

如果同时接有多个 USB 设备的话,可能上一次开机设备 A 是 /dev/ttyUSB0,下一次开机就是 /dev/ttyUSB2,导致在程序中无法进行正确连接。

解决方案

1. 分辨当前 USB 设备的绝对地址

首先尽量在 Linux 系统上接入 USB 设备,使用以下命令查看当前系统分配有哪些绝对地址:

ls /dev/ttyUSB*
# 输出可能为空,也可能如下:
# /dev/ttyUSB0

然后插上一个 USB 设备,重新使用以上命令,对比输出的差别,新增部分址即为该设备当前的绝对地址,具体示例如下:

# 第一次输出
/dev/ttyUSB0
# 第二次输出
/dev/ttyUSB0  /dev/ttyUSB1
# 那么新增的 /dev/ttyUSB1 即为新插入 USB 设备当前的绝对地址

2. 使用绝对地址查看设备属性

使用 udevadm 命令可以查看 USB 设备的属性信息。

# 请将命令中的 /dev/ttyUSB1 替换为想要实际 USB 设备的绝对地址
udevadm info -a -n /dev/ttyUSB1

输出大概如下图:

在这里插入图片描述
其中在第 4 部分有该 USB 设备最详细的各个属性,各个属性的含义如下(由 ChatGPT 提供):

KERNELS=="1-4"  # 设备的内核名称。
SUBSYSTEMS=="usb"  # 设备的子系统,表示该设备属于 USB 子系统。
DRIVERS=="usb"  # 设备所使用的驱动程序。
ATTRS{authorized}=="1"  # 设备是否被授权可用。
ATTRS{avoid_reset_quirk}=="0"  # 避免重置的特性。
ATTRS{bConfigurationValue}=="1"  # 配置值。
ATTRS{bDeviceClass}=="00"  # 设备类别。
ATTRS{bDeviceProtocol}=="00"  # 设备协议。
ATTRS{bDeviceSubClass}=="00"  # 设备子类。
ATTRS{bMaxPacketSize0}=="8"  # 端点0的最大包大小。
ATTRS{bMaxPower}=="90mA"  # 设备的最大电流消耗。
ATTRS{bNumConfigurations}=="1"  # 设备的配置数量。
ATTRS{bNumInterfaces}==" 1"  # 设备的接口数量。
ATTRS{bcdDevice}=="0600"  # 设备的设备版本号。
ATTRS{bmAttributes}=="a0"  # 设备的属性。
ATTRS{busnum}=="1"  # 设备所在的总线号。
ATTRS{configuration}==""  # 设备的当前配置。
ATTRS{devnum}=="7"  # 设备号。
ATTRS{devpath}=="4"  # 设备路径。
ATTRS{idProduct}=="6001"  # 设备的产品 ID。
ATTRS{idVendor}=="0403"  # 设备的供应商 ID。
ATTRS{ltm_capable}=="no"  # 是否支持长时间传输。
ATTRS{manufacturer}=="FTDI"  # 设备的制造商。
ATTRS{maxchild}=="0"  # 子设备的最大数量。
ATTRS{product}=="FT232R USB UART"  # 设备的产品名称。
ATTRS{quirks}=="0x0"  # 设备的特性。
ATTRS{removable}=="removable"  # 设备是否可拔插。
ATTRS{rx_lanes}=="1"  # 接收通道数量。
ATTRS{serial}=="AB0P40P1"  # 设备的序列号。
ATTRS{speed}=="12"  # 设备的传输速度。
ATTRS{tx_lanes}=="1"  # 发送通道数量。
ATTRS{urbnum}=="16"  # URB(USB Request Block)的数量。
ATTRS{version}==" 2.00"  # 设备的 USB 版本。

3. 使用 udev 规则绑定设备到相对地址

/etc/udev/rules.d 路径下,通过新增 udev 规则文件可以给 USB 设备绑定类似 /dev/my_usb_dev_1 这样自定义的相对地址,从而使程序中连接 USB 设备更加灵活。

示例 udev 规则文件( example.rules )的内容如下,我们先用 ATTRS{product} 设备名属性进行绑定:

# 【USB 设备 1】
# 根据设备的某个特有属性区分设备
ATTRS{product}=="FT232R USB UART", \
# 设置设备权限
MODE:="0777", \
# 将设备绑定到相对地址
SYMLINK+="usb_dev_1"

随后使用以下命令使规则生效

sudo udevadm trigger
sudo /etc/init.d/udev restart

最后使用以下命令查看绑定是否成功

ll /dev/usb_dev_1
# 输出示例如下
# lrwxrwxrwx 1 root root 7 4月  18 11:37 /dev/usb_dev_1 -> ttyUSB0

以上说明 /dev/ttyUSB0 绝对地址的设备,已经成功绑定到 /dev/usb_dev_1 相对地址。

3.1. 区分多个不同型号 USB 设备

多个不同型号 USB 设备往往 ATTRS{product} 也是不同的,区分它们只需要使用这一属性即可。

示例 udev 规则文件( example.rules )的内容如下:

# 【USB 设备 1】
# 根据设备名区分设备
ATTRS{product}=="FT232R USB UART", \
# 设置设备权限
MODE:="0777", \
# 将设备绑定到相对地址
SYMLINK+="usb_dev_1"

# 【USB 设备 2】
# 根据设备名区分设备
ATTRS{product}=="CP2102 USB to UART Bridge Controller", \
# 设置设备权限
MODE:="0777", \
# 将设备绑定到相对地址
SYMLINK+="usb_dev_2"

注:许多博客使用 ATTRS{idVendorATTRS{idProduct} 这两个属性也是可行的,只要不同设备使用的 USB 芯片型号不同,这两个属性也就会不同。

3.2. 区分多个相同型号 USB 设备

多个不同型号 USB 设备往往绝大部分属性都是相同的,几乎只有 KERNELSATTRS{serial} 是不同的,但 KERNELS 是与硬件 USB 接口强关联的,因此使用 ATTRS{serial} 这一唯一属性区分它们更为明智。

注:如果像多数博客中使用 KERNELS 区分设备,当设备换了一个 USB 接口插上时,地址的绑定就会发生错误。

示例 udev 规则文件( example.rules )的内容如下:

# 【USB 设备 1】
# 根据设备名区分设备
ATTRS{serial}=="AB0P40P1", \
# 设置设备权限
MODE:="0777", \
# 将设备绑定到相对地址
SYMLINK+="usb_dev_1"

# 【USB 设备 2】
# 根据设备名区分设备
ATTRS{serial}=="AB0P40P2", \
# 设置设备权限
MODE:="0777", \
# 将设备绑定到相对地址
SYMLINK+="usb_dev_2"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1614654.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ubuntu20 解决网线不能联网 RTL8111/8168/8411

这种问题一般是驱动没有正确安装。 ----RTL8111/8168/8411是一块比较坑的网卡。 1、 查看网卡信息 lspci |grep Ethernet2、 对于高版本的Ubuntu,能直接使用命令安装驱动。下面的r8168-dkms需根据网卡信息修改,上面的网卡信息还有8111,但逐个…

CSS画一条虚线,并且灵活设置虚线的宽度和虚线之间的间隔和虚线的颜色

CSS画一条虚线,并且灵活设置虚线的宽度和虚线之间的间隔和虚线的颜色。 先看效果图: 在CSS中,你可以使用border属性或者background属性来画一条虚线。以下是两种常见的方法: 方法一:使用border属性 你可以设置一个元素的border…

C#版Facefusion:让你的脸与世界融为一体!-05 人脸增强

C#版Facefusion:让你的脸与世界融为一体!-05 人脸增强 目录 说明 效果 模型信息 项目 代码 下载 说明 C#版Facefusion一共有如下5个步骤: 1、使用yoloface_8n.onnx进行人脸检测 2、使用2dfan4.onnx获取人脸关键点 3、使用arcface_w60…

C++高级特性:虚函数与多态的实现原理(十三)

1、虚函数表和虚函数表指针 如果一个类存在virtual关键字函数或者继承的基类中存在virtual关键字的函数,那么该类的就会存在vptr和一个vtable vptr虚函数表指针全称virtual table pointer、vtable是虚函数表virtual table的缩写。 class A{ public:~A(); };class B…

随机森林(Random Forests)

通过5个条件判定一件事情是否会发生,5个条件对这件事情是否发生的影响力不同,计算每个条件对这件事情发生的影响力多大,写一个随机森林(Random Forests)模型程序,最后打印5个条件分别的影响力。 ChatGPT 下面是一个使…

书生·浦语大模型实战营Day04OpenXLab 部署

书生浦语大模型实战营Day04OpenXLab 部署 如何在 OpenXLab 部署一个 InternLM2-7B chat 的应用。 OpenXLab浦源平台介绍 OpenXLab 浦源平台以开源为核心,旨在构建开源开放的人工智能生态,促进学术成果的开放共享。OpenXLab面向 AI 研究员和开发者提供…

微电子领域常见概念(五)界面结合能

微电子领域常见概念(五)界面结合能 界面结合能,也称为界面能或界面自由能,是描述两种不同材料接触时在它们的交界面上存在的特殊能量状态的物理量。在材料科学中,界面结合能是一个重要的概念,因为它直接影响…

【机器学习】特征筛选:提升模型性能的关键步骤

一、引言 在机器学习领域,特征筛选是一个至关重要的预处理步骤。随着数据集的日益庞大和复杂,特征的数量往往也随之激增。然而,并非所有的特征都对模型的性能提升有所贡献,有些特征甚至可能是冗余的、噪声较大的或者与目标变量无关…

STM32定时器编码器模式

定时器编码器模式: Timer -mode Cubemx配置项: 定时器编码模式选择: Encode: mode: TI1: 通道1上升沿使计数器1 TI2: 通道2上升沿使计数器1 TI1 and TI2: 1 和 2 都会1 EX: 获取 编码器正反转数值 数值demo: int Read_Spee…

claude3国内注册

claude3国内注册 Claude 3 作为大型语言模型的强大之处在于其先进的算法设计和大规模训练数据的应用,能够执行复杂和多样化的任务。以下是 Claude 3 主要的强项: 接近人类的理解能力:Claude 3 能够更加深入地理解文本的含义,包括…

7.Prism框架之对话框服务

文章目录 一. 目标二. 技能介绍① 什么是Dialog?② Prism中Dialog的实现方式③ Dialog使用案例一 (修改器)④ Dialog使用案例2(异常显示窗口) 一. 目标 1. 什么是Dialog?2. 传统的Dialog如何实现?3. Prism中Dialog实现方式4. 使用Dialog实现一个异常信息弹出框 二. 技能介…

python编写一个简单的课时记录系统

👽发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 使用Python创建一个简单的课时记录系统 在学习过程中,跟踪课时的进度是非常重要…

LeetCode in Python 69. Sqrt(x) (x的平方根)

求x的平方根,第一想法可能是遍历0~x,求其平方,找到或且但其时间复杂度为O(n),或是想到遍历0~M即可,其中M x // 2,将时间复杂度降至O()。本文利用二分思想,给出一种时间复…

python--pyQt5 进度条:QProgressBar

https://www.cnblogs.com/itwangqiang/articles/14959401.html https://blog.csdn.net/weixin_43990846/article/details/123880081 进度条用于向用户指示操作的进度,并向他们保证应用程序仍在运行 例 1 import sys from PyQt5.QtWidgets import QApplication, QWi…

(十六)C++自制植物大战僵尸游戏的宏定义讲解

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/uzrnw 宏定义 在游戏代码中为了方便,定义了许多宏定义。使用宏定义简化代码并提高可读性。下面将讲解游戏中用到的宏定义。 代码位置 代码所在位置是Class\Scenes\GameScene文件夹中。具体如下图所示。 Define.h …

尝试给笔记本超频

超频(英语:overclocking)是把一个电子配件的时脉速度提升至高于厂方所定的速度运作,从而提升性能的方法,但此举有可能导致该配件稳定性以及配件寿命下降。 笔记本配置为: 处理器 AMD Ryzen 7 7730U wit…

学习部分排序,插入排序,冒泡排序以及希尔排序

1.插入排序 <1>.首先我们举个例子 我们要把6进行前面的插入&#xff0c;那我们要进行比较&#xff0c;首先确定一个end的指针&#xff0c;然后他指向的数字就是我们需要比较的&#xff0c;如果end指向的数比我们end1 的大的话&#xff0c;那我们就往前挪一个&#xff0c…

四六级英语听力考试音频无线发射系统在安顺学院的成功应用分析

四六级英语听力考试音频无线发射系统在安顺学院的成功应用分析 由北京海特伟业科技任洪卓发布于2024年4月22日 安顺学院为了提高学生的外语听力水平&#xff0c;并确保英语四六级听力考试的稳定可靠进行&#xff0c;决定对传统的英语听力音频传输系统进行改造&#xff0c;以提供…

【YOLOv9】实战二:手把手教你使用TensorRT实现YOLOv9实时目标检测(含源码)

‍‍&#x1f3e1;博客主页&#xff1a; virobotics(仪酷智能)&#xff1a;LabVIEW深度学习、人工智能博主 &#x1f384;所属专栏&#xff1a;『LabVIEW深度学习实战』 &#x1f4d1;上期文章&#xff1a;『【YOLOv9】实战一&#xff1a;在 Windows 上使用LabVIEW OpenVINO工具…

gitlab 16.x - ERR unknown command ‘HELLO‘

现象 gitlab部分操作报错500。通过Rails日志发现以下报错&#xff1a; 报错&#xff1a; RedisClient::CommandError ERR unknown command HELLO {"severity": "ERROR","time": "2024-04-22T02:50:16.906Z","correlation_id&quo…