如何解决Linux下USB设备节点名不固定问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何解决Linux下USB设备节点名不固定问题相关的知识,希望对你有一定的参考价值。

Linux下USB设备节点名不固定问题经常会遇到,下面就是解决的方法:
以USB转串口为例,通常设备节点名为ttyUSBx(x为0~n),Linux内核会根据插入设备的先后顺序进行编号的分配,比如第一个插入的设备编号为0,然后依此加1。
如果仅仅以设备节点ttyUSBn来区别具体是哪个设备,因为末位的编号是随时会变的,所以就会造成混乱。无法保证A设备就是0,B设备就是1。其实这个问题在LDD3上已经提到过,目前的内核早已经解决类似的问题,将所以有USB设备都导致到sys文件系统中,其实每个USB端口都有唯一的端口号,相当于每个门店的门牌号。只要我们依据端口号来进行设备的区分,那么问题就迎刃而解了。
比如当前设备插入两个USB转串口设备后,查看ttyUSBn所在端口的端口号:
root@android:/ $ ls -l /sys/class/tty/
...
lrwxrwxrwx root root 2011-01-01 13:40 ttyUSB0 -> ../../devices/ff540000.usb/usb3/3-1/3-1.1/3-1.1:1.0/ttyUSB0/tty/ttyUSB0
lrwxrwxrwx root root 2011-01-01 13:43 ttyUSB1 -> ../../devices/ff540000.usb/usb3/3-1/3-1.2/3-1.2:1.0/ttyUSB1/tty/ttyUSB1
root@android:/ $ 12345

其中ttyUSB0所在的端口号为3-1.1,而ttyUSB1所在的端口号为3-1.2。
其它类型USB设备同理,以上思路清理完毕。
查看系统当前usb设备,下面是对第二列排序的结果。
$ lsusb
Bus 001 Device 001: ID xxx:xxx Linux Foundation 2.0 root hub
Bus 001 Device 002: ID xxx:xxx Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 003: ID xxx:xxx Genesys Logic, Inc. GL827L SD/MMC/MS Flash Card Reader
Bus 001 Device 005: ID xxx:xxx Philips (or NXP)
Bus 002 Device 001: ID xxx:xxx Linux Foundation 2.0 root hub
Bus 002 Device 002: ID xxx:xxx Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 003: ID xxx:xxx Intel Corp.
Bus 003 Device 001: ID xxx:xxx Linux Foundation 2.0 root hub
Bus 004 Device 001: ID xxx:xxx Linux Foundation 3.0 root hub

第二列是usb设备的hub编号。pc中usb设备都是接在hub上的,即使你的主板提供好多usb口,他们实际都是接在hub上的。
第四列是usb设备编号,设备在本机的编号。

所以,上面信息显示一共有4个usb hub(3个usb2.0,一个usb3.0)。如果
黑体字部分是我机器上的三个设备,001.003 是机箱自带读卡器,001.005是无线键盘,002.003是intel无线网卡蓝牙模块(具体怎么知道的往下看)。

usb设备也可以用在内核文件中找到/sys/bus/usb/devices。linux将所有设备驱动映射到了/sys下。
ls -1 /sys/bus/usb/devices/
1-0:1.0
1-1
1-1:1.0
1-1.2
1-1.2:1.0
1-1.4
1-1.4.1
1-1.4:1.0
1-1.4.1:1.0
1-1.4.1:1.1
1-1.4.1:1.2
1-1.5
1-1.5:1.0
1-1.5:1.1
1-1.5:1.2
2-0:1.0
2-1
2-1:1.0
2-1.5
2-1.5:1.0
2-1.5:1.1
3-0:1.0
4-0:1.0
usb1
usb2
usb3
usb4
都是符号连接。也可以用ls -l /sys/bus/usb/devices/ 看具体位置

输出看起来比较乱。用 udevadm工具能比较清楚列出设备信息。命令看起来是这样的:
udevadm info -p /sys/bus/usb/devices/usb1 -q property

那怎么找出是那个usb设备呢?
Bus 002 Device 003: ID xxx:xxx Intel Corp.
第二列,002 就要在所有2开头的文件去找,下面的符合第一规则。
2-0:1.0
2-1
2-1:1.0
2-1.5
2-1.5:1.0
2-1.5:1.1
通常系统的usb hub占据了`-`减号后第一位0。第一个 2-0:1.0,就是usb hub。

2-1.5*文件就是上面的设备。
$ udevadm info -p /sys/bus/usb/devices/2-1.5 -q property
BUSNUM=002
DEVNAME=/dev/bus/usb/002/003
DEVNUM=003
............
ID_MODEL_ID=xxx
............
ID_VENDOR=xxx
............
ID_VENDOR_FROM_DATABASE=Intel Corp.
............
002和003 就是lsusb 的第2/4列. 第6列,来自modelID和vender。
lsusb中的的东东就是这么来的。

那问题是怎么知道是蓝牙呢? 答案是继续用udevadm查:
$ udevadm info -p /sys/bus/usb/devices/2-1.5:1.0 -q property
ID_USB_CLASS_FROM_DATABASE=Wireless
ID_USB_PROTOCOL_FROM_DATABASE=Bluetooth
ID_USB_SUBCLASS_FROM_DATABASE=Radio Frequency
ID_VENDOR_FROM_DATABASE=Intel Corp.
参考技术A 以USB转串口为例,通常设备节点名为ttyUSBx(x为0~n),Linux内核会根据插入设备的先后顺序进行编号的分配,比如第一个插入的设备编号为0,然后依此加1。
如果仅仅以设备节点ttyUSBn来区别具体是哪个设备,因为末位的编号是随时会变的,所以就会造成混乱。无法保证A设备就是0,B设备就是1。目前的内核早已经解决类似的问题,将所以有USB设备都导致到sys文件系统中,其实每个USB端口都有唯一的端口号,相当于每个门店的门牌号。只要我们依据端口号来进行设备的区分,那么问题就迎刃而解了。
比如当前设备插入两个USB转串口设备后,查看ttyUSBn所在端口的端口号:
1 root@android:/ $ ls -l /sys/class/tty/
2 ...
3 lrwxrwxrwx root root 2011-01-01 13:40 ttyUSB0 -> ../../devices/ff540000.usb/usb3/3-1/3-1.1/3-1.1:1.0/ttyUSB0/tty/ttyUSB0
4 lrwxrwxrwx root root 2011-01-01 13:43 ttyUSB1 -> ../../devices/ff540000.usb/usb3/3-1/3-1.2/3-1.2:1.0/ttyUSB1/tty/ttyUSB1
5 root@android:/ $
其中ttyUSB0所在的端口号为3-1.1,而ttyUSB1所在的端口号为3-1.2。
其它类型USB设备同理,以上思路清理完毕。

Linux 下 USB 端口和设备的绑定

一、为什么需要绑定?

如果系统中同时接入多个USB设备,比如多个USB串口,当每一次系统启动的时候,系统会为每一个插入的USB设备自动升序命名,例如:ttyUSB0、ttyUSB1…,但因为系统枚举USB设备的顺序是不一定的,而应用程序不可能每次去修改读写的设备名,因此就需要用到将USB端口和设备进行绑定。

二、如何实现USB端口和设备的绑定

  • 将要绑定的设备插入系统中,使用lsusb指令查看设备信息
droid@droid:~$ lsusb

Bus 008 Device 003: ID 2207:1808
Bus 008 Device 004: ID 2207:1808
Bus 008 Device 002: ID 0bda:0411 Realtek Semiconductor Corp.
Bus 008 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 007 Device 002: ID 0bda:5411 Realtek Semiconductor Corp.
Bus 007 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 006 Device 002: ID 174c:1153 ASMedia Technology Inc. ASM2115 SATA 6Gb/s bridge
Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 

以上是关于如何解决Linux下USB设备节点名不固定问题的主要内容,如果未能解决你的问题,请参考以下文章

如何获取当前节点的父节点名?

linux 如何写发送一个数据到usb的应用

Linux 下 USB 端口和设备的绑定

Linux 下 USB 端口和设备的绑定

Linux下如何测试及使用USB转串口线

如何在 Linux 下格式化 USB 设备