简体   繁体   English

如何在Ubuntu 10.1下识别多个USB串行适配器

[英]How to identify multiple USB-serial adapters under Ubuntu 10.1

I am reading data from multiple identical USB-serial adapters under Ubuntu 10.1. 我正在Ubuntu 10.1下从多个相同的USB串行适配器读取数据。

On occasion, their /dev/tty path changes (eg if other USB devices are connected on startup). 有时,它们的/ dev / tty路径会发生变化(例如,如果启动时连接了其他USB设备)。

I need a way of repeatedly referring to the same adapter through any such changes. 我需要一种通过任何此类更改重复引用相同适配器的方法。

The devices all have the same serial numbers, according to udevadm. 根据udevadm,这些设备都具有相同的序列号。

I think the most likely option is to identify an adapter by which port it is connected to (they don't get moved around). 我认为最可能的选择是识别连接到哪个端口的适配器(它们不会被移动)。

I can find all sorts of interesting /dev paths that might work, but despite all the discussion about udev online, I can't locate a definitive statement about whether some of these paths are static if the device is plugged into a static port. 我可以找到可能有用的各种有趣的/ dev路径,但是尽管有关于udev在线的所有讨论,但是如果设备插入静态端口,我找不到关于这些路径中的某些路径是否是静态的明确声明。

There is a solution. 有一个解决方案。 It's better late then never ;) 从来没有好过晚了;)

Use the following udev rule to map /dev/ttyUSB{?} devices into the /dev/usb-ports/%bus_id-%port_id link. 使用以下udev规则将/dev/ttyUSB{?}设备映射到/dev/usb-ports/%bus_id-%port_id链接。

Here is my /etc/udev/rules.d/usb-parse-devpath.rules: 这是我的/etc/udev/rules.d/usb-parse-devpath.rules:

ACTION=="add", KERNEL=="ttyUSB[0-9]*", PROGRAM="/etc/udev/rules.d/usb-parse-devpath.pm %p", SYMLINK+="usb-ports/%c"

And the usb-parse-devpath.pm script: usb-parse-devpath.pm脚本:

#!/usr/bin/perl -w

@items = split("/", $ARGV[0]);
for ($i = 0; $i < @items; $i++) {
    if ($items[$i] =~ m/^usb[0-9]+$/) {
        print $items[$i + 1] . "\n";
        last;
    }
}

As you can see this helps us to create named links to /dev/ttyUSB{?} devices and place them at /dev/usb-ports in the following format: bus_id-port_id . 如您所见,这有助于我们创建指向/dev/ttyUSB{?}设备的命名链接,并将它们放在/dev/usb-ports中,格式如下: bus_id-port_id

For example, the next command gives me the following: 例如,下一个命令给出了以下内容:

$ udevadm info --query=path --name=/dev/ttyUSB0
/devices/pci0000:00/0000:00:1d.1/usb3/3-1/3-1:1.0/ttyUSB0/tty/ttyUSB0

So, the bus_id is 3 and port_id is 1 and now I have following in my /dev/usb-ports : 所以, bus_id3port_id1 ,现在我的/dev/usb-ports有以下内容:

$ ls -al /dev/usb-ports
lrwxrwxrwx  1 root root   10 Май 12 00:26 3-1 -> ../ttyUSB0

Regards. 问候。

Look with $ udevadm info -n /dev/ttyUSB0 -a which port your USB device is plugged in. The variable KERNELS of one of the parent devices should be something like KERNELS=="1-1.2:1.0". 请查看$ udevadm info -n /dev/ttyUSB0 -a USB设备插入的端口。其中一个父设备的变量KERNELS应该类似于KERNELS ==“1-1.2:1.0”。

Create a udev rule: 创建一个udev规则:

SUBSYSTEM=="tty", KERNELS=="1-1.2:1.0", SYMLINK+="ttyUSB42"
SUBSYSTEM=="tty", KERNELS=="1-1.3:1.0", SYMLINK+="usb-serial"

and trigger udev 并触发udev

$ udevadm trigger

I have many USB to Serial devices with each many ports and the solutions mentioned above did not quite did it for me. 我有许多USB到串行设备, 每个端口很多,上面提到的解决方案对我来说并不是很好。

The USB "KERNEL" was not enough in my case, but I found the port number. USB“KERNEL”在我的情况下是不够的,但我找到了端口号。

I am aware that what I'm proposing now might be considered an insane hack, but it works for me.. 我知道我现在提出的建议可能会被认为是一个疯狂的黑客,但它对我有用..
for now.. 目前..

I would actually be pleased to see a more elegant suggestion that accomplish something similar.. 我真的很高兴看到一个更优雅的建议,实现类似的东西..

So... Based on the previous answer form Ilya Matveychikov 所以...基于之前的答案形式Ilya Matveychikov

File: /etc/udev/rules.d/usb-parse-devpath.sh 文件:/etc/udev/rules.d/usb-parse-devpath.sh

#!/bin/bash

DEVNUM=$(echo "${1}" | rev | cut -d'/' -f4 | rev | tr -d '-' | tr -d '.' | tr -d ':')
PORTNUM=$(/sbin/udevadm info -a --path=${1} | grep "ATTRS{port_number}" | head -1 | cut -d'"' -f2)
PRODUCT=$(/sbin/udevadm info -a --path=${1} | grep "ATTRS{product}" | head -1 | cut -d'"' -f2 | tr -d '/' | tr ' ' '_')

NEWID="ttyUSB_${PRODUCT}_${DEVNUM}${PORTNUM}"

#echo "${NEWID} :: $1" >> /tmp/DEBUG_udev.txt

echo "$NEWID"

And File: /etc/udev/rules.d/99-usb-serial.rules 和文件:/etc/udev/rules.d/99-usb-serial.rules

ACTION=="add", KERNEL=="ttyUSB[0-9]*", PROGRAM="/etc/udev/rules.d/usb-parse-devpath.sh %p", SYMLINK+="TTYUSBs/%c"

The result look something like this: 结果看起来像这样:

# ls -l /dev/TTYUSBs

lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport416_435100 -> ../ttyUSB20
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport416_435101 -> ../ttyUSB21
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport416_435102 -> ../ttyUSB22
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport416_435103 -> ../ttyUSB23
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport416_435104 -> ../ttyUSB24
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport416_435105 -> ../ttyUSB25
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport416_435106 -> ../ttyUSB26
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport416_435107 -> ../ttyUSB27
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport416_436100 -> ../ttyUSB28
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport416_436101 -> ../ttyUSB29
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport416_436102 -> ../ttyUSB30
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport416_436103 -> ../ttyUSB31
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport416_436104 -> ../ttyUSB32
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport416_436105 -> ../ttyUSB33
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport416_436106 -> ../ttyUSB34
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport416_436107 -> ../ttyUSB35
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport4_4341100 -> ../ttyUSB38
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport4_4341101 -> ../ttyUSB39
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport4_4342100 -> ../ttyUSB36
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport4_4342101 -> ../ttyUSB37
lrwxrwxrwx. 1 root root 10 Jan  5 18:46 ttyUSB_Edgeport8_421100 -> ../ttyUSB2
lrwxrwxrwx. 1 root root 10 Jan  5 18:46 ttyUSB_Edgeport8_421101 -> ../ttyUSB3
lrwxrwxrwx. 1 root root 10 Jan  5 18:46 ttyUSB_Edgeport8_422100 -> ../ttyUSB4
lrwxrwxrwx. 1 root root 10 Jan  5 18:46 ttyUSB_Edgeport8_422101 -> ../ttyUSB5
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport8_423100 -> ../ttyUSB18
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Edgeport8_423101 -> ../ttyUSB19
lrwxrwxrwx. 1 root root 10 Jan  5 18:46 ttyUSB_Edgeport8_424100 -> ../ttyUSB0
lrwxrwxrwx. 1 root root 10 Jan  5 18:46 ttyUSB_Edgeport8_424101 -> ../ttyUSB1
lrwxrwxrwx. 1 root root 10 Jan  5 18:46 ttyUSB_Keyspan_USA-49WG_431100 -> ../ttyUSB6
lrwxrwxrwx. 1 root root 10 Jan  5 18:46 ttyUSB_Keyspan_USA-49WG_431101 -> ../ttyUSB7
lrwxrwxrwx. 1 root root 10 Jan  5 18:46 ttyUSB_Keyspan_USA-49WG_431102 -> ../ttyUSB8
lrwxrwxrwx. 1 root root 10 Jan  5 18:46 ttyUSB_Keyspan_USA-49WG_431103 -> ../ttyUSB9
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Keyspan_USA-49WG_432100 -> ../ttyUSB10
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Keyspan_USA-49WG_432101 -> ../ttyUSB11
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Keyspan_USA-49WG_432102 -> ../ttyUSB12
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Keyspan_USA-49WG_432103 -> ../ttyUSB13
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Keyspan_USA-49WG_433100 -> ../ttyUSB14
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Keyspan_USA-49WG_433101 -> ../ttyUSB15
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Keyspan_USA-49WG_433102 -> ../ttyUSB16
lrwxrwxrwx. 1 root root 11 Jan  5 18:46 ttyUSB_Keyspan_USA-49WG_433103 -> ../ttyUSB17

Much like Ilya Matvejchikov's answer, a good solution is to add udev rules to do what you want with the device. 就像Ilya Matvejchikov的回答一样,一个好的解决方案就是添加udev规则来做你想要的设备。 Like you, I was having a similar problem. 和你一样,我遇到了类似的问题。 I had a UPS on a USB-to-multi-serial adapter and occasionally the system would switch around the /dev/tty numbers. 我在USB到多串口适配器上安装了UPS,偶尔系统会切换/ dev / tty号码。

My solution was to create a rule to match the type of device by driver and port, then create a symbolic link to the port to which my UPS was attached. 我的解决方案是创建一个规则,通过驱动程序和端口匹配设备类型,然后创建一个指向我的UPS所连接端口的符号链接。 I used NUT to monitor the UPS, which was always plugged into the same physical port. 我用NUT来监控UPS,它总是插在同一个物理端口上。

# File contents of /etc/udev/rules.d/75-nut-ups.rules
# Create /dev/nut-ups0 to use as a persistent serial device that can be used
# reliably by nut to communicate with a UPS attached to the system.
# The UPS is attached to the first port of a MosSemiconductor dual USB
# serial adapter.
KERNELS=="ttyUSB*", SUBSYSTEMS=="usb-serial", DRIVERS=="moschip7720", ATTRS{port_number}=="0", SYMLINK+="nut-ups0"

Now I configure NUT to always use a constant /dev/nut-ups0, as the serial port and the rule takes care of mapping properly when the usb-serial device is recognized. 现在我将NUT配置为始终使用常量/ dev / nut-ups0,因为串行端口和规则在识别usb-serial设备时会正确映射。

You can use the lsusb command to find out the actual device name to use in the rule when it's plugged in. 您可以使用lsusb命令查找插入规则时要在规则中使用的实际设备名称。

usb-devices可以获取端口号和总线/ dev枚举。

I too was searching this topic for a way to find which physical USB device was assigned/connected to a logical /dev device name. 我也在搜索这个主题,以找到分配/连接到逻辑/ dev设备名称的物理USB设备的方法。 So, after some trial and error, this is what worked best for me: 所以,经过一些反复试验,这对我来说最有用:

See what logical ttyUSBx devices exist (where x is 0, 1, 2...): 查看存在哪些逻辑ttyUSBx设备(其中x为0,1,2 ......):

$ ls /dev

Show bus and device numbers for all usb-serial adapters: 显示所有USB串行适配器的总线和设备编号:

$ lsusb 

Finally, use: 最后,使用:

$ udevadm info --name=ttyUSBx --attribute-walk | grep num  

Now inspect the udevadm output to match the logical device name to the actual physical device. 现在检查udevadm输出以使逻辑设备名称与实际物理设备匹配。 Here my listing when I did it: 我这样做的时候是我的上市:

$ lsusb
Bus 002 Device 005: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial     (UART) IC
Bus 002 Device 004: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
Bus 002 Device 002: ID 80ee:0021  
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

$ udevadm info --name=ttyUSB0 --attribute-walk | grep num
    ATTRS{port_number}=="0"
    ATTRS{urbnum}=="812"
    ATTRS{busnum}=="2"
    ATTRS{devnum}=="5"
    ATTRS{urbnum}=="115"
    ATTRS{busnum}=="2"
    ATTRS{devnum}=="1"
    ATTRS{numa_node}=="-1"

$ udevadm info --name=ttyUSB1 --attribute-walk | grep num
    ATTRS{port_number}=="0"
    ATTRS{urbnum}=="465"
    ATTRS{busnum}=="2"
    ATTRS{devnum}=="4"
    ATTRS{urbnum}=="115"
    ATTRS{busnum}=="2"
    ATTRS{devnum}=="1"
    ATTRS{numa_node}=="-1"

So, in my case, ttyUSB0 is associated with the device on bus2, device5, which is the Future Technology Devices International USB to Serial Adapter; 因此,在我的情况下,ttyUSB0与bus2上的设备相关联,即device5,即Future Technology Devices International USB转串口适配器; and likewise, ttyUSB1 is associated with the device on bus2, device4, which is the Prolific Technology, Inc. USB to Serial adapter. 同样,ttyUSB1与bus2,device4上的设备相关联,这是Prolific Technology,Inc。的USB转串口适配器。

And as has been pointed out, the command: 正如已经指出的那样,命令:

$ usb-devices

Will get you the same info in a one-line manner. 将以一条线的方式为您提供相同的信息。 I thought I'd post the details that helped me learn how the stuff worked behind the scenes... 我想我会发布一些细节,帮助我了解幕后的工作原理......

Hope that was helpful :) 希望有帮助:)

The devices all have the same serial numbers [..] 这些设备都具有相同的序列号[..]

The usb-parse-devpath.pm addresses this by using the bus and port id of the adapter. usb-parse-devpath.pm通过使用适配器的总线和端口ID来解决这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM