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?
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.
Das Protokol ist gut fuer den anfang. Ich mach sowas jeweils ohne RTOS.
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?
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.
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.
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
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.