Hi zusammen,
ich bin gerade dabei erste Schritte mit C für die serielle Schnittstelle
unter Linux zu machen.
Nun habe ich festgestellt, dass man mein Programm mehrfach starten kann
und die einzelnen Prozesse dann Fragmente der seriellen Daten erhalten.
Hier mein bisheriger code:
1
intmain(intargc,char*argv[])
2
{
3
charc;
4
intfd;
5
6
fd=open("/dev/ttyUSB0",O_RDWR|O_NOCTTY|O_NDELAY);
7
if(fd==-1){
8
printf("Error opening port!\n");
9
}else{
10
printf("Opened port!\n");
11
getchar();
12
close(fd);
13
}
14
return0;
15
}
Wie kann ich dedizierten Zugriff auf eine Serielle Schnittstelle
realisieren? Gibt es einen Weg generell weitere Zugriffe zu sperren oder
verlässlich abzufragen ob die Schnittstelle schon benutzt wird?
Gruß
René
...wie wär'S mit einem Flag, das bei Beginn einer Übertragung gesetzt
wird und "belegt" meldet, bis es es nach beenden der Übertragung vom
aufrufenden Task wieder rückgesetzt wird?
Mikel_X schrieb:> ...wie wär'S mit einem Flag, das bei Beginn einer Übertragung gesetzt> wird und "belegt" meldet, bis es es nach beenden der Übertragung vom> aufrufenden Task wieder rückgesetzt wird?
Mehrere Programme verwenden die Schnittstelle. Daher muss ich
allgemeingültig prüfen können.
Mit lsof kann ich nun sogar testen ob mehrere prozesse die Schnittstelle
geöffnet haben und ggf. einen Prozess beenden. Da meine Anweundg
unkritisch ist, ist das für mich die perfekte Quick&Dirty lösung ;)
@Norbert: Sieht fast schon genau nach dem aus, was ich suche.
Mir fällt nur auf, dass dann erst der Port geöffnet wird und dann die
Prüfung stattfindet. (Damit könnte ich ja eine vorhandene kommunikation
stören, oder?).
Rene P. schrieb:> @Norbert: Sieht fast schon genau nach dem aus, was ich suche.> Mir fällt nur auf, dass dann erst der Port geöffnet wird und dann die> Prüfung stattfindet. (Damit könnte ich ja eine vorhandene kommunikation> stören, oder?).
Nö, nur öffnen ist rein passiv und stört gar nichts.
Kannst du wunderbar testen, indem du mit einer Applikation eine
andauernde Datenübertragung machst und die Daten mit zB. md5sum oder
sha1sum überprüfst. Während diese Übertragung läuft, startest du ein
zweites Programm, das eine Million mal die Schnittstelle öffnet, ein
paar 100 µs wartet und wieder schließt.
Norbert schrieb:> Nö, nur öffnen ist rein passiv und stört gar nichts.> Kannst du wunderbar testen, indem du mit einer Applikation eine> andauernde Datenübertragung machst und die Daten mit zB. md5sum oder> sha1sum überprüfst. Während diese Übertragung läuft, startest du ein> zweites Programm, das eine Million mal die Schnittstelle öffnet, ein> paar 100 µs wartet und wieder schließt.
Super! Danke für die Erklärung.
Dann habe ich ja genau was ich brauche und wünsche allen hier ein frohes
Osterfest :-)
Traditionell (d.h. andere Programme machen es auch so) werden
Lock-Dateien verwendet. Das Programm, das etwa auf /dev/ttyS0 zugreifen
will, erzeugt eine Datei /var/lock/LCK..ttyS0 und schreibt seine PID
rein.
Wenn das Erzeugen fehlschlägt (weil die Datei existiert und die
entsprechenden Flags bei open gesetzt wurden), ist das Device gesperrt.
Man sollte in dem Fall die Lock-Datei noch auslesen und prüfen, ob die
angegebene PID überheupt noch existiert und gegebenenfalls die veraltete
Lock-Datei löschen und es neu versuchen. Selber sollte man natürlich
auch die Lock-Datei zuverlässig am Programmende löschen (etwa via
atexit() Handler).
Andreas B. schrieb:> Traditionell (d.h. andere Programme machen es auch so) werden> Lock-Dateien verwendet. Das Programm, das etwa auf /dev/ttyS0 zugreifen> will, erzeugt eine Datei /var/lock/LCK..ttyS0 und schreibt seine PID> rein.
Das funktioniert allerdings nur für das eigene Programm, denn es gibt
kein Standard-Lockfile für ttyS0, das von allen Programmen, die drauf
zugreifen genutzt wird.
Das Standard-Lockfile für ttyS0 ist /var/lock/LCK..ttyS0 unter Linux und
dem Filesystem Hierarchy Standard. Früher und unter anderen Unixen ist
unter Umständen das Verzeichnis anders (etwa /usr/spool/locks), das
Prinzip ist das gleiche.
Dazu der FHS:
Many programs follow a convention to create a lock file in /var/lock to
indicate that they are using a particular device or file. This directory
holds those lock files (for some devices) and hopefully other programs
will notice the lock file and won't attempt to use the device or file.
Lock files should be stored within the /var/lock directory structure.
Lock files for devices and other resources shared by multiple
applications, such as the serial device lock files that were originally
found in either /usr/spool/locks or /usr/spool/uucp, must now be stored
in /var/lock. The naming convention which must be used is LCK.. followed
by the base name of the device file. For example, to lock /dev/ttyS0 the
file LCK..ttyS0 would be created. The format used for the contents of
such lock files must be the HDB UUCP lock file format. The HDB format is
to store the process identifier (PID) as a ten byte ASCII decimal
number, with a trailing newline. For example, if process 1230 holds a
lock file, it would contain the eleven characters: space, space, space,
space, space, space, one, two, three, zero, and newline.
Andreas B. schrieb:> ...and hopefully other programs> will notice the lock file and won't attempt to use the device or file.
Da würde ich doch sagen: Ich lege ein Lockfile an und schaue trotzdem
mal nach, ob die Schnittstelle nicht schon geöffnet ist ;-)
Hallo,
wenn ich die Diskussion hier lese, verstehe ich nicht, wieso Linux
Windows so unendlich überlegen sein soll - unter Windows kann Programm B
eine COM-Schnittstelle einfach nicht öffnen, wenn diese schon von
Programm A benutzt wird, Basta. Ich weiss, der Glaube machts, da
schluckt man jede Kröte.
Gruss Reinhard
Reinhard Kern schrieb:> Hallo,>> wenn ich die Diskussion hier lese, verstehe ich nicht, wieso Linux> Windows so unendlich überlegen sein soll - unter Windows kann Programm B> eine COM-Schnittstelle einfach nicht öffnen, wenn diese schon von> Programm A benutzt wird, Basta. Ich weiss, der Glaube machts, da> schluckt man jede Kröte.>> Gruss Reinhard
Du wirst im Laufe der Diskussion hier festgestellt haben, das es unter
Linux sehr einfach ist, ein Device exklusiv zu öffnen *WENN MAN SELBST
ES MÖCHTE* und nicht wenn das OS es befiehlt.
Alles was man tun muß, ist einen Betriebssystembefehl abzusetzen.
Ich habe als Programmierer die volle Kontrolle, wo also ist das Problem
(wenn man mal Polemik außen vor lässt)?
Rolf Magnus schrieb:> Andreas B. schrieb:>> and hopefully other programs will notice the lock>> Das sagt ja schon genug darüber aus, wie zuverlässig das ist.
Welche Programme, die auf die seriellen Schnittstellen zugreifen,
verletzen denn konkret dieses Protokoll?
Norbert schrieb:> printf("Opened port!\n");> if (-1 == ioctl(fd, TIOCEXCL))> printf("...exclusive!\n");
Achtung, das hat nicht exakt das gewünschte Ergebnis. Das verhindert,
dass das Device in Zukunft von Prozessen, die nicht als root laufen,
geöffnet werden kann. Damit merkt man nicht, ob das Device bereits von
anderen Prozessen geöffnet wurde und benutzt wird.
Andreas B. schrieb:> Achtung, das hat nicht exakt das gewünschte Ergebnis. Das verhindert,> dass das Device in Zukunft von Prozessen, die nicht als root laufen,> geöffnet werden kann. Damit merkt man nicht, ob das Device bereits von> anderen Prozessen geöffnet wurde und benutzt wird.
Interessanter Einwand. Hatte ich bis jetzt noch nicht festgestellt, da
meine daemons immer ihre Rechte auf Minimal 'droppen' sobald sie
gestartet werden.
Sollte man aber im Hinterkopf behalten, wenn man irgendetwas komplett
mit root Rechten laufen lässt.
Norbert schrieb:> Ich habe als Programmierer die volle Kontrolle, wo also ist das Problem> (wenn man mal Polemik außen vor lässt)?
Darüber, ob das Device schon benutzt wird, hast du ja, wie sich aus der
Diskussion ergibt, mit deiner Methode überhaupt keine Kontrolle - nur
darüber, ob sich in Zukunft noch ein Dritter einklinken kann.
Wie schon gesagt, der Glaube muss es richten. Es war mir schon klar dass
sich auf meinen Post gleich die ultraorthodoxen Eiferer zu Wort melden,
aber für mich zählen halt nur logisch korrekte Aussagen, tut mir leid.
Linux hat natürlich auch seine guten Seiten, da muss man Schwächen nicht
mit Täuschungsmanövern schönreden.
Gruss Reinhard
Nun, an sich macht es ja mehr Sinn, komplett zu verhindern, dass "in
Zukunft" ein 2. Programm auf den selben Port zugreift, anstatt zu
hoffen, dass ein solches Programm so nett ist, zu prüfen, ob bereits ein
Zugriff erfolgt. Das macht man eben mit dem TIOCEXCL Flag. Unter Windows
ist dieses Flag quasi immer gesetzt, unter Linux hat man eben die Wahl -
Linux kann also das gleiche wie Windows, und noch mehr - wo ist da die
Schwäche? Was hat Windows deiner Meinung nach für einen Vorteil?
Reinhard Kern schrieb:> Darüber, ob das Device schon benutzt wird, hast du ja, wie sich aus der> Diskussion ergibt, mit deiner Methode überhaupt keine Kontrolle - nur> darüber, ob sich in Zukunft noch ein Dritter einklinken kann.
Mit Lockfiles ja, aber dass es allgemein keine Kontrolle gäbe, ist
schlicht falsch (schließlich wurde ja weiter oben die Lösung gepostet).
Und nun fantasier weiter herum.
Aus den Diskussionsbeiträgen kann man sehr schön erkennen,
das es Windows Benutzern* - und das ist jetzt nicht abfällig gemeint -
ein nahezu unbekanntes Konzept ist, das Programme immer nur mit den
Rechten laufen die unbedingt für die Funktion nötig sind.
Hält man sich an dieses Konzept erkennt man das normale Programme
praktisch (im Sinne von nahezu) niemals root-Rechte brauchen. Von
System- und Wartungswerkzeugen einmal abgesehen, da hängen die
notwendigen Rechte damit zusammen auf was und wie diese Werkzeuge
zugreifen.
Wenn man daemons schreibt, kann es in Einzelfällen notwendig sein,
diesen für bestimmt Aufgaben root-Rechte zu erteilen. Das kann man sogar
nach einem fork() per Prozess festlegen und allen anderen Beteiligten
Prozessen die unbenötigten Rechte entziehen (eigentlich geben sie selbst
ihre Rechte ab)
Eine serielle Schnittstelle zum Beispiel braucht keine root-Rechte
PUNKT.
Es liegt logisch gefolgert am Programmierer ob er seine Aufgabe gut oder
schlecht macht / machen will.
*) Wie oft haben wir schon lesen müssen, das selbst triviale Aufgaben
mittels sudo oder direkt als root durchgeführt werden. Dieses Prinzip
ist gerade bei Windows Umsteigern sehr beliebt.
*) Wie oft haben wir schon lesen müssen, das Benutzerrechte solange
erweitert werden bis etwas funktioniert.
*) Wie oft haben wir schon lesen müssen, das Resourcerestriktionen
solange heruntergesetzt werden bis etwas funktioniert.
Ein schönes Beispiel sind Windows SMB Freigaben:
Kannst du auf die Datei zugreifen? Nein!
Prutsch,werkel,... und jetzt, geht's jetzt? Nein!
OK...bastel,bastel... teste nochmal. Cool jetzt gehts!
OK, dann lassen wir die volle Freigabe auf alles einfach drin. Ist ja
kein Sicherheitproblem, man muß ja schließlich noch den Pfad kennen.
Dr. Sommer schrieb:> Was hat Windows deiner Meinung nach für einen Vorteil?
Dass es die ganze Diskussion überhaupt nicht gäbe, ein COMPort steht
einem Programm zur Verfügung, ein weiteres kann das Device nicht öffnen
bevor das erste es nicht geschlossen hat. Und das ohne dass der
Programmierer etwas tun muss, er bekommt beim Open einfach die Antwort
geht nicht, wird schon verwendet. Da Devices wie Comports normalerweise
für mehrfache Benutzung vollkommen ungeeignet sind, ist das auch die
einzig korrekte Behandlung durch das Betriebssystem - allerdings, nach
dem Verlauf der Diskussion, für Linuxer vollkommen unverständlich. Hier
scheint man es für natürlich zu halten, dass die Sendedaten zweier
Programme bunt gemischt auf TxD erscheinen. Naja, wenn ihr das so toll
findet, da kann man halt nichts machen.
Wir hatten schon genug Ärger mit den ach so tollen Unix-Methoden wie
Lockfiles, bei denen selbst Software der 100 KEuro-Klasse nicht sauber
funktioniert, weil jedes Programm nur seine eigenen Lockfiles sieht.
Aber jeder Unix-Anhänger schwört darauf als ultimative Sharing-Regelung.
Ist aber wirklich jedes Wort zuviel, Argumente werden in diesem Umfeld
garnicht zur Kenntnis genommen und erst recht nicht beantwortet, weil
jemand von ausserhalb ja nur zu dumm sein kann um Unix zu kennen - eine
Standardantwort, die ich seit 30 Jahren immer wieder höre, ganz egal um
was es geht.
Danke für die Belehrungen, Reinhard
Reinhard Kern schrieb:> Dass es die ganze Diskussion überhaupt nicht gäbe, ein COMPort steht> einem Programm zur Verfügung, ein weiteres kann das Device nicht öffnen> bevor das erste es nicht geschlossen hat.
Das ist zwar in vielen Fällen sinnvoll, aber eben nur in vielen. Ein
Beispiel, wo es das nicht ist, ist die Nutzung der seriellen
Schnittstelle, um daran ein Terminal oder Modem zu betreiben.
In einer unixoiden Umgebung können sich mehrere Prozesse mit dieser
Schnittstelle verbinden und horchen, was da an Daten reinkommt.
Primär verantwortlich ist der Prozess, der das ganze mit einer
logon-Sitzung und letzlich irgendeiner Kommandozeilen-Shell verbindet,
aber sekundär kann auch ein Z-Modem-Protokoll-Interpreter und ein
Fax-Modem-Interpreter gleichzeitig dranhängen, so daß, wenn in der
Terminalsitzung jemand Daten per Z-Modem überträgt, die gleich im
richtigen Loch landen können, oder bei Einwahlsitzungen ein an ein
angeschlossenes Modem gesandtes Fax nicht in einer Shell landet, sondern
korrekt empfangen wird.
Gut, das sind alles Konzepte aus der kommunikativen Altsteinzeit ...
aber auch in "neuzeitlicheren" Anwendungen kann es ganz praktisch sein,
den Datenstrom, der über eine serielle Schnittstelle geht, mehrfach
abgreifen zu können. Man stelle sich ein Gerät vor, das mit einem
unbekannten Protokoll von einer proprietären Software angesteuert wird
... durch einen "Mithörer" kann man schon mal Ansätze des
Reverse-Engineering betreiben.
Fragwürdig erscheint mir das Konzept, daß die Verriegelung der
Schnittstelle nur per informeller Absprache (lockfile und hoffen, daß
sich alle dran halten) und nicht per open übergebenen Flags erfolgt.
Das Windows-Pendant, CreateFile bietet die Möglichkeit, mit "share
flags" anzugeben, ob und wie andere Prozesse die göffneten Handles
ebenfalls öffnen dürfen.
Dr. Sommer schrieb:> Nun, an sich macht es ja mehr Sinn, komplett zu verhindern, dass "in> Zukunft" ein 2. Programm auf den selben Port zugreift, anstatt zu> hoffen, dass ein solches Programm so nett ist, zu prüfen, ob bereits ein> Zugriff erfolgt. Das macht man eben mit dem TIOCEXCL Flag. Unter Windows> ist dieses Flag quasi immer gesetzt,
Nein.
> unter Linux hat man eben die Wahl -> Linux kann also das gleiche wie Windows, und noch *mehr*
Nö
> - wo ist da die> Schwäche? Was hat Windows deiner Meinung nach für einen Vorteil?
Win32 CreateFile
dwShareMode gibt an ob der Aufrufer exklusiven Zugriff haben will oder
ob andere Programme lesen und/oder schreiben dürfen. Ganz einfach
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx