UART Protokoll implementieren

Gast #2940667
Lesenswert?

Hallo,
ich habe zum übertragen von Daten von meinem STM32 zum PC ein einfaches 
Protokoll erfunden. Es läuft alles unter einem RTOS mit Interrupts und 
allem.

So und ich frage mich schon lange, wie man das "richtig" macht. ich 
verwende folgendes Frameformat:

0x02 (ASCII STX)
Length
Command
Address
Data
CRC16
0x03

Für den Empfang gilt selbiges.

Soll ich Empfang und Senden in separate Tasks auslagern? oder bei jedem 
eintreffenden Zeichen eine Message an den Task schicken?Was ist 
eleganter?
Gast #2940684
Lesenswert?

Wie sind denn diese Daten:

Length
Command
Address
Data
CRC16

kodiert?
Die Frage zielt darauf, ob 0x02 und 0x03 in diesen Daten vorkommen 
können.
In der Regel wird das dann in ASCII-Ziffern (ggf. Hexadecimal) 
übertragen damit Frame-Limiter nicht in den Daten vorkommen können.

Was Deine Frage betrifft, so ist die Aufgabe ja einen kompletten Frame 
zu empfangen und zu senden unter der Voraussetzung, das die eigentliche 
Anwendung mit Teilframes nichts anfangen kann. Eine andere Frage ist, ob 
die Anwendung auf fehlerhafte Frames reagieren kann. Jedenfalls unter 
der genannten Voraussetzung ist es "sauberer" den Empfang und das Senden 
völlig von der Anwendung zu trennen. Also kurz: Ja. Lage das aus.
Gast #2941356
Lesenswert?

Nun, da ich noch vieles andere nebenbei machen muss, möchte ich nicht 
auf das RTOS verzichten. Die Frage ist, wie soll ich die Empfangsroutine 
gestalten? Ich dachte erst, im RX interrupt des UART sende ich das 
jeweils empfangene Byte an den Empfangs-Task, der dann mit einem 
Zustandsautomaten die Pakete erkennt. Aber ist nicht so elegant, oder?
Gast #2941396
Lesenswert?

Wieso hast du eigentlich ein Framing mit STX/ETX und zusätzlich noch ein 
Längenfeld? Eins von beiden ist unnötig. STX/ETX erlaubt dir aber, schon 
im Interrupt-Handler Pakete zu separieren bzw. deiner Hauptroutine ein 
flag zu setzen, wenn ein vollständiges Paket im Empfangspuffer liegt.

Hmm schrieb:
> Die Frage zielt darauf, ob 0x02 und 0x03 in diesen Daten vorkommen
> können.
> In der Regel wird das dann in ASCII-Ziffern (ggf. Hexadecimal)
> übertragen damit Frame-Limiter nicht in den Daten vorkommen können.

Im klassischen ASCII-Framing wird vor jedem ETX in den Nutzdaten ein DLE 
(0x10) gesendet, so verhindert man die Fehlerkennung. DLE selbst wird 
ebenfalls mit DLE escaped. DLE ETX wird für 0x03 gesendet und DLE DLE 
für 0x10.
Gast #2941402
Lesenswert?

Nachtrag: STX/ETX erlaubt dir das gesagte besonders einfach, ohne 
explizite state machine, nur ein DLE-Flag und ein ETX-Flag muss der 
Interrupt verwalten. Natürlich geht das auch mit dem Parsen der Pakete 
on-the-fly, aber dann wird das eben alles etwas aufwendiger.
Gast #2941871
Lesenswert?

Aus "Frame senden" und "Frame empfangen" wird erst ein "Protokoll", wenn 
es eine Bestätigung (Acknowledge) und gegebenfalls eine Wiederholung 
eines verlorenen Frames gibt. Dann aber sind zwingend fortlaufende 
Nummern (Identifier) notwendig. Und da es dann auch verschiedene 
"Frames" (besser "Messages") gibt, sollte auch noch ein Message 
Identifier vorgesehen werden.


Blackbird

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