Hallo Foraner,
momentan schreibe ich eine Software, um über die serielle Schnittstelle
eine Hardware zu Parametrisieren. Der Compiler (PureBasic,
https://www.purebasic.com/german/) ist kein Cross-Compiler, und die
Platformen Linux und MacOS stehen mir nicht zur Verfügung. Linux werde
ich in eine VirtualBox installieren, für MacOS werde ich meine Nichte
bitten, das zu kompilieren.
Problem: Zum Einstellen der seriellen Schnittstelle durchforste ich im
Windows-Branch (Compiler-Select) einfach alle COM-Ports von 1...32 und
stelle alle Gefundenen in einer ComboBox zur Auswahl bereit. Die
Prozedur dafür ist:
Christian M. schrieb:> Kann ich bei Linux davon ausgehen, dass die Enumeration immer> "/dev/ttyUSBx" ist?
Nein. /dev/ttyACMx ist auch gängig. Bei MacOS heißen sie wiederum
anders. Letztendlich kann da jeder Treiber auch noch sein eigenes
Süppchen kochen. Ein Programm dass sich auf ein bestimmtes Muster
beschränkt, wird früher oder später Probleme bereiten. Ich würde
zusätzlich zur Drop-Down Liste auch noch eine freie Texteingabe
zulassen.
Stefan F. schrieb:> Ich würde> zusätzlich zur Drop-Down Liste auch noch eine freie Texteingabe> zulassen.
Danke! Also:
Christian M. schrieb:> ComboBox editable gemacht, dann kann der> User den Eintrag manuell machen.
Gruss Chregu
Unter Linux sind da, wie bereits angesprochen, mehrere Namen üblich.
Ich würde, wenn ich wirklich sichergehen will, dass ich alle seriellen
Schnittstellen aufliste, in /sys/class/tty gucken und alles weglassen,
was bekanntermaßen keine serielle Schnittstelle ist.
Christian M. schrieb:> Problem: Zum Einstellen der seriellen Schnittstelle durchforste ich im> Windows-Branch (Compiler-Select) einfach alle COM-Ports von 1...32 und> stelle alle Gefundenen in einer ComboBox zur Auswahl bereit.
SO macht man das eigentlich nicht. Die Win32 API stellt zwei Wege für
das Enumerieren von (beliebigen) Devices zur Verfügung:
1. cfgmgr32
2. setupapi
https://learn.microsoft.com/en-us/windows-hardware/drivers/install/enumerating-installed-device-interface-classes
Wenn Du Ports wahllos öffnest und wieder schließt, könnten das einige
Geräte übelnehmen. Über die offiziellen APIs kannst Du auch USB-Devices
durchenumerieren, nach bestimmten VID/PID/SerialNum filtern und dann
abfragen, ob und wenn ja welcher COM: dann da dran hängt. Im Netz gibts
genug Dokumentation dazu. Das hat den Vorteil, dass Du nur DEINE EIGENEN
FTDI-UARTs bekommst und nicht irgendwelche fremden Geräte, die zufällig
auch die gleichen FTDI-Bridges drin haben.
Bei Linux kannst Du entweder das sysfs durchiterieren (z.B.
/sys/bus/usb/devices für alle USB-Devices oder /sys/class/tty für alle
ttys), oder Du kannst über udev gehen.
Bei MacOS bin ich aktuell nicht im Bilde. Ich hab hier zwar einen
stehen, aber auf dem mache ich keine Entwicklung.
Dein jetziger Weg ist jedenfalls nicht im Sinne der Erfinder.
fchk
Christian M. schrieb:> Es kommen ausschliesslich FT232 zu Einsatz.
Wenn man das auch in Zukunft wörtlich nimmt und keinen extra Treiber
installiert, gibt es nur /dev/ttyUSBx; auch mit den 2-fach und 4-fach
Konvertern von FTDI.
Die Idee mit dmesg finde ich nicht schön, das ist ein Ringpuffer. Wenn
auf einem Rechner viel los ist, fehlen die ältesten Einträge irgendwann.
Konverter, die schon beim Einschalten eingesteckt waren, findet man dann
nicht. Das sicherste ist, in /dev nach ttyUSBx zu suchen. Man könnte
auch ein paar andere Verzeichnisse nehmen, aber die sind teils
bewegliche Ziele oder nicht immer vorhanden oder nicht aktuell. /dev
wird es noch lange geben und es wird direkt vom Kernel selbst in
Echtzeit aktualisiert.
/dev/ttySx sind die klassischen COM-Ports aus DOS-Zeiten. 2 bis 4 davon
tauchen auch bei modernen Boards auf und auch, wenn es die Stecker
garnicht gibt. Die würde ich direkt ignorieren.
Hmmm schrieb:> Nicht für FTDI-Chips,
Niemand hindert dich daran, per einfacher Udev-Rule alle FTDI-Ports
(oder auch nur die mit deiner Seriennummer etc.) als z.B.
/dev/ttyFTDI0…99 oder /dev/dasGerät anzulegen.
Ansonsten erleuchtet vielleicht ein Blick in die Datei
"/usr/lib/udev/rules.d/60-serial.rules" aus dem default
udev/systemd-Regelwerk:
unter /dev/serial/by-id finden sich die USB-Seriel-Ports mit sehr
aussagekräftigen Dateinamen. Da die Richtigen für deine Hardware
rauszufiltern ist einfach.
Es gibt für Linux ein Terminalprogramm "tio" für die Comsole. Dort gibt
es die Möglichkeit, die zur Verfügung stehenden Ports zu listen.
tio -L
Das Programm ist Open Source und findest du hier.
https://github.com/tio/tio
Vielleicht schaust du dort in den Source wie es dort gemacht wird. Es
funktioniert auch ;)
Εrnst B. schrieb:> Niemand hindert dich daran, per einfacher Udev-Rule alle FTDI-Ports> (oder auch nur die mit deiner Seriennummer etc.) als z.B.> /dev/ttyFTDI0…99 oder /dev/dasGerät anzulegen.
Klar, wenn es praktikabel ist, im System herumzuwursteln. Hier scheint
es ja um ein Produkt zu gehen, das auf fremden Systemen laufen soll.
Ohne Eingriffe heissen normalerweise nur CDC/ACM-Devices /dev/ttyACM*,
die mit herstellerspezifischen Treibern /dev/ttyUSB*, daher mein Einwand
bzgl. der FTDI-Chips.
900ss D. schrieb:> Es gibt für Linux ein Terminalprogramm "tio" für die Comsole. Dort gibt> es die Möglichkeit, die zur Verfügung stehenden Ports zu listen.> tio -L
Das grast unter Linux /dev/serial/by-id/* ab, unter den meisten anderen
Systemen geht es in Richtung /dev/tty*.
tty.c, list_serial_devices(), die OS-spezifischen #defines findet man ab
Zeile 61.
geht hier auf einem Win7-Rechner. Aber jetzt fangen weitere Probleme an:
Auf einem Win10-Rechner hat es den Befehl nicht gefunden. Gegoogelt:
Aha, der heisst jetzt neu
1
change port /query
Funktioniert auch auf Win7, aber auf dem Win10-Rechner ums verrecken
nicht => wieder nicht gefunden. Da dreht man doch durch!
Gruss Chregu
Harald K. schrieb:> "change" ohne weitere Parameter geht nicht?
Das habe ich natürlich als Erstes gemacht. Nein.
Gruss Chregu
Edit: Geht das nur als "Administrator"?
Christian M. schrieb:> Edit: Geht das nur als "Administrator"?
Die Fehlermeldung wäre eine andere.
Erscheint bei Dir das hier?
> Der Befehl "change" ist entweder falsch geschrieben oder> konnte nicht gefunden werden.
Harald K. schrieb:> Erscheint bei Dir das hier?>> Der Befehl "change" ist entweder falsch geschrieben oder>> konnte nicht gefunden werden.
Ja ja, genau! Aber ich habe jetzt keine Zeit mehr, mich damit
auseinander zu setzen. Ich komme erst Mitte nächster Woche wieder dazu.
Gruss Chregu
Stefan F. schrieb:> Christian M. schrieb:>> Kann ich bei Linux davon ausgehen, dass die Enumeration immer>> "/dev/ttyUSBx" ist?>> Nein. /dev/ttyACMx ist auch gängig. Bei MacOS heißen sie wiederum> anders. Letztendlich kann da jeder Treiber auch noch sein eigenes> Süppchen kochen. Ein Programm dass sich auf ein bestimmtes Muster> beschränkt, wird früher oder später Probleme bereiten. Ich würde> zusätzlich zur Drop-Down Liste auch noch eine freie Texteingabe> zulassen.
Hier ein Beispiel:
iMac $ ls -l /dev/cu.*
crw-rw-rw- 1 root wheel 0x16000007 22 Nov 06:58
/dev/cu.Bluetooth-Incoming-Port
crw-rw-rw- 1 root wheel 0x16000001 22 Nov 06:58
/dev/cu.usbserial-143340
crw-rw-rw- 1 root wheel 0x16000005 22 Nov 06:58
/dev/cu.usbserial-FTGHPOLK
crw-rw-rw- 1 root wheel 0x16000003 22 Nov 06:58
/dev/cu.usbserial-FTH9L0T7
iMac $
Das sind 2 FTDI, ein Prolific 2303 und ein Bluetooth-Device (das aber
nicht aktiv ist). Andere Devices melden sich manchmal mit -000000...
D.h. man könnte auf "/dev/ci.usbserial-FT*" filtern wenn man nur die
FTDIs haben will.
Wenn man keinen ollen Serial-Port sondern native USB-Geräte verwenden
würde, könnte man unter allen Plattformen mit libusb sehr einfach alle
angeschlossenen Geräte finden...
Niklas G. schrieb:> Wenn man keinen ollen Serial-Port sondern native USB-Geräte verwenden> würde, könnte man unter allen Plattformen mit libusb sehr einfach alle> angeschlossenen Geräte finden...
So ein FTDI-Konverter ist doch ein "native USB-Gerät"? Und genau solche
will man finden.
Bauform B. schrieb:> So ein FTDI-Konverter ist doch ein "native USB-Gerät"?
Nach der Logik sind alle USB-Geräte "nativ". Ich meinte damit ein
eigenes anwendungsspezifisches USB-Protokoll zu definieren, statt einen
Serial-Port zu emulieren. Problem Nr. 1 ist ja offensichtlich dass aus
PC-Sicht alle USB-Serial-Ports gleich sind und dem FTDI nicht anzusehen
ist was für ein serielles Protokoll da jetzt drüber gehen soll; bei
spezifischen USB-Protokollen kann man das Gerät eindeutig
identifizieren.
Christian M. schrieb:> Ja ja, genau!
Dann ist Dein Windows 10 merkwürdig. Alle Windows-Versionen, die ich
hier im Büro habe (beginnend bei 2012 Server bis hin zum 2022 Server
sowie Windows 10 und Windows 11) kennen "change".
Niklas G. schrieb:> Problem Nr. 1 ist ja offensichtlich dass aus> PC-Sicht alle USB-Serial-Ports gleich sind
Sind sie das? Jeder wird mit dem dafür vorgesehenen Treiber
angesprochen, FTDI mit FTDI-Treibern, WCH mit WCH-Treibern, Prolific mit
Prolific-Treibern. Der generischen CDC-Treiber kommt nur selten zum
Einsatz, denn die meisten USB-Seriell-Bridges sind keine CDC-Geräte.
Harald K. schrieb:> Jeder wird mit dem dafür vorgesehenen Treiber> angesprochen, FTDI mit FTDI-Treibern, WCH mit WCH-Treibern, Prolific mit> Prolific-Treibern.
Aber alle erzeugen einen generischen COMx-Port. Aus Anwendungssicht gibt
es da keinen Unterschied außer eben mit speziellen APIs. Aber auch daran
kann man nur den Hersteller des Adapters identifizieren, nicht das
tatsächliche Gerät. Zu wissen ob es ein Prolific, FTDI, ... -IC ist
hilft kaum dabei zu entscheiden ob da ein Arduino, STK500, Analogmodem
oder GPS-Tracker dran hängt.
Wobei: Eigentlich ist die CDC-ACM-Klasse nur dafür gemacht,
Analog-Modems mit AT-Command-Set anzusteuern, somit sollten alle
CDC-ACM-COM-Ports solchen Modems entsprechen. "Zufällig" erlauben
alle(?) Betriebssysteme die Verwendung von solchen Ports auch mit
anderen Geräten und anderen Anwendungen als Dial-Up. Daher werden wohl
so gut wie alle der CDC-ACM-COM-Ports nicht für Analog-Modems genutzt.
Niklas G. schrieb:> Aber auch daran> kann man nur den Hersteller des Adapters identifizieren, nicht das> tatsächliche Gerät. Zu wissen ob es ein Prolific, FTDI, ... -IC ist> hilft kaum dabei zu entscheiden ob da ein Arduino, STK500, Analogmodem> oder GPS-Tracker dran hängt.
Und? Das war zu den Zeiten, wo man "echte" serielle Schnittstellen
verwendete, keinen Deut anders.
Bei USB-Seriell-Bridges ist mehr möglich, da kann dem Ding nämlich über
den USB-Descriptor ein Name mitgegeben werden, der sagt, worum es sich
handelt -- und dann hat anständig geschriebene Software die Möglichkeit,
sich den rauszusuchen und anzuzeigen. Die kann dann natürlich nicht nur
die Schnittstellen-API von 1993 verwenden.
Harald K. schrieb:> Und? Das war zu den Zeiten, wo man "echte" serielle Schnittstellen> verwendete, keinen Deut anders.
Richtig, aber das macht's nicht besser.
Harald K. schrieb:> Bei USB-Seriell-Bridges ist mehr möglich, da kann dem Ding nämlich über> den USB-Descriptor ein Name mitgegeben werden, der sagt, worum es sich> handelt
Ja, aber wenn man sich schon auf einen ganz spezifischen USB-Serial-IC
einschränkt und diesen auch manuell konfiguriert/programmiert, kann man
auch gleich sein eigenes Protokoll definieren. Das hat dann auch noch
weitere Vorteile, wie eben mehrere Endpoints, automatische
Flusskontrolle und Paketierung usw. Das erspart dann auch wieder einiges
an Arbeit welche man beim Serialport hat.
Das o.g. C# Snippet habe ich genutzt um eine serielle Kommunikation mit
einem eigenen Board zu implementieren. Dank dem gezeigten API war es
schön einfach den Port zu finden. Beim Implementieren vom seriellen
Protokoll mit Paketierung hab ich aber geflucht und mich gefragt warum
ich nicht ein eigenes USB-Protokoll implementiert hab - hätte im
Endeffekt wahrscheinlich einiges an Nerven gespart...
Niklas G. schrieb:> Ja, aber wenn man sich schon auf einen ganz spezifischen USB-Serial-IC> einschränkt und diesen auch manuell konfiguriert/programmiert, kann man> auch gleich sein eigenes Protokoll definieren.
Wenn man Lust dazu hat, notfalls einen eigenen Devicetreiber zu klöppeln
- und dem Anwender fest vorzuschreiben, mit welcher Software er mit
seinen Geräten reden darf, dann kann man das so machen.
Harald K. schrieb:> Wenn man Lust dazu hat, notfalls einen eigenen Devicetreiber zu klöppeln
Unnötig, libusb, WinUSB existiert.
Harald K. schrieb:> und dem Anwender fest vorzuschreiben, mit welcher Software er mit> seinen Geräten reden darf
Der TO entwickelt doch eh seine eigene Software. Ob der Anwender jetzt
die serielle Kommunikation oder die USB-Kommunikation sniffen muss um
seine eigene Software zu implementieren tut sich nicht viel. Man kann
beide Protokolle dokumentieren falls man Eigenentwicklungen erlauben
möchte.