Как идентифицировать несколько последовательных USB-адаптеров в Ubuntu 10.1

Я читаю данные с нескольких идентичных последовательных USB-адаптеров под Ubuntu 10.1.

Иногда их путь /dev/tty меняется (например, если при запуске подключаются другие USB-устройства).

Мне нужен способ многократного обращения к одному и тому же адаптеру через любые такие изменения.

По словам udevadm, все устройства имеют одинаковые серийные номера.

Я думаю, что наиболее вероятным вариантом является определение адаптера, к какому порту он подключен (они не перемещаются).

Я могу найти всевозможные интересные пути /dev, которые могут работать, но, несмотря на все обсуждения udev в Интернете, я не могу найти окончательного утверждения о том, являются ли некоторые из этих путей статическими, если устройство подключено к статическому порту.


person user589888    schedule 25.01.2011    source источник
comment
Я нашел этот ответ суперпользователя очень полезным: superuser.com/a/536648/27510   -  person ergosys    schedule 11.08.2013


Ответы (7)


Есть решение. Лучше поздно, чем никогда ;)

Используйте следующее правило udev для сопоставления /dev/ttyUSB{?} устройств со ссылкой /dev/usb-ports/%bus_id-%port_id.

Вот мой /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"

И скрипт 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;
    }
}

Как видите, это помогает нам создавать именованные ссылки на /dev/ttyUSB{?} устройства и размещать их на /dev/usb-ports в следующем формате: bus_id-port_id.

Например, следующая команда дает мне следующее:

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

Итак, bus_id это 3, а port_id это 1 и теперь у меня есть следующее в моем /dev/usb-ports:

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

С Уважением.

person Ilya Matveychikov    schedule 11.05.2011
comment
Я обнаружил, что здесь полезнее заменить print $items[$i + 1] на print $items[$i + 2]; так как оба USB-порта на передней панели моего компьютера, казалось, отображались на «1-1» под первым! - person James Muscat; 09.11.2012
comment
@JamesMuscat: Спасибо за ответ. - person Ilya Matveychikov; 09.11.2012
comment
Поговорим о сверхинжиниринге! ACTION=="add", KERNEL=="ttyUSB[0-9]*", SYMLINK+="usb-ports/tty-%s{../busnum}-%s{../devpath}" делает то же самое. - person Alex P.; 09.01.2017

Как и в ответе Ильи Матвейчикова, хорошим решением является добавление правил udev, чтобы делать с устройством то, что вы хотите. Как и у вас, у меня была похожая проблема. У меня был ИБП на адаптере USB-to-multi-serial, и иногда система переключалась между номерами /dev/tty.

Мое решение состояло в том, чтобы создать правило для сопоставления типа устройства по драйверу и порту, а затем создать символическую ссылку на порт, к которому был подключен мой ИБП. Я использовал NUT для мониторинга ИБП, который всегда был подключен к одному и тому же физическому порту.

# 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"

Теперь я настраиваю NUT так, чтобы он всегда использовал константу /dev/nut-ups0, так как последовательный порт и правило заботятся о правильном отображении, когда устройство usb-serial распознается.

Вы можете использовать команду lsusb, чтобы узнать фактическое имя устройства, которое будет использоваться в правиле, когда оно подключено.

person Suncat2000    schedule 02.04.2012

Посмотрите с помощью $ udevadm info -n /dev/ttyUSB0 -a, к какому порту подключено ваше USB-устройство. Переменная KERNELS одного из родительских устройств должна иметь вид KERNELS=="1-1.2:1.0".

Создайте правило udev:

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

и запустить udev

$ udevadm trigger
person mickeyrourkeske    schedule 23.07.2013

У меня есть много USB-последовательных устройств с каждым множеством портов, и решения, упомянутые выше, не совсем помогли мне.

USB "KERNEL" в моем случае не хватило, но номер порта я нашел.

Я понимаю, что то, что я сейчас предлагаю, можно счесть безумным хаком, но это работает для меня..
на данный момент..

На самом деле мне было бы приятно увидеть более элегантное предложение, которое сделает что-то подобное.

Итак... На основании предыдущей формы ответа Ильи Матвейчикова

Файл: /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"

И файл: /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"

Результат выглядит примерно так:

# 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
person Nicolas Tremblay    schedule 06.01.2015

usb-devices может дать вам номер порта и перечисление bus/dev.

person richmb    schedule 24.09.2013

Я тоже искал в этой теме способ узнать, какое физическое USB-устройство было назначено/подключено к логическому имени устройства /dev. Итак, после некоторых проб и ошибок, это то, что сработало для меня лучше всего:

Посмотрите, какие логические устройства ttyUSBx существуют (где x равно 0, 1, 2...):

$ ls /dev

Показать номера шин и устройств для всех адаптеров usb-serial:

$ lsusb 

Наконец, используйте:

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

Теперь проверьте выходные данные udevadm, чтобы сопоставить имя логического устройства с реальным физическим устройством. Вот мой список, когда я это сделал:

$ 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"

Итак, в моем случае ttyUSB0 связан с устройством на шине 2, устройство 5, которое является адаптером USB-последовательный порт Future Technology Devices International; и аналогично, ttyUSB1 связан с устройством на шине2, устройство4, которое является адаптером Prolific Technology, Inc. USB to Serial.

И, как было указано, команда:

$ usb-devices

Вы получите ту же информацию в одну строку. Я решил опубликовать подробности, которые помогли мне узнать, как все работает за кулисами...

Надеюсь, это было полезно :)

person GOTIL    schedule 27.12.2013

Все устройства имеют одинаковые серийные номера [...]

Usb-parse-devpath.pm решает эту проблему, используя идентификатор шины и порта адаптера.

person Turbo J    schedule 28.01.2011