Hi bin jetzt seit 4 Tagen an diesem Problem und komm nicht mehr weiter :( Hab nen DSP mit dem ich über die Serielle Schnittstelle kommunizieren will. Und zwar über Folgen von zweistelligen Hex Zahlen. Also z.B. fordere ich ihn mit "0x02 0x01 0x7F 0x80 0x03" auf, zu pingen und er antwortet das gleiche zurück. Die Antwort kann aber bei anderen Befehlen auch unterschiedlich lang sein. Jetzt will ich das ganze mit nem C-Programm unter Linux machen. Wie kann ich das empfangen, was ankommt? anbei mal mein Programm-Code so far. Hab in allen Tutorials dies im Netz so gibt geguckt aber es funzt einfach nicht. Teilweise aus dem Serial Programming Howto kopiert. oben die openport funktion, weiter unten die auslesen. Das Öffnen des Ports funzt. Das Senden funzt auch. Aber Lesen geht nicht. Der Port läuft im non-canonical mode. canonical geht nicht, da wartet er ewig auf ein cr. oder read failed weil timeout. der read Befehl gibt auch kein -1 zurück, also er liest was, aber mal sind es o bytes und mal 5, und stimmen tun sie auch nicht. mit printf wird nur schwachsinn angezeigt und im debugger steht 0x80 als -128 drin und 0x03 gar nicht. Nehme an, das ist ein Problem im Array angekommen, vielleicht falscher datentyp, vielleicht ist VMIN oder VTIME falsch gesetzt. Vielleicht ist auch noch was im Puffer was stört. :( Was mach ich falsch? Danke für eure Hilfe LG
du must einfach mehrfach lesen. Es kann auch sein das jedes byte einzeln ankommt. Die Frage ist wieviel du lesen musst, aber das sollte in der Doku vom Protokoll erkennt bar sein. was soll das flush nach dem Read?
Danke für die schnelle Antwort stimmt, das flush brauch ich nicht, da in der openport funktion schon der puffer vor dem lesen geleert wird ?? Gut, ich werds dann mal mit ner lese Schleife versuchen. Ist aber komisch, dass mal alle 5 Bytes ankommen wie gewollt und mal gar keine. Der Debugger zeigts an
VT0815 schrieb: > Gut, ich werds dann mal mit ner lese Schleife versuchen. Ist aber > komisch, dass mal alle 5 Bytes ankommen wie gewollt und mal gar keine. > Der Debugger zeigts an weil du im debugger langsam bist, damit kann es sein das in puffer schon 5 byte das sein.
Ok, ein usleep(200000) vor Aufruf der Auslesen Funktion hat es gebracht, jetzt sind immer Daten da :) Vielen Dank :)
VT0815 schrieb: > Ok, ein usleep(200000) vor Aufruf der Auslesen Funktion hat es gebracht, > jetzt sind immer Daten da :) > Vielen Dank :) das ist doch aber murks. Man sollte kein sleep verwenden!. Normalerweise sollte read blockieren wenn man lesen will. Dann kann man einfach byteweise einlesen. Denn ich konnte nicht sehen das du nicht-blockierend arbeitest.
VT0815 schrieb: > Ok, ein usleep(200000) vor Aufruf der Auslesen Funktion hat es > gebracht, > jetzt sind immer Daten da :) > Vielen Dank :) Und was passiert, wenn doch keine Daten da sind? Du hast also einen usleep() eingebaut, der bei korrekter Programmierung unnötig wäre, und die korrekte Funktion basiert allein auf dem Prinzip Hoffnung.
1 | printf ("%s das ist angekommen\n", angekommen); |
angekommen ist kein String! Bestenfalls stehen da nach deiner Aussage die selben Daten drin, die du verschickt hast. Da fehlt ein Null-Byte zum Abschluss des Strings, und die Zeichen sind in ASCII "STX SOH DEL ??? ETX" (0x80 ist in reinem ASCII nicht definiert) und nichts davon sind sichtbare Zeichen. Kein Wunder, dass da immer Müll rauskommt.
1 | if (status != num){ |
2 | printf("write failed weil != sizeof textlänge\n"); |
3 | }
|
Das ist kein Fehler, sondern ganz normaler Betrieb.
arbeite auch nicht nicht-blockierend. Wahrscheinlich braucht das Gerät am anderen Ende der Leitung einfach die Zeit um den Antwortstring zu generieren und zu schicken
Wäre nicht-blockierend besser? Die Gegenhardware muss doch erstmal lauschen, verarbeiten und sendet dann erst. Jedenfalls geht es jetzt. Danke für die Hilfe
VT0815 schrieb: > Wäre nicht-blockierend besser? kommt daruf an. Unter linux gibt es für die serielle schnittstelle kein möglichkeit einen Timeout festzulegen. Damit würde das Programm blockiern weil eventuell NIE etwas kommt. Da muss man wohl oder übel mit non-block arbeiten. Aber dann sollte man die Abfrage ob etwas da ist mit select oder poll vorher machen, dort kann man dann den Timeout übergeben. while( !alles gelesen ) { if ( select ( fd ..., timeout ) == timeout ) { FEHLER; } read(fd ... ) } so in der Art ist es ohne sleep sauber.
Aber man kann doch mit c_cc [VTIME] einen Timeout festlegen, auch wenn man blockierend arbeitet? Lass die NONBLOCk Option jetzt aber doch gesetzt. Und deinen Vorschlag mit dem Polling werde ich auch mal ausprobieren.
VT0815 schrieb: > Aber man kann doch mit c_cc [VTIME] einen Timeout festlegen, auch wenn > man blockierend arbeitet? ja, aber das wirkt glaube ich nicht wirklich. > Und deinen Vorschlag > mit dem Polling werde ich auch mal ausprobieren. ist es kein polling
2 der größten Mysterien in der ganzen Programmierung * warum können Computer nicht in die Zukunft sehen, um zu wissen wieviele Bytes ihr Gegenüber noch schicken wird? * warum benötigt auch eine Datenübertragung Zeit, die dann auch noch gemeinerweise um Größenordnungen langsamer ist, als die heutigen Gigaherz-Boliden rechnen können? Die Antwort auf beide Fragen, liefert dir die Begründung warum ein deartiges read nicht funktioniert.
1 | status = read (fd, angekommen, nbytes); //readbefehl, status ist anzahl der gelesenen bytes |
der Kommentar ist falsch bzw. missverständlich. Das sind in dem Fall, dass von der UART gelesen werden soll, die Bytes die schon am PC eingetrudelt sind. Ob das alle Bytes sind, der der Empfänger sich anschickt auch wegzuschicken, ist damit noch lange nicht gesagt. read liefert das was da ist. Nicht mehr und nicht weniger. Ob einige der Bytes, die ser Empfänger wegschickt noch mit dem berittenen Boten unterwegs sind oder vieleicht gar noch gar nicht auf den Weg gebracht wurden, kann read nicht wissen. Also gibt es dir erst mal das, was da ist.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.