RS232-Protokoll

Herakles

Profifragensteller
Moin!

Ich möchte gern zwei Chips (ein STM und ein ATMEL, beide mit www.freertos.com bestückt) via RS232 ohne ASCII-kodierung miteinander kommunizieren lassen. Die Datenpakete sind dabei von variabler Länge und haben immer unterschiedliche Inhalte.

Bisher habe ich sowas immer "quick & dirty" so implementiert, dass im Datenpaket selbst die Länge des Pakets stand und dann beim Empfangen gezählt wurde, wieviel schon empfangen wurde bis das komplette Paket da war. Dabei erkennt man natürlich keine Fehler wie "Einschalten einer Platine mitten in einer laufenden Übertragung" oder "Byte bei der Übertragung verloren", sondern rennt dann in Fehler wie "ich warte bis zum Sankt Nimmerleinstag auf Daten, weil ich glaube, noch gar nicht alles bekommen zu haben" oder "ich häre schon auf zu lesen, obwohl noch gar nicht alles da ist". Lösen könnte man sowas vielleicht über ein RX Timeout, aber sicher geht das auch noch anders...

Datenfehler selbst will ich nicht so abfangen, dafür möchte ich gerne eine CRC mit ins Protokoll stecken. Mein Frage ist eher:

Was ist ein wirklich gutes Protokoll, das ich hierfür verwenden kann? Wie machen die "Profis" sowas?

Vielen dank im Voraus für jeden Tipp,
Herakles
 
Wenn das ganze etwas komplizierter ist dann braucht es halt ein vernünftiges Protokoll. Über Ethernet mach ich sowas dann eher so, dass jede Aktion von der Gegenstelle quittiert wird. Sprich A baut auf und B bestätigt. Wenn das passt sagt A, dass er z.B. 16Byte sendet. B sagt OK er empfängt. Dann sendet A seine Byte und sagt dann er ist fertig. B bestätigt 16Byte empfangen zu haben.

Die ganzen Ansagen und OKs musst du halt in eigens festgelegten Bytemustern codieren.
 
Der UART erkennt für dich Bits und Bytes. Meistens will man heutzutage vielfache von Bytes zu je 8 Bit übertragen und wenn nur aus Gewohnheit. Die nächste Frage ist wieviel Overhead du dir erlauben kannst und willst. Passen deine Nachrichten nicht in ein Byte, wie bereits durch den CRC impliziert, so musst du die Nachrichtengrenzen kodieren. Hierbei ist es wichtig auf Datentransparenz zu achten unter Berücksichtung der möglichen Übertragungsfehler. Ein RS232 UART wir sich wieder auf ganze Bytes synchronisieren und kann Bytes verändern, einfügen oder verwerfen.

Mögliche Ansätze:
  • Falls alle UARTs 9 Bit Bytes unterstützen verwende das 9. Bit um den Anfang einer Nachricht zu markieren.
  • Transformiere die Nachricht Datentransparenz zu gewähren z.B. base64 oder Quoting
Ein interessanter Hack für kurze Nachrichten fester Länge ist es den CRC wiederzuverwenden um die Nachrichten grenzen zu finden. Bei diesem Ansatz schiebst du die Nachricht in einen Ringpuffer und berechnest sobald der voll ist den CRC. Stimmt der CRC akzeptierst du die Nachricht und du leerst den Puffer. Stimmt der CRC nicht schreibst du weiter in den Ringpuffer. Aus diesen kleinen Nachrichten kannst du nun bequem größere zusammenbauen sollte das notwendig sein. Auf einem STM32F103 war es mir möglich den DMA Controller sowohl direkt die CRC32 Engine zu füttern wie den Ringpuffer zu implementieren.
 
Moin!

Danke für die Tipps, ich habe es nun mit einem Timeout-getriggerten IRQ gemacht. Wer Interesse an der ISR und den Einstellungen für die GPIO-Pins sowie die Initilalisierung der USARTs hat, melde sich bitte einfach bei mir.

Grüße
Herakles
 
Zurück
Oben