www.mikrocontroller.net

Forum: PC-Programmierung gcc unter Linux - serielle Schnittstelle


Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Raptor (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hi,

wie kann ich in C programmieren, dass der Eingabepuffer abgefragt wird, 
ob sich dort noch Daten befinden?

if (weitere Daten vorhanden?)
{
    lies ein Zeichen von Seriell ein
}

Gruß
R.

Autor: Raptor (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Zusatzfrage: Gibt es überhaupt einen Puffer? Wie groß ist er?

Autor: block (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Du musst die Schnittstelle im NONBLOCKing modus öffnen. Dann gibt er dir 
beim lesen genau so viele bytes zurück, wie er im puffer hat.

Autor: Raptor (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Wenn ich die Zeichen byteweise einlese, dann komme ich irgendwann an 
einen Punkt, wo keine Zeichen mehr zur Verfügung stehen.

Das Programm hängt bei 'read(port, buffer, 1)'.

Autor: Use the source (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Raptor schrieb:
> Wenn ich die Zeichen byteweise einlese, dann komme ich irgendwann an
> einen Punkt, wo keine Zeichen mehr zur Verfügung stehen.
>
> Das Programm hängt bei 'read(port, buffer, 1)'.

Quellcode ?

Autor: Raptor (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Der Quellcode sieht im Moment so aus:
for (x=0; x<30; x++)
{
    // Jetzt können Daten gelesen werden
    bytes = read(port, buffer, sizeof(buffer));
    printf(buffer);
    if (buffer[0] == '\n')
    {
        break;
    }
}

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?

Autor: raute (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Die serielle Schnittstelle muss auch richtig konfiguriert werden, Rest 
siehe:
http://tldp.org/HOWTO/Serial-Programming-HOWTO/x115.html

P.S.: Ich vermute mal, dass du auch select verwenden möchtest.

Autor: Raptor (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Ja, ich habe die Schnittstelle auch initialisiert:
        // serielle Schnittstelle für die Kommunikation zum Arduiono öffnen
        // beim Arduino wird dadurch ein RESET durchgeführt, Grund: DTR geht auf LOW
        port = open(COM_DEVICE, O_RDWR);
        // prüfen, ob die Schnittstelle erfolgreich geöffnet wurde
        if (port == -1)
        {       // das ist der Fehlerfall
                printf("Schnittstelle konnte nicht geöffnet werden.\n");
                return(1);
        }
        // Geschwindigkeit einstellen und sonstige Einstellungen
        if (tcgetattr(port, &com_attr)!= 0)
        {
                printf("Schnittstelle fehlerhaft: tcgetattr()");
                return(1);
        }
        // jetzt die Einstellungen
        com_attr.c_cflag        = COM_SPEED | CS8 | CRTSCTS | CLOCAL | CREAD;
        com_attr.c_iflag        = 0;
        com_attr.c_oflag        = OPOST | ONLCR;
        com_attr.c_lflag        = 0;
        if (tcsetattr(port,TCSAFLUSH, &com_attr) != 0)
        {
                printf("Schnittstelle fehlerhaft: tcsetattr()");
        }

Was ist 'select'? Ist das das Zauberwort? Ich werde es mir mal ansehen.

Autor: Der Weise (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Raptor schrieb:
> port = open(COM_DEVICE, O_RDWR);
durch
port = open (COM_DEVICE; O_RDWR | O_NONBLOCK);
ersetzen.
block schrieb:
> Dann gibt er dir
> beim lesen genau so viele bytes zurück, wie er im puffer hat.

Autor: Rolf Magnus (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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().

Autor: Georg A. (georga)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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.

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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.

Autor: Georg A. (georga)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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.

Autor: Rolf Magnus (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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().

Autor: Der Weise (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
select() hat vor allem den Vorteil, dass bei mehreren Streams 
gleichzeitig warten kann, ob etwas ankommt, um dann nur bei dem, bei dem 
was angekommen ist, read() aufrufen zu müssen. Wobei einer der Streams 
natürlich auch stdin o.ä. sein kann.

Autor: der Thomas (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Du kannst Dir auch bevor "read" ausgeführt wird die Anzahl der Bytes im 
Puffer mittels ioctl abholen, ist recht nützlich!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net