Forum: PC-Programmierung Kommunikation über Hex-Codes auf Serieller Schnittstelle unter Linux in C


von VT0815 (Gast)


Angehängte Dateien:

Lesenswert?

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

von Peter II (Gast)


Lesenswert?

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?

von VT0815 (Gast)


Lesenswert?

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

von Peter II (Gast)


Lesenswert?

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.

von VT0815 (Gast)


Lesenswert?

Ok, ein usleep(200000) vor Aufruf der Auslesen Funktion hat es gebracht, 
jetzt sind immer Daten da :)
Vielen Dank :)

von Peter II (Gast)


Lesenswert?

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.

von Andreas B. (andreas_b77)


Lesenswert?

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.

von VT0815 (Gast)


Lesenswert?

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

von Peter II (Gast)


Lesenswert?

VT0815 schrieb:
> arbeite auch nicht nicht-blockierend.

und warum?

von VT0815 (Gast)


Lesenswert?

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

von Peter II (Gast)


Lesenswert?

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.

von VT0815 (Gast)


Lesenswert?

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.

von Peter II (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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
Noch kein Account? Hier anmelden.