Ich habe ein Problem: Ich habe einen Aufbau aus meheren USB Geräten. Diese sind an einem USB Hub angeschlossen. An Port 1 wird ein /dev/ttyACM0 erkannt. Da es eine Seriennummer hat, kann ich mit pySerial über alle erkannten Ports enumerieren und die Seriennummer vergleichen. -> Kein Problem hier. An Port 2 habe ich ein /dev/ttyUSB0. Leider ohne Seriennummer. Da jenachdem was ich noch angeschlossen habe, sich die Namen ändern hier meine Frage: Wie komme ich am besten unter Linux und Python von /dev/ACM0 (den ich sicher finden kann) auf /dev/ttyUSB0 (der ein Port weiter eingesteckt ist)?
B. W. schrieb: > An Port 2 habe ich ein /dev/ttyUSB0. Leider ohne Seriennummer. > > Da jenachdem was ich noch angeschlossen habe, sich die Namen ändern hier > meine Frage: In ›/etc/udev/rules.d‹ eine Regel einführen, welche auf Vid:Pid triggert und einen eigens erstellten und benannten Link in /dev hinzu fügt. Habe mir vor Äonen so etwas erstellt:
1 | # stm32 discovery board with onboard st/linkv2 |
2 | SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", \
|
3 | MODE:="0666", \ |
4 | SYMLINK+="stlinkv2_%n" |
An sich eine gute Idee, aber leider haben die CH340 irgendwie alle die selbe VID:PID. Da bleibt dann noch die unterschiedliche Enumerierung bei Boot und Hotplug...
B. W. schrieb: > aber leider haben die CH340 irgendwie alle die > selbe VID:PID. Ahhh, diese Information gab's gerade noch nicht. Gleiche VID, gleiche PID, keine SERIAL. Device ──▶ /dev/null
Und wenn du mehrere Devices hast, die sich nicht durch VID/PID oder Seriennummer unterscheiden, kannst du die udev-Rule auch nach Device-Pfad unterscheiden, als z.B. je nachdem in welchen Port vom USB-Hub die gesteckt sind:
1 | ... ENV{ID_PATH}=="pci-0000:01:00.0-usb-0:2.3:1.0",SYMLINK+="ttyUSB_HUB_PORT3"...
|
Im ENV{ID_PATH} - Match gehen Wildcards, Wenn es egal sein soll an
welchem Mainboard-Port der Hub steckt, kannst du das entsprechend
raus-'*'-en.
Und wenn dir eigene UDEV-Rules suspekt sind, schau mal in die
unterordner von /dev/serial, die Default-UDEV-Regeln legen da schon
einige Symlinks an, die dir reichen könnten.
Εrnst B. schrieb: > Und wenn du mehrere Devices hast, die sich nicht durch VID/PID > oder > Seriennummer unterscheiden, kannst du die udev-Rule auch nach > Device-Pfad unterscheiden, Stimmt. Aber dann fliegt er blind, da die Geräte nicht unterscheidbar sind und nun ausschließlich von der Steckposition abhängen. Da braucht man große Aufkleber und blinkende Pfeile an den Hubs.
Εrnst B. schrieb: > Und wenn du mehrere Devices hast, die sich nicht durch VID/PID oder > Seriennummer unterscheiden, kannst du die udev-Rule auch nach > Device-Pfad unterscheiden, als z.B. je nachdem in welchen Port vom > USB-Hub die gesteckt sind: genau. > ENV{ID_PATH}=="pci-0000:01:00.0-usb-0:2.3:1.0",SYMLINK+="ttyUSB_HUB_PORT 3"... und um diesen ID_PATH herauszubekommen, kannst Du den udevadm-Befehl verwenden:
1 | udevadm info /dev/ttyUSB0 |
:
Bearbeitet durch User
Gerd E. schrieb: > udevadm info /dev/ttyUSB0 Hmm... mal schauen wie ich das parse...
1 | P: /devices/pci0000:00/0000:00:08.1/0000:29:00.3/usb5/5-1/5-1.1/5-1.1.2/5-1.1.2:1.0/ttyUSB1/tty/ttyUSB1 |
2 | P: /devices/pci0000:00/0000:00:08.1/0000:29:00.3/usb5/5-1/5-1.1/5-1.1.1/5-1.1.1:1.0/tty/ttyACM1 |
B. W. schrieb: > Hmm... mal schauen wie ich das parse... Schau nach der Zeile mit ID_PATH # udevadm info /dev/ttyACM1 |grep ID_PATH= E: ID_PATH=pci-0000:01:00.0-usb-0:2.3:1.0 das "E:" davor bedeutet, dass der Wert in der Rule mit ENV{} erreichbar ist.
Norbert schrieb: > Stimmt. Aber dann fliegt er blind, da die Geräte nicht unterscheidbar > sind und nun ausschließlich von der Steckposition abhängen. Ist doch in Ordnung, solange man sie nicht umsteckt. Bei manchen Aufbauten ändert sich ja nichts. Und wenn man das alles in eine Kiste steckt und außen dann SubD-Steckverbinder für irgendwelche UART-basierte Geräte (wovon ich bei der Verwendung von CH340 ausgehe) hat, kann man die SubDs einfach entsprechend bezeichnen ("labeln").
Kann man nicht die CH340 durch FTDI's ersetzen? Das würde das ganze Problem nachhaltig und sauber lösen. fchk
Rahul D. schrieb: > Ist doch in Ordnung, solange man sie nicht umsteckt. Und genau darum will ich mir keine Sorgen machen. Alles in eine Kiste stecken? Ja bitte. Rahul D. schrieb: > SubD-Steckverbinder Ich hätte da eine Handvoll Fragen... * Mach ich da am besten meine eigene Belegung oder nehme ich einen Standard? * Wie finde ich das im System wieder? * ... Frank K. schrieb: > CH340 durch FTDI's ersetzen? Ich würde jetzt nicht auf FTDI gehen da ich mit einem FT4232 schon Probleme hatte: * braucht ein EEPROM für die SN * schickt bei STOP des HW-Flows noch 2 Bytes über die Leitung Würde da dann auf den CP2102 gehen. Ist jetzt nicht schön, aber fängt an zu funktionieren:
1 | import pyudev |
2 | from pprint import pprint |
3 | import types |
4 | |
5 | def printDevice(device): |
6 | print(device) |
7 | #print(dir(device)) |
8 | |
9 | for n in dir(device): |
10 | if n.startswith("__"):
|
11 | continue |
12 | |
13 | v = getattr(device, n) |
14 | if isinstance(v, types.GeneratorType): |
15 | v = list(v) |
16 | |
17 | print(n, v) |
18 | |
19 | for k, v in device.items(): |
20 | print(f" * {k}: {v}")
|
21 | |
22 | def main(serial): |
23 | context = pyudev.Context() |
24 | device = list(context.list_devices(ID_SERIAL_SHORT=serial))[0] |
25 | hub = device.parent |
26 | |
27 | #printDevice(device) |
28 | |
29 | for port in range(1,5): |
30 | sysName = hub.sys_name + f".{port}"
|
31 | for c in hub.children: |
32 | if c.sys_name == sysName: |
33 | for sc in c.children: |
34 | #printDevice(sc) |
35 | dn = sc.get("DEVNAME")
|
36 | if dn: |
37 | print(port, dn) |
38 | |
39 | if __name__ == "__main__": |
40 | import sys |
41 | main(sys.argv[1]) |
B. W. schrieb: > Rahul D. schrieb: >> Ist doch in Ordnung, solange man sie nicht umsteckt. > > Und genau darum will ich mir keine Sorgen machen. > > Alles in eine Kiste stecken? Ja bitte. Es gibt doch zwei Möglichkeiten: Die Belegung des Busses ändert sich nicht, und man kann die Bausteine anhand des USB-Tree ansprechen. Oder: man verwendet Bausteine mit einer einzigartigen Seriennummer. > > Rahul D. schrieb: >> SubD-Steckverbinder > > Ich hätte da eine Handvoll Fragen... > * Mach ich da am besten meine eigene Belegung oder nehme ich einen > Standard? > * Wie finde ich das im System wieder? > * ... RS232 hat eine Standardbelegung je nach Steckergröße (9 oder 25 polig) und nach Geräte (DCE oder DTE). Davon gehe ich bei der Verwendung eines CH340 aus. Wenn es keine Standard-Schittstelle ist, und man sie mit was anderem (u.U. für die Schaltung gefährlichem) vertauschen kann, wäre eine eigene Belegung oder ein anderer Steckverbindertyp angebracht.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.