gcc unter Linux - serielle Schnittstelle

Gast #2618691
Lesenswert?

Der Quellcode sieht im Moment so aus:
1
for (x=0; x<30; x++)
2
{
3
    // Jetzt können Daten gelesen werden
4
    bytes = read(port, buffer, sizeof(buffer));
5
    printf(buffer);
6
    if (buffer[0] == '\n')
7
    {
8
        break;
9
    }
10
}

Wenn aus irgendeinem Grund weniger als 30 Zeichen und kein '\n' 
geliefert werden, dann hängt das Programm an dieser Stelle.

Was kann ich dagegen machen?
Gast #2618718
Lesenswert?

Ja, ich habe die Schnittstelle auch initialisiert:
1
        // serielle Schnittstelle für die Kommunikation zum Arduiono öffnen
2
        // beim Arduino wird dadurch ein RESET durchgeführt, Grund: DTR geht auf LOW
3
        port = open(COM_DEVICE, O_RDWR);
4
        // prüfen, ob die Schnittstelle erfolgreich geöffnet wurde
5
        if (port == -1)
6
        {       // das ist der Fehlerfall
7
                printf("Schnittstelle konnte nicht geöffnet werden.\n");
8
                return(1);
9
        }
10
        // Geschwindigkeit einstellen und sonstige Einstellungen
11
        if (tcgetattr(port, &com_attr)!= 0)
12
        {
13
                printf("Schnittstelle fehlerhaft: tcgetattr()");
14
                return(1);
15
        }
16
        // jetzt die Einstellungen
17
        com_attr.c_cflag        = COM_SPEED | CS8 | CRTSCTS | CLOCAL | CREAD;
18
        com_attr.c_iflag        = 0;
19
        com_attr.c_oflag        = OPOST | ONLCR;
20
        com_attr.c_lflag        = 0;
21
        if (tcsetattr(port,TCSAFLUSH, &com_attr) != 0)
22
        {
23
                printf("Schnittstelle fehlerhaft: tcsetattr()");
24
        }

Was ist 'select'? Ist das das Zauberwort? Ich werde es mir mal ansehen.
Gast #2618821
Lesenswert?

Raptor schrieb:
> Wenn aus irgendeinem Grund weniger als 30 Zeichen und kein '\n'
> geliefert werden, dann hängt das Programm an dieser Stelle.
>
> Was kann ich dagegen machen?

Es "hängt" nicht, sondern es blockiert. Es wartet auf ein Zeichen. Du 
hast ja immerhin mit read() gesagt, daß das nächste Zeichen gelesen 
werden soll. Wenn keins da ist, wird halt gewartet, bis eins da ist. Wo 
soll es auch sonst herkommen?

Raptor schrieb:
> Was ist 'select'? Ist das das Zauberwort? Ich werde es mir mal ansehen.

Kommt drauf an, was du denn nun genau tun willst. Mit select() kannst du 
auf eine oder mehrere Dateien/Geräte/Sockets mit Timeout warten.
Wenn du also das Warten nach einer bestimmten Zeit abbrechen willst, 
gige das mit select().
#2618899
Lesenswert?

poll ist heutzutage eher der passende Call. Das hilft aber nicht gegen 
das Blockieren, wenn man danach mehr als ein Zeichen lesen will. D.h. 
man sollte mit NONBLOCK öffnen und dann zur Vermeidung von 
zeitfressenden Schleifen (weil read immer mit -1 zurückkommt) mit poll 
feststellen, ob was da ist und sonst einfach Zeit (aber nicht CPU...) 
verbraten.
#2618903
Lesenswert?

Ehrlich gesagt habe ich den Anwendungszweck das nichtblockierenden 
Lesens noch nie so richtig verstanden. Wenn ich von irgend was Daten 
will, dann warte ich doch so lange, bis diese da sind. Will ich parallel 
was anderes machen, benutze ich Threads.

was bringt das "Ich lese nichtblockierend und wenn nix da war, warte 
ich". Das ist doch auch nur blockierendes Lesen in kompliziert.
#2619012
Lesenswert?

> Ehrlich gesagt habe ich den Anwendungszweck das nichtblockierenden
> Lesens noch nie so richtig verstanden.

Wenn man zB. nicht weiss, wie lange die Message ist, die da eigentlich 
so reinkommt... Entweder popele ich dann jedes einzelne Byte aus dem 
Device (naja, ginge bei RS232 noch so) oder man nimmt alles, was man 
bekommen kann aber ohne das Warten auf das Füllen des Gesamtbuffers...

> Will ich parallel was anderes machen, benutze ich Threads.

Die helfen gegen obiges Problem nicht.
Gast #2619157
Lesenswert?

Vlad Tepesch schrieb:
> Ehrlich gesagt habe ich den Anwendungszweck das nichtblockierenden
> Lesens noch nie so richtig verstanden. Wenn ich von irgend was Daten
> will, dann warte ich doch so lange, bis diese da sind. Will ich parallel
> was anderes machen, benutze ich Threads.

Für sowas muß man doch nicht gleich mit Threads und deren 
Synchronisation hantieren. Einen Thread zu erzeugen, der dann quasi 
nichts anderes tut, als blockierend auf Daten zu warten, finde ich 
irgendwie unsinnig. Und nun müssen die Daten auch wieder irgendwie vom 
Lese-Thread in den anderen Thread kommen, und dann habe ich wieder das 
gleiche Problem.

> was bringt das "Ich lese nichtblockierend und wenn nix da war, warte
> ich". Das ist doch auch nur blockierendes Lesen in kompliziert.

Es sei denn, ich erwarte eine bestimmte Menge Daten, will aber nicht bis 
zum Sanktnimmerleinstag warten, wenn doch mal nicht alles ankommt.
read() hat halt keine Möglichkeit einen Timeout anzugeben, select() 
schon. Wenn man das benutzt, muß man aber darauf achten, daß es nicht 
passieren kann, daß read() doch mal blockiert, also öffnet man das Gerät 
non-blocking und wartet dann nur im select().

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren