Как привязать USB-устройство под статическим именем?

44

У меня есть Arduino, который иногда связан, /dev/ttyUSB0а иногда и /dev/ttyUSB1делает мой сценарий неудачным.

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

Как мне этого добиться?

k0pernikus
источник
4
Просто напишите простое правило udev, которое назначит symlink / dev / arduino правильному устройству по его VID и PID.
Eddy_Em
Проверьте arch-wiki: wiki.archlinux.org/index.php/Udev#Writing_udev_rules
uzsolt
1
После того, как вы изменили правила, смотрите Как перезагрузить правила udev без перезагрузки?
Жиль "ТАК - перестань быть злым"

Ответы:

42

Как и предполагалось, вы можете добавить некоторые правила udev. Я отредактировал, /etc/udev/rules.d/10-local.rulesчтобы содержать:

ACTION=="add", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="my_uart"

Вы можете проверить переменные вашего устройства, запустив

udevadm info -a -p  $(udevadm info -q path -n /dev/ttyUSB0)

Существует более подробное руководство, которое вы можете прочитать на http://www.reactivation.net/writing_udev_rules.html.

Котте
источник
Работал как шарм. Один вопрос: как выйти udevam? И важно отметить, что my_uartсоздает символическую ссылку под /dev/my_uart. Я впервые написал /dev/arduinoв первый раз, и это не удалось, пока arduinoдостаточно.
k0pernikus
udevadmдолжен выйти сам, когда это будет сделано.
Котте
Затем по какой-то неизвестной причине он заморозил сеанс терминала для моего Raspberry Pi при создании отчета.
k0pernikus
35

Синтаксис правила выше может работать на некоторых дистрибутивах, но не работает на моем (Raspbian). Поскольку я не нашел ни одного документа, объясняющего все входы и выходы, я написал свой собственный, который можно найти здесь . Вот к чему это сводится.
1. узнать что есть на ttyUSB:

dmesg | grep ttyUSB  

2. перечислите все атрибуты устройства:

udevadm info --name=/dev/ttyUSBx --attribute-walk

(с номером вашего устройства вместо х, конечно). Выберите уникальный набор идентификаторов, например, idVendor + idProduct. Вам также может понадобиться SerialNumber, если у вас есть несколько устройств с одинаковыми idVendor и idProduct. Серийные номера должны быть уникальными для каждого устройства.
3. Создайте файл /etc/udev/rules.d/99-usb-serial.rulesс такой строкой:

SUBSYSTEM=="tty", ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678", SYMLINK+="your_device_name" 

(при условии, что вам не нужен серийный номер там, и, конечно, с номерами для idVendor и idProduct, которые вы нашли в шаге 2.
4. Загрузите новое правило:

sudo udevadm trigger

5. Проверьте, что случилось:

ls -l /dev/your_device_name  

покажет, на какой номер ttyUSB пошла символическая ссылка. Если это так /dev/ttyUSB1, то проверьте, кому это принадлежит и к какой группе оно принадлежит:

ls -l /dev/ttyUSB1   

Тогда просто для удовольствия:

udevadm test -a -p  $(udevadm info -q path -n /dev/your_device_name)
RolfBly
источник
Так есть ли решение, если idVendorи idProductточно так же? (два датчика подключены к идентичным моделям USB для модулей UART)
Стивен Лу
@StevenLu Да, см. Шаг 2, выполните udevadm info --name=/dev/ttyUSB1 --attribute-walkдля обоих устройств и найдите серийные номера, они должны быть уникальными для каждого устройства. Если у ваших датчиков нет серийного номера, можете ли вы указать, какие они есть?
RolfBly
это здорово, я сообщу, когда попробую это
Стивен Лу
У моих ключей USB к UART за 2 доллара есть серийный номер 0001. Не могу сказать, что я удивлен. Похоже, мне нужно идентифицировать датчики на основе их протокола вывода.
Стивен Лу
@ StevenLu Неудача. Конвертеры FTDI USB-UART имеют уникальный серийный номер AFAIK. Несколько лишних баксов, но меньше времени на разработку.
RolfBly
9

Проблема с несколькими идентичными USB-устройствами

У меня есть Rasperry Pi с четырьмя камерами. Я принимаю пикс с fswebcamкоторой идентифицирует камеры , как /dev/video0.. video3. Иногда камера video0, vide02, video4и , video6но мы можем забыть о том, что на данный момент.

Мне нужен постоянный идентификатор для идентификации номера камеры, чтобы, например video0, всегда была одна и та же камера, потому что я подписываю снимки. К сожалению, это не происходит надежно - при загрузке камеры перечисляются как video0... video3но не всегда одинаково.

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

Решение этой проблемы включает в себя правила udev, но там также есть много рыболовных крючков.

Если вы выполните команду

udevadm info –attribute-walk –path=/dev/video0

вы получаете разметку выходных данных, но выдающиеся биты

KERNEL=”video0”, SUBSYSTEM=”video4linux” and KERNELS=”1:1.2.4:1.0”.

Бит KERNELS - это порт USB-концентратора. С четырьмя камерами их четыре - они не меняются при перезагрузке, но video{x}связанные с портом могут измениться.

Поэтому нам нужно правило udev для привязки номера видео к порту USB-концентратора - что-то вроде:

KERNEL==”video0”,SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0”,SYMLINK+=”camera0” 

Выглядит просто - доступ к камере с

fswebcam –d  $realpath /dev/camera0

За исключением того, что это не работает - если вы поместите это в правило udev, и система выделит video0 (при загрузке) для другого порта, правило udev игнорируется. Символьная ссылка в /dev/camera0основном говорит no such device. Квадратная.

Мы хотим связать символическую ссылку с адресом USB-концентратора, а не с video{x}номером. Потребовалась программа на Python.

Первый шаг должен был бежать

fswebcam –d /dev/video${x}  tst.jpg

для xмежду 1 и 8. Существование tst.jpgпосле каждого вызова идентифицирует есть ли камера на этом видео числом. Из этого сделайте список активных видео номеров. Мой опыт показывает, что это либо 0,1,2,3или 0,2,4,6для камер я использовал.

Другие могут, конечно, построить этот список, используя другой процесс.

Затем для каждого номера видео в списке запустить

udevadm info –attribute-walk –path=/dev/videox > dd

и извлечь KERNELS= lineиз dd. В результате вы получите список адресов портов USB для камер. Сортируйте этот список так, чтобы на следующем шаге вы всегда обрабатывали его в одном и том же порядке. Назовите это «список адресов».

Запустите udevadm … > ddвещь снова и создайте список, который выглядит как

KERNEL==”video0”, SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0 ”,SYMLINK+=”camerax”. Call this the “video list”.

Теперь пройдитесь по списку адресов - для каждой записи найдите соответствующую запись из списка видео. Создайте новый список, который выглядит как набор строк, таких как

KERNEL==”video0”, SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0 ”,SYMLINK+=”camera2”

Символ x (номер символической ссылки) заменяется порядковым номером в списке адресов.

Теперь у вас есть правило udev, которое работает. Символическая ссылка, привязанная к адресу концентратора USB, независимо от того, какой номер видео выделен этому порту при загрузке.

Запишите окончательный список в файл /etc/udev/rules.d/cam.rules. Запустите, udevadm triggerчтобы активировать его, и работа сделана. /dev/camera2будет одна и та же камера (порт USB) независимо от ее номера видео.

Ян Боаг
источник
Добро пожаловать на unix stackexchange. Пожалуйста, отформатируйте ваш ответ, используя уценку. Я только что сделал это для тебя. Также имейте в виду, что мы хотим, чтобы ответы были точными. Это больше похоже на запись в блоге (что не так уж и плохо), но не очень полезно сначала прочитать о подходах, которые не сработали. Вы можете отказаться от этой части.
k0pernikus
Сожалею. Я здесь новенький. Я исследовал эту проблему в течение нескольких месяцев. Я нашел, что другие борются с той же самой проблемой, и я не нашел ответ, который работал для меня. Просто чтобы я знал, где бы вы посоветовали мне опубликовать что-то подобное? Я сдержался и не включил исходники Python :-)
Ян Боаг
1

Я также смог найти уникальное устройство в /dev/serial/by-id. Я еще не пробовал перезагрузить компьютер, но файлы в этом каталоге были просто ссылками на соответствующий файл устройства ( ttyACM[0-9]) .`

Я запускаю arch linux на Raspberry Pi, но наткнулся на них, просто сделав findдля имен файлов, содержащих «Arduino». Мои программы на python работают нормально, используя эти файлы в качестве устройств для чтения / записи данных в / из моих Arduinos (пока что два на одном Pi).

huey_driver
источник
0

Просто чтобы сказать, что вышесказанное сработало для меня, а также автоматически подключило устройство после того, как я поместил запись в / etc / fstab (и он также вызывает umount после удаления флешки)

т.е.

/ И т.д. / Fstab

# See /etc/udev/rules.d/5-usb-disk.rules
/dev/backup     /vol/backup     ext4    defaults,errors=remount-ro 0       1

cat /etc/udev/rules.d/5-usb-stick.rules

#
# the next line creates a symlink to this disk drive called /dev/backup 
# i.e.
#   root:# ls -la /dev/backup 
#   lrwxrwxrwx 1 root root 3 Jul 22 19:33 /dev/backup -> sg0

# Backup usb stick - create /dev/backup
# ATTRS{model}=="Cruzer Blade    "
ACTION=="add", ATTRS{model}=="Cruzer Blade    ", SYMLINK+="backup"

# Clean up after removal  
ACTION=="remove", ATTRS{model}=="Cruzer Blade    ", RUN+="/bin/umount /vol/backup"

Итак, вставив мою флешку, я получаю:

root:# mount | grep sd
/dev/sda1 on /vol/backup type ext4 (rw,relatime,errors=remount-ro,data=ordered)
Будет
источник