RasPi: Feste USB-Schnittstellen-Namen durch udev-Regeln

USB-Geräte ändern am Raspberry nach jedem Booten oder Einstecken den Schnittstellen-Namen. Das bringt Software oft durcheinander, läßt sich aber verhindern.

In Pocket speichern vorlesen Druckansicht 1 Kommentar lesen
Feste USB-Schnittstellen-Namen durch udev-Regeln
Lesezeit: 5 Min.
Von
  • Heinz Behling
Inhaltsverzeichnis

Zahlreiche Programme, etwa zur Steuerung von Lasercuttern, 3D-Druckern oder Mediaplayern, erfordern bei ihrer Konfiguration die Angabe der Schnittstellenbezeichnung der an USB-Buchsen angeschlossenen Geräte. Lästig dabei: Nach einem Neustart des RasPis werden diese Bezeichnungen neu vergeben: Wenn ein 3D-Drucker zuvor noch auf ttyUSB0 hörte, kann er nun vielleicht ttyUSB1 sein. Klar, dass soetwas Programme durcheinander bringen kann, insbesondere, wenn zwei gleichartige Geräte (3D-Drucker Anet A8 und Creality Ender 3 mit silent board)) angeschlossen sind und verwechselt werden.

Es gibt aber einen Mechanismus, mit dem man das Betriebssystem zwingen kann, zusätzlich zu diesen mehr oder weniger zufälligen Bezeichnungen an die jeweiligen Geräte fest gebundene Schnittstellennamen zu vergeben – und zwar mit udev-Regeln.

Das Hintergrundprogramm udev verwaltet dynamisch alle Gerätedateien im Verzeichnis /dev, also auch die USB-Geräte. Bei jedem Bootvorgang oder dem An- beziehungsweise Abstecken eines Geräts vergibt es normalerweise automatisch die Bezeichnungen, kann aber durch Regeln (Textdateien) im Verzeichnis /etc/udev/rules.d/ gezwungen werden, bei bestimmten Geräten den wechselnden Bezeichnungen zusätzlich feste Namen in Form von symbolischen Links zuzuordnen. So hört dann ein 3D-Drucker beispielsweise immer auf ttyANET, obwohl er mal die Schnittstelle ttyUSB0, und dann wieder ttyUSB1 erhält.

Im Verzeichnis /dev findet sich für jedes an den RasPi angeschlossenes Gerät eine Datei. Dessen Name entspricht der Schnittstellenbezeichnung.

Dazu muss udev das jeweilige Gerät aber individuell identifizieren können. Deshalb enthalten udev-Regeln immer mindestens eine Bedingung, die eine charakteristische, vom Gerät ans Betriebssystem gemeldete Eigenschaft enthält, und eine Aktion, die bei Erfüllung der Bedingung ausgeführt wird.

Am Beispiel zweier am RasPi angeschlossener 3D-Drucker zeigen wir, wie man diese Geräteeigenschaften herausfindet und eine entsprechende udev-Regel schreibt. Sie können das aber auch für alle anderen USB-Geräte anwenden.

Für diese Aufgabe gibt es in Raspbian (Linux) schon ein geeignetes Programm: udevadm, das Sie in einem Terminal-Fenster direkt am RasPi oder via ssh starten können.

Zunächst einmal muss man jedoch die aktuelle Schnittstellenbezeichnung der Drucker herausfinden. Dazu startet man den Raspi zunächst ohne Verbindung zu den Printern. Im Verzeichnis /dev (Anzeige mit dir /dev/tty*) sollten dann keine Schnittstellen ttyUSBx vorhanden sein. Schließen Sie nun den ersten Drucker an, zum Beispiel einen Anet A8. Daraufhin erscheint in /dev nun der Eintrag ttyUSB0. Schließen Sie nun auch den zweiten Printer an (beispielsweise einen Creality Ender 3) und es erscheint zusätzlich auch ttyUSB1. Jetzt wissen Sie, welche Schnittstelle aktuell zu welchem Drucker gehört und Sie können sich die Eigenschaften der Drucker anzeigen lassen. Mit

udevadm info -a -n /dev/ttyUSB0

erhalten Sie eine lange Liste von Eigenschaften des Anet.

Die Eigenschaften des ersten Druckers

Wiederholen Sie das mit dem zweiten Gerät durch

udevadm info -a -n /dev/ttyUSB1

Auch diese Liste ist ähnlich lang. (Tipp: Wenn Sie mit zwei nebeneinanderstehenden Konsolenfenstern arbeiten und in jedem die Eigenschaften eines Geräts anzeigen, ist die Arbeit einfacher).

Scrollen Sie an den Anfang der Listen. Die Einträge sind geordnet nach devices. Je weiter oben eine Eigenschaft steht, umso näher ist sie dem Gerät.

In einer udev-Regel müssen wir ein Subsystem angeben, in dem das Gerät vorkommt. In unserem Beispiel ist das

SUBSYSTEM=="tty"

Suchen Sie anschließend von oben beginnend nach Einträgen, die charakteristisch für die Geräte sind und in denen sie sich von anderen unterscheiden. Häufig gibt es dazu den Tipp, die Kennung des Geräteherstellers ATTRS{idVendor} und des Produkts ATTRS{idProduct} zu verwenden. Das allein wird in diesem Beispiel aber nicht genügen, denn diese Angaben sind bei beiden Geräten gleich. Warum eigentlich, wo sich die Drucker doch so unterscheiden? Das liegt daran, dass beide Drucker auf einer Arduino-kompatiblen Steuerelektronik beruhen. Und daher sind diese beiden Kennungen gleich. Trotzdem können wir auch diese Angaben in unsere Regel einsetzen, um sie von eventuell anderen USB-Geräten zu unterscheiden. Das allein reicht aber nicht.

Wir brauchen mindestens eine individuelle Eigenschaft. Beide Drucker unterscheiden sich zum Beispiel durch die Eintrage ATTRS{devpath}

Drucker 1: Vendor- und Product-Id sind dieselben wie beim zweiten. Aber der devpath unterscheidet sich.

Beim zweiten Drucker lautet der devpath 1.1.3.

Damit haben wir fast alles, was wir brauchen. Jetzt müssen wir uns nur noch die Schnittstellennamen ausdenken, die wir den Druckern fest zuordnen möchten, zum Beispiel ttyANET und ttyENDER, und können nun die Regeln schreiben. Das geschieht ebenfalls im Konsolenfenster mit Root-Rechten, also mit

sudo nano /etc/udev/rules.d/99-usb.rules

Die erste Zeile der Regel lautet dann

SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", ATTRS{devpath}=="1.2", SYMLINK+="ttyANET"

Deie zweite entsprechend

SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", ATTRS{devpath}=="1.1.3", SYMLINK+="ttyENDER"

Achten Sie unbedingt auf Groß- und Kleinschreibung. Die Schreibweise muss exakt den zuvor in den Listen angezeigten Schreibweisen entsprechen. Achten Sie auch auf die geschweiften Klammern. Speichern Sie die Datei und rebooten den RasPi. Lassen Sie sich dann die Schnittstellen anzeigen mit

dir /dev/tty*

Nun sehen Sie die beiden neuen Schnittstellen, die jetzt den Druckern fest zugeordnet sind.

Die beiden neuen Schnittstellen ttyANET und ttyEnder sind nun unveränderlich.

(hgb)