解决Linux下USB设备节点ttyUSB名不固定的问题,生成固定USB转串口设备节点

2018-09-19

http://blog.sina.com.cn/s/blog_8b58097f0102wxm3.htmlARM,STM32,FPGA,AD,PCB同行原创bloghttp://blog.sina.com.cn/s/articlelist_2337802623_0_1.html

1.Linux下USB设备节点名不固定问题经常会遇到

以USB转串口设备为例,通常设备节点名为ttyUSBx(x为0~n),Linux内核会根据设备插入的先后顺序进行编号的分配,比如第一个插入的设备编号为ttyUSB0,然后依此加1,变为ttyUSB1,ttyUSB2……

如果仅仅以设备节点ttyUSBx来区别具体是哪个设备,因为末位的编号是随时会变的,所以就会造成混乱。无法保证A设备就是ttyUSB0,B设备就是ttyUSB1。在设备文件/dev目录下并没有提供固定显示ttyUSB的方法,但是,其实,每个USB端口都有唯一的端口号,相当于每个门店的门牌号。只要我们依据端口号来进行设备的区分,那么问题就迎刃而解了。简单点来说就是找到端口号,然后根据端口号找到挂载在这个端口号上面的USB设备是ttyUSB0还是ttyUSB1….(这个是变化的,前面讲到了)。

2.关于端口号的查看方法,连接好两个USB转串口设备之后:

执行命令:ls -l/sys/class/tty/ttyUSB*

lrwxrwxrwx root    root            2017-08-0113:40 ttyUSB0 ->../../devices/ff540000.usb/usb3/3-1/3-1.1/3-1.1:1.0/ttyUSB0/tty/ttyUSB0

lrwxrwxrwx root    root            2017-08-0113:43 ttyUSB1 ->../../devices/ff540000.usb/usb3/3-1/3-1.2/3-1.2:1.0/ttyUSB1/tty/ttyUSB1

可知:其中ttyUSB0所在的端口号为3-1.1,而ttyUSB1所在的端口号为3-1.2,可以看出,这里的3-1.1端口上比3-1.2上提前插上USB设备,所以会以这种方式命名。如果插入设备的顺序相反,那么端口号3-1.1上对应的设备应该是ttyUSB1,而3-1.2上对应的设备应该是ttyUSB0。但是如果在实际过程中我们只需要采集端口3-1.1传来的数据,我们该如何通过ttyUSBx不定的设备节点,获取到固定端口的数据呢?

3.实际问题,实际解决:

实际工程中,碰到的一个问题是:硬件上连接有两个USB转串口设备,硬件只要一上电,两个USB设备几乎是同时上电的,这将导致ttyUSB0或者ttyUSB1无法每次固定的对应到上一次的那个相同端口,上层软件需要通过串口设备节点/dev/ttyUSBx来打开一个串口,并从串口获取数据,但是这个ttyUSBx设备并不是一直都指向固定的一个usb端口号,这直接导致我们无法往下操作了。

解决办法:这里使用bash语言加Python正则表达式的相关知识解决这个问题:解决问题的思路是:

1. 第一次上电的时候,我们需要确定哪个端口上的数据是我们所需要的:

ls -l/sys/class/tty/ttyUSB*

假设是3-1.1这个端口是我们的data端口。

2.以后每次上电,我们要找到3-1.1这个端口后面挂载的ttyUSB设备是ttyUSB0还是ttyUSB1,并建立一个软链接将当时获取到的ttyUSBx生成一个软链接,名字固定为ttydata,那么以后每次打开/dev/ttydata就能找到正确3-1.1这个端口,并获取数据了。

3.建立一个文件夹getUSB,该文件夹下面包含:

其中cmd.sh是利用bash脚本获取/sys/class/tty/ttyUSB*的一些信息保存在device_usb.txt中

getUSB.py是通过device_usb.txt中的信息,获取到当前挂着在端口3-1.1上的是ttyUSB0还是ttyUSB1并保存在usbdev中

cmd.sh如下:

#!/bin/bash

declare -i a=0

declare -i b=0

while [[ ! -e "/sys/class/tty/ttyUSB0" ]]

do

sudo sleep 0.01s

a=a+1

if [ $a -eq 300 ];then #等待一段时间没有检测ttyUSB0设备到会自动跳出while

break

fi

done

while [[ ! -e "/sys/class/tty/ttyUSB1" ]]

do

sudo sleep 0.01s

b=b+1

if [[ $b -eq 300||$a -ne 0 ]];then  #if USB0been detected ,also get out of while

break

fi

done

if [[ ! -e /sys/class/tty/ttyUSB0&&! -e/sys/class/tty/ttyUSB1 ]]; then #如果不存在ttyUSB设备

echo "Not have ttyUSB0 or not have ttyUSB1"

else                             #如果完美检测到了两个ttyUSB设备,则将信息log到device_usb.txt当中

tty1=$(ls -l /sys/class/tty/ttyUSB0)

tty2=$(ls -l /sys/class/tty/ttyUSB1)

sudo ls -l /sys/class/tty/ttyUSB0 /sys/class/tty/ttyUSB1 >./device_usb.txt

fi

if [ ! -n "$tty1" ] ;then   # "! -n" showsblank var  #非空检测

echo "tty1 is empty"

fi

#delay 0.01s to make sure the device_usb.txt complete

sudo sleep 0.01s

#remove the old USB device shortcut

if [ ! -e "/dev/ttydata" ] ;then # 如果/dev/ttydata本身不存在

echo "-------------/dev/ttydata not found"

else                               #如果存在,则需删除之,然后重新创建之

echo "/dev/ttydata is exist"

sudo rm /dev/ttydata

fi

#exct Python language to get the rignt USB interface

./getUSB.py   #调用当前路径下的getUSB.py这个Python语言,明确此次是哪个,ttyUSB0,或者ttyUSB1挂载在端口3-1.1上

usbdev=$(cat ./usbdev) #获取到这个设备

echo "the device is : "

echo $usbdev

sudo ln -s /dev/$usbdev /dev/ttydata#将这个设备软连接到/dev/ttydata以后每次打开这个ttydata即可

getUSB.py:

#!/usr/bin/python

#coding:utf-8

import re  #正在表达式

sss = open("./device_usb.txt","rb")#打开device_usb.txt设备,并读取内容

www = open("./usbdev","wb") #当前路径下创建usbdev文件,后续会写入内容

s_read = sss.read()  usb3/3-1/3-1.1/

r = r"usb3/3-1/3-1\.1.+(ttyUSB[0-9])"

#正则中“.”需要转义,所以使用“\.”表示“.”

#这个规则是找到usb3/3-1/3-1.1/这个字符串后面紧跟的是此次上电生成的ttyUSB0或者ttyUSB1

output = re.findall(r,s_read)

www.write(output[0]) #将结果写到usbdev中

www.close()

sss.close()

完成之后设置开机项目,将文件夹当道一个位置,然后设置开机启动cmd.sh(在/etc/rc.local中设置)则每次开机之后,会从/dev/ttydata获取到固定端口的数据

这两天在ubuntu中开发跟串口有关程序时,发现来回拔插串口线或者插多个串口线时总是出现串口号ttyUSB*不固定的问题,给应用程序带来不少麻烦,遂google解决。

linux中设备号一般按先后顺序一次向后增大,udev规则文件可以解决这个蛋疼的问题。udev是一种Linux2.6内核采用的/dev目录的管理系统(可以把它认为是windows中的设备管理器),它通过从sysfs获得的信息,可以提供对特定设备的固定的设备名。sysfs是linux 2.6内核的一种新型文件系统,它提供了当前设备的基本信息。

udev的重要功能就是为为设备提供固定的设备名, 根据Wirting udev rules的详细介绍,udev有如下功能:

Rename a device node from the default name to something else

Provide an alternative/persistent name for a device node bycreating a symbolic link to the default device node

Name a device node based on the output of a program

Change permissions and ownership of a device node

Launch a script when a device node is created or deleted (typicallywhen a device is attached or unplugged)

Rename network interfaces

简单阅读之后创建文件/etc/udev/rules.d/10-local.rule,内容如下

[html] viewplain copy

<span style="white-space:pre">  span>KERNEL=="ttyUSB*", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", MODE:="0777", SYMLINK+="user_uart"

<span style="white-space:pre">  span>KERNEL=="ttyUSB*", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0777", SYMLINK+="mcu_uart"

意思就是匹配sys中内核名为ttyUSB*的设备,属性匹配依据生产商编号idVendor和产品号idProduct,设定读写权限为0777, 符号链接名为user_uart-----PL2303串口转USB,mcu_uart----CH340串口转USB。

idVendor和idProduct由 lsusb  -vvv命令查看。

保存退出后udev规则就生效了,重新拔插两个串口设备,就可以看到/dev/user_uart指向/dev/ttyUSB0, /dev/mcu_uart指向/dev/ttyUSB1.这样以来,我只要在程序里打开/dev/user_uart或/dev/mcu_uart就可以一直准确的打开指定的串口设备了。

PS:如果您的两个串口用的都是PL2303或者都是CH340/CP2102,那就真的无能为力了。。。

常用的匹配类型:

* BUS:匹配总路类型,比如PCIUSB等

* KERNEL:- 匹配Kernel设备名,比如hdahdb.

* DRIVER :-匹配Kernel的驱动程序名

* SUBSYSTEM: -匹配子系统名。

* ID :- 匹配总路系统的ID (e.g. PCI busID)。

* PLACE :- 匹配物理位置 (对USB很有用)

资料链接:

http://www.cnblogs.com/ynxf/p/6379449.html

http://biancheng.dnbcw.net/linux/295328.html

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。

http://www.pinlue.com/style/images/nopic.gif

linux下usb设备节点名不固定,解决Linux下USB设备节点ttyUSB名不固定的问题,生成固定USB转串口设备节点...相关推荐

  1. IIS - 实现HTTPS的主机名绑定(解决IIS7下主机名灰色无法修改问题)

    问题 默认情况下,IIS7 下面 HTTPS 绑定是无法指定主机名的. 如下图可以看到"主机名"这块是灰色不可编辑的. 解决方案 IIS - 实现HTTPS的主机名绑定(解决IIS ...

  2. windows下修改黑苹果config_【黑苹果】解决linux和黑苹果下usb无线网卡兼容问题

    黑苹果* 简单的说,就是在自己的电脑上安装苹果系统(MAC OS).但由于苹果公司的软硬件限制,导致装系统这么一个在WIN系统中平常的事情,变成很多极客爱好者的专业.比如,我们的毛老师- 上面这个配置 ...

  3. linux下u盘目录带锁,完美解决linux下U盘文件只读的问题

    1. 在终端运行如下命令 tail -f /var/log/syslog 2. 插入有只读文件系统故障的U盘 3. 观察命令行输出 输出局部如下: Jul  8 16:44:50 cslouis-pc ...

  4. linux 解压文件乱码,云服务器:解决linux下zip文件解压乱码问题

    云服务器:解决linux下zip文件解压乱码问题 原因 由于zip格式并没有指定编码格式,Windows下生成的zip文件中的编码是GBK/GB2312等,因此,导致这些zip文件在Linux下解压时 ...

  5. linux apr防火墙,教你一招:解决linux下arp攻击的方法

    一般Windows用户可以使用antiArp防火墙,但是有些计算专业的朋友们由于工作或其他原因使用的是linux系统,那么linux下arp攻击怎么办呢?下面就是一位高手解决linux下arp攻击的方 ...

  6. linux服务器每次重启卡住,运维如何解决Linux服务器重启后命令无法正常使用的问题...

    原标题:运维如何解决 Linux 服务器重启后命令无法正常使用的问题 前提:在Linux系统中安装ASM,安装完ASM和Oracle数据库时都是正常使用的,但在重启服务器后Oracle相关命令不识别. ...

  7. 解除计算机睡眠不能打印,win10下打印机深度休眠不打印怎么解决_win10下网络打印机休眠无法打印...

    打印机是我们常用的办公设备.一些win10系统用户碰到打印机突然不能打印了,win10系统显示屏上出现打印机深度睡眠.那么怎么取消打印机休眠呢?今天爱纯净小编详细介绍下打印机深度休眠不打印的唤醒方法. ...

  8. linux和windows双系统怎么引导,如何解决Linux和Windows双系统的引导问题

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 现在大家应该都在上班吧,咱今天探讨的是解决Linux和Windows双系统的引导问题 本文中, Windows使用XP, Linux选用Ubuntu. 但 ...

  9. Linux中配置DNS出现的问题,完美解决liunx下dns配置重启失效的问题

    有时候能ping同ip地址,却ping不通域名,这就是dns没有配置的缘故. 但是DNS配置文件 /etc/resolv.conf 每次重启就会失效. 打开这个配置文件,发现有注释提示: Dynami ...

最新文章

  1. matlab练习程序(图像区域分裂)
  2. Window CMD快捷键
  3. C# 类中继承接口的属性
  4. HD_2037今年暑假不AC
  5. 基于sentry的前端错误监控日志系统(部署sentry服务器/前端项目部署)-让前端最快的定位到生产问题...
  6. 最受欢迎的应用服务器
  7. 五个提升人生智慧的经典故事
  8. 开源计算机集群监控Ganglia应用视频
  9. 【王道操作系统笔记】进程定义组成组织方式特征
  10. android studio 便携式wlan热点 网络名称_手机移动网络共享,还可以这么玩,你知道吗?...
  11. 心有所鼠,鼠年快乐~
  12. javascript的constructor属性介绍
  13. 深入浅出通信原理知识点2
  14. log4j的日志级别以及配置
  15. Speedoffice(word)如何绘制流程图
  16. locality sensitive hashing(LSH)原理和具体实现
  17. 管网模型(julia)
  18. 时光机················
  19. 怎样在PDF上直接编辑文字?这几种编辑方法需要掌握
  20. 非侵入式负荷matlab程序,非侵入式负荷分解之BLUED数据集

热门文章

  1. composer 完整路径才能访问_一份完整的运营方案策划思路,拿走不谢(精华版)
  2. 通信网络基础实验报告_建设亚太信息枢纽港、实现5G网络全覆盖!临港新片区通信基础设施规划发布...
  3. 招聘面试的套路和原则
  4. 小米手机能用上鸿蒙吗,鸿蒙系统小米手机能用吗?鸿蒙系统支持第三方手机!
  5. html表白_HTML 表白网页
  6. numpy 矩阵乘法_一起学习Python常用模块——numpy
  7. devc代码补全没效果_从零开始写文本编辑器(二十八):自动补全(上)
  8. 传智学员信息登记表html代码_IT兄弟连 HTML5教程 HTML5文字版面和编辑标签 使用HTML表格...
  9. Linux下crontab乱码,Linux下crontab自动运行Java程序乱码解决方案
  10. java super object,java学习记录笔记--继承,super,Object类