Wie binde ich ein USB-Gerät unter einem statischen Namen?

43

Ich habe ein Arduino, an das manchmal /dev/ttyUSB0und manchmal etwas gebunden ist /dev/ttyUSB1, wodurch mein Skript fehlschlägt.

Ich möchte nicht alle Möglichkeiten aufzählen, wo sich mein Gerät befinden könnte, aber ich möchte lieber, dass es an einen statischen Ort gebunden wird, z /dev/arduino.

Wie erreiche ich das?

k0pernikus
quelle
4
Schreiben Sie einfach eine einfache udev-Regel, die symlink / dev / arduino anhand ihrer VID & PID der richtigen Devise zuweist.
Eddy_Em
Überprüfen Sie arch-wiki: wiki.archlinux.org/index.php/Udev#Writing_udev_rules
uzsolt
1
Nachdem Sie die Regeln geändert haben, lesen Sie Wie Sie udev-Regeln ohne Neustart neu laden?
Gilles 'SO - hör auf böse zu sein'

Antworten:

41

Wie vorgeschlagen, können Sie einige udev-Regeln hinzufügen. Ich habe das bearbeitet, /etc/udev/rules.d/10-local.rulesum Folgendes zu enthalten:

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

Sie können die Variablen Ihres Geräts überprüfen, indem Sie ausführen

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

Eine ausführlichere Anleitung finden Sie unter http://www.reactivated.net/writing_udev_rules.html

Kotte
quelle
Lief wie am Schnürchen. Eine Frage: Wie verlasse ich udevam? Und es ist wichtig zu beachten, dass my_uartder Symlink unter erstellt /dev/my_uart. Ich habe /dev/arduinodas erste Mal geschrieben und es ist fehlgeschlagen, solange arduinoes ausreicht.
k0pernikus
udevadmsollte von selbst beenden, wenn es fertig ist.
Kotte
Aus einem unbekannten Grund hat es dann die Terminalsitzung für meinen Raspberry Pi eingefroren, während der Bericht erstellt wurde.
k0pernikus
35

Die obige Regelsyntax funktioniert möglicherweise auf einigen Distributionen, auf meinen (Raspbian) jedoch nicht. Da ich nie ein einziges Dokument gefunden habe, das alle Einzelheiten erklärt, habe ich mein eigenes geschrieben, das hier zu finden ist . Darauf kommt es an.
1. Finde heraus, was auf ttyUSB läuft:

dmesg | grep ttyUSB  

2. Alle Attribute des Geräts auflisten:

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

(natürlich mit Ihrer (n) Gerätenummer (n) anstelle von x). Wählen Sie einen eindeutigen Identifizierungssatz aus, z. B. idVendor + idProduct. Möglicherweise benötigen Sie auch die Seriennummer, wenn Sie mehr als ein Gerät mit demselben idVendor und demselben idProduct haben. Seriennummern sollten für jedes Gerät eindeutig sein.
3. Erstellen Sie eine Datei /etc/udev/rules.d/99-usb-serial.rulesmit der folgenden Zeile:

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

(vorausgesetzt, Sie benötigen dort keine Seriennummer und natürlich die Nummern für idVendor und idProduct, die Sie in Schritt 2 gefunden haben.
4. Laden Sie die neue Regel:

sudo udevadm trigger

5. Überprüfen Sie, was passiert ist:

ls -l /dev/your_device_name  

Zeigt an, zu welcher ttyUSB-Nummer der Symlink gegangen ist. Wenn ja /dev/ttyUSB1, überprüfen Sie, wem das gehört und zu welcher Gruppe es gehört:

ls -l /dev/ttyUSB1   

Dann nur zum Spaß:

udevadm test -a -p  $(udevadm info -q path -n /dev/your_device_name)
RolfBly
quelle
Gibt es also eine Lösung, wenn die idVendorund idProductgenau gleich sind? (zwei Sensoren an identischen USB-UART-Modulen)
Steven Lu
@StevenLu Ja, siehe Schritt 2, udevadm info --name=/dev/ttyUSB1 --attribute-walkfür beide Geräte ausführen und nach Seriennummern suchen. Sie sollten für jedes Gerät eindeutig sein. Wenn Ihre Sensoren keine Seriennummer haben, können Sie angeben, was sie sind?
RolfBly
das ist großartig, ich melde mich wieder, wenn ich das ausprobiere
Steven Lu
Meine USB-zu-UART-Dongles für 2 US-Dollar haben die Seriennummer 0001. Ich bin nicht überrascht. Sieht so aus, als müsste ich die Sensoren anhand ihres Ausgabeprotokolls identifizieren.
Steven Lu
@StevenLu Pech. FTDI-USB-UART-Konverter haben eine eindeutige Seriennummer, AFAIK. Ein paar Extra-Dollars, aber weniger Zeit zum Entwickeln.
RolfBly
9

Das Problem mit mehreren identischen USB-Geräten

Ich habe einen Rasperry Pi mit vier Kameras. Ich nehme pix mit fswebcamdenen identifiziert die Kameras wie /dev/video0.. video3. Manchmal ist die Kamera video0, vide02, video4und video6doch können wir darüber jetzt vergessen.

Ich benötige eine persistente ID, um eine Kameranummer zu identifizieren, damit z. B. video0immer die gleiche Kamera ist, da ich die Bilder beschrifte. Leider passiert dies nicht zuverlässig - beim Booten werden die Kameras mit video0.. aufgelistet, video3aber nicht immer auf die gleiche Weise.

Die Kameras haben alle die gleiche ID und Seriennummer.

Die Lösung für dieses Problem beinhaltet udev-Regeln, aber es gibt auch viele Angelhaken.

Wenn Sie den Befehl ausgeben

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

Sie erhalten einen Estrich der Ausgabe, aber die hervorstechenden Teile sind

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

Das KERNELS-Bit ist ein USB-Hub-Port. Bei vier Kameras gibt es vier davon - sie ändern sich nicht beim Neustart, aber der video{x}mit einem Port verknüpfte kann sich ändern.

Wir brauchen also eine udev-Regel, um eine Videonummer an einen USB-Hub-Port zu binden - so etwas wie:

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

Sieht einfach aus - greifen Sie mit auf die Kamera zu

fswebcam –d  $realpath /dev/camera0

Außer es funktioniert nicht - wenn Sie dies in eine udev-Regel einfügen und das System video0 (beim Booten) einem anderen Port zugewiesen hat, wird die udev-Regel ignoriert. Der Symlink /dev/camera0sagt im Grunde no such device. Platz eins.

Wir möchten einen Symlink an eine USB-Hub-Adresse binden, nicht an eine video{x}Nummer. Es dauerte ein Python-Programm.

Der erste Schritt war zu rennen

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

für xzwischen 1 und 8. Das Vorhandensein tst.jpgnach jedem Anruf gibt an, ob sich auf dieser Videonummer eine Kamera befindet. Daraus machen Sie eine Liste der aktiven Videonummern. Meine Erfahrung war, dass es entweder 0,1,2,3oder 0,2,4,6für Kameras ist, die ich benutzt habe.

Andere können diese Liste natürlich mit einem anderen Verfahren erstellen.

Dann für jede Videonummer in der Liste ausführen

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

und extrahiere die KERNELS= lineaus dd. Nach diesem Vorgang erhalten Sie eine Liste der USB-Anschlussadressen für die Kameras. Sortieren Sie diese Liste so, dass Sie sie im nächsten Schritt immer in der gleichen Reihenfolge bearbeiten. Nennen Sie dies die "Adressliste".

Führen Sie das udevadm … > ddDing erneut aus und erstellen Sie eine Liste, die aussieht

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

Blättern Sie nun durch die Adressliste - für jeden Eintrag finden Sie den entsprechenden Eintrag aus der Videoliste. Erstellen Sie eine neue Liste, die wie eine Sammlung von Zeilen aussieht

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

Das x (Symlink-Nummer) wird durch die laufende Nummer in der Adressliste ersetzt.

Jetzt haben Sie eine udev-Regel, die funktioniert. Ein Symlink, der an eine USB-Hub-Adresse gebunden ist, unabhängig davon, welche Videonummer diesem Port beim Start zugewiesen wird.

Schreiben Sie die endgültige Liste in eine Datei /etc/udev/rules.d/cam.rules. Führen udevadm triggerSie den Befehl aus , um es zu aktivieren, und der Auftrag ist abgeschlossen. /dev/camera2wird die gleiche Kamera (USB-Anschluss) sein, unabhängig von seiner Videonummer.

Ian Boag
quelle
Willkommen bei Unix StackExchange. Bitte formatieren Sie Ihre Antwort mit Markdown. Ich habe es nur für dich getan. Denken Sie auch daran, dass die Antworten auf den Punkt gebracht werden sollen. Das liest sich eher wie ein Blogeintrag (was nicht ganz schlecht ist), aber es ist nicht so hilfreich, zuerst über Ansätze zu lesen, die nicht funktionierten. Sie können diesen Teil verschrotten.
k0pernikus
Es tut uns leid. Ich bin neu hier. Ich habe dieses Problem monatelang untersucht. Ich fand andere, die mit dem gleichen Problem zu kämpfen hatten, und fand keine Antwort, die für mich funktionierte. Nur damit ich weiß, wo würdest du raten, dass ich so etwas poste? Ich habe mich zurückgehalten und die Python-Quelle nicht aufgenommen :-)
Ian Boag
1

Ich konnte auch ein einzigartiges Gerät in finden /dev/serial/by-id. Ich habe noch keinen Neustart versucht, aber die Dateien in diesem Verzeichnis waren nur Links zur entsprechenden Gerätedatei ( ttyACM[0-9]) .`

Ich verwende Arch Linux auf Raspberry Pi, aber ich bin über sie gestolpert, indem ich nur findnach Dateinamen gesucht habe, die "Arduino" enthalten. Meine Python-Programme funktionieren einwandfrei, wenn sie diese Dateien als Geräte zum Lesen / Schreiben von Daten auf / von meinen Arduinos verwenden (bisher zwei auf einem einzigen Pi).

huey_driver
quelle
0

Um nur zu sagen, dass das oben Genannte für mich funktioniert hat und das Gerät auch für mich automatisch gemountet wurde, nachdem ich einen Eintrag in / etc / fstab vorgenommen hatte (und es ruft nach dem Entfernen des Sticks auch umount auf).

dh

/ etc / 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"

Nachdem ich meinen USB-Stick eingesteckt habe, erhalte ich:

root:# mount | grep sd
/dev/sda1 on /vol/backup type ext4 (rw,relatime,errors=remount-ro,data=ordered)
Wille
quelle