Lesen und Schreiben vom seriellen Port unter Linux

Hallo Experten,

ich habe momentan ein mir nicht ganz nachvollziehbares Problem mit dem Lesen und Schreiben von Daten auf einen seriellen Port. Folgender Sachverhalt: Ich habe ein ZigBee Gerät an die serielle Schnittstelle ttyUSB0 angeschlossen und will dort nun mittels Tastutareingabe Befehle versenden und die Rückgabewerte auf die Konsole ausgeben.
Das Problem ist nun, dass der file descriptor nicht das liefert, was er soll. Wenn ich z.Bsp. den Befehl ATI eingebe(gibt Infos für das Gerät zurück) wird nur diese Eingabe auf die Konsole geschrieben. Nichts die erwarteten Werte.
Der Witz ist: Sobald ich allerdings in einer zweiten Konsole den Port mit Minicom öffne, erscheinen die Ausgaben auf der ersten Konsole. Hat jemand eine Idee, woran das liegen könnte?

Hier die beiden Threads, die das Senden und Empfangen bewerkstelligen:
fd ist dabei das Device.

/\*\* thread for message sending \*\*/
void \*startMessageSending() {
 char key;
 char message[BUFSIZE];

 while(1) {
 /\*\* get message from the keyboard input \*\*/
 message[0] = '\0';
 while ((key = getchar()) != '\n') {
 sprintf(message, "%s%c", message, key);
 }
 //sprintf(message, "%s%c", message, '\0');

 /\*\* send message to the port \*\*/
 printf("Sending message %s to %s\n", message, DEVICE);
 if (write(fd, message, strlen(message)) 

Howdy,

/** thread for message sending **/
void *startMessageSending() {
char key;
char message[BUFSIZE];

while ((key = getchar()) != ‚\n‘) {
sprintf(message, „%s%c“, message, key);
}
//sprintf(message, „%s%c“, message, ‚\0‘);

mal abgesehen von der sehr gewöhnungsbedürftigen unf fehlerträchtigen Benutzung von sprintf, solltest du zunächst mal den fd auf non-buffered setzen. Danach sehen wir dann mal weiter.

Gruss
norsemanna

Howdy,

mal abgesehen von der sehr gewöhnungsbedürftigen unf
fehlerträchtigen Benutzung von sprintf, solltest du zunächst
mal den fd auf non-buffered setzen. Danach sehen wir dann mal
weiter.

Gruss
norsemanna

Und wie genau erreich ich das? Ich habe das Flag für O_NONBLOCKING bereits gesetzt, aber immer noch das selbe Problem.

Hi,

Und wie genau erreich ich das? Ich habe das Flag für
O_NONBLOCKING bereits gesetzt, aber immer noch das selbe
Problem.

Non-Blocking ist erstmal was ganz anderes als Non-Buffering. Non-Buffering erreicht man bei stream-based-fds mit setvbuf/setbuf und anderenfalls schaust du (was du ohnehin musst) mal auf ioctl. Es ist aber nur eine Vermutung, dass es am Buffering liegt, das muss nicht die Ursache deines Problems sein.

Gruss
norsemanna

Hej,

Non-Blocking ist erstmal was ganz anderes als Non-Buffering.
Non-Buffering erreicht man bei stream-based-fds mit
setvbuf/setbuf und anderenfalls schaust du (was du ohnehin
musst) mal auf ioctl. Es ist aber nur eine Vermutung, dass es
am Buffering liegt, das muss nicht die Ursache deines Problems
sein.

Gruss
norsemanna

Ich blick grad nicht ganz durch… setvbuf und setbuf erwarten als Paramter doch ein FILE*, ich hab doch aber nur einen normalen Integer fd. Und die ioctl Kommandos zum flushen, werfen bei mir immer die Fehlermeldung raus, dass die Argumente invalide sind. Vielleicht weil der fd kein STREAMS device ist?

Ich will doch eigentlich nur einen stinknormalen Com-Port öffnen und auf dem Lesen und Schreiben. =( So wie Minicom das tut, bloß sehr viel vereinfachter.

Gruss,
Sebastian

Hallo SebastianN !

Es gibt die Stream I/O Funktionen die mit Filepointern (=FILE*) (zu denen gehören z.B. setbuf(), fopen() und fclose()) arbeiten und die low-level I/O Funktionen die mit (int) handles (zu denen gehören z. B. open() und close()) arbeiten.

Um für einen Stream mit handle eine Filepointer zu erzeugen gibt es die Funktion _fdopen():

_fdopen(): Associate a stream with a file that was previously opened for low-level I/O.

FILE \*\_fdopen( int handle, const char \*mode );

(Vorsicht: Die Funktion fclose() schliesst nicht nur den Filepointer sondern macht damit auch das Handle ungültig!)

mfg
Christof