Ringpuffer über UART verwenden

Ich richte ein UART-Protokoll ein, das die Kommunikation zwischen 2 Karten ermöglicht; Ein Masterboard und ein Slaveboard. Die Kommunikation zwischen ihnen wird wie folgt aussehen:
Beispiel 1:
Master [Tx] -- GET_VALUE--> [Rx] Slave
Master [Rx] <-- 0x05 -------- [Tx] Slave

Beispiel 2:
Master [Tx] -- GET_STATUS -----------> [Rx] Slave
Master [Rx] <-- I_AM_BUSY ------------ [Tx] Slave

Beispiel 3:
Master [Tx] -- START_OPERATION --> [Rx] Slave
Master [Rx] <----------ACK------------[Tx] Slave

Die Datengröße beträgt 1 Byte für den größten Teil des Datenflusses zwischen den beiden Karten. Deshalb werde ich Makros verwenden, um diese Befehle zu definieren:

Beispiel:

  #define GET_VALUE 0x05
  #define START_OPERATION 0x06
  etc ...

Zusätzlich zu diesen 1-Byte-Daten gibt es nur ein Element, das zwischen den beiden Karten übertragen werden sollte, dessen Größe nicht 1 Byte beträgt. Tatsächlich bin ich bereit, die Serialisierung zu verwenden, um eine Datenstruktur über UART unter Verwendung eines kreisförmigen FIFO-Puffers zu übertragen

Beispiel:
Master [Tx] -- GET_STRUCTURE ----> [Rx] Slave
Master [Rx] <----------STRUCTURE-------- ----[Tx] Slave

typedef struct{
uint8_t var1;
uint8_t var2;
uint8_t var3;
}MyStructTypeDef;

Soll über UART in diesem Format "Variablenname:WertXXX" übertragen werden:

var1:123XXXvar2:456XXXvar3:789XXX

XXX ist ein Trennzeichen

Meine Frage ist: Wenn 99% des Datenflusses 1 Byte groß sind und nur 1% des Datenflusses nicht 1 Byte groß ist, sollte ich dann nur einen Ringpuffer verwenden, um die Struktur zu erhalten? Gibt es eine bessere Möglichkeit, die Länge der über UART übergebenen Daten zu standardisieren?

Sie haben hier zwei unterschiedliche Schwierigkeiten. Das erste ist die Entwicklung eines 1-Byte-Protokolls, das auch beliebige Werte ohne Verwirrung verschieben kann. Wenn Sie keine Geschwindigkeit benötigen, sollten Sie Buchstaben und Ziffern in Betracht ziehen. oder ein 7-Bit-Zahlenformat verwenden, wobei das 8. Bit für Ihre speziellen Statuscodes reserviert ist. In Bezug auf die Pufferung geht es in der Regel nicht um die Bedeutung , sondern eher darum, ob Sie in der Lage sind, die Daten so zu verarbeiten, wie sie ankommen. Wenn dies der Fall ist, haben Sie möglicherweise einfach einen "Struct Being Collected"-Puffer anstelle eines kreisförmigen Puffers. Wenn nicht, möchten Sie wahrscheinlich alles durch einen Puffer zwischen dem ISR und dem Verbraucher leiten.
Ist dies Lock-Step oder asynchron, wenn der MASTER mehr als einen Befehl sendet, bevor er auf Antworten prüft?
@Jasen Es ist asynchron
Es wäre viel einfacher, Ihre Struktur als 4 Bytes zu senden: ein Byte, das sagt, was passiert (nennen Sie es THIS_IS_MY_STRUCTURE oder wie auch immer) und dann die 3 Strukturbytes. Sie sind Ein-Byte-Variablen, senden Sie einfach das Byte, anstatt es in Dezimalzahlen umzuwandeln.

Antworten (2)

Kann der Master beschäftigt auf dem UART warten und auf Antworten warten? Kann es die empfangenen Zeichen schnell genug sammeln und verarbeiten, um Überläufe zu vermeiden? Wenn nicht, dann brauchen Sie einen Puffer.

Wenn die längste Nachricht in den Puffer passt und Sie sie beim Senden jedes Befehls zurücksetzen, muss sie nicht kreisförmig sein.

Ich bin bereit, die Serialisierung zu verwenden, um eine Datenstruktur zu übertragen ... in diesem Format "Variablenname: WertXXX" ...

Gibt es eine bessere Möglichkeit, die Länge der über UART übergebenen Daten zu standardisieren?

Ich nehme an, dass die 'XXX's die Zeichenfolge auf eine feste Länge auffüllen. Es könnte effizienter sein, eine Zeichenfolge mit variabler Länge mit einzelnen Zeichen als Trennzeichen zu erstellen oder die Zahlen sogar in roher Binärform zu senden, aber wenn die Bandbreite kein Problem darstellt, ist das, was Sie tun, in Ordnung.

Vielleicht möchten Sie auch darüber nachdenken, was zu tun ist, wenn Master und Slave nicht mehr synchron sind. Wenn zum Beispiel der Slave eine Struktur sendet, aber der Master eine Antwort auf einen anderen Befehl erwartet, könnten einige der Zeichen in der Strukturnachricht fälschlicherweise als gültige Antworten interpretiert werden. Auch das,

Master [Tx] -- GET_VALUE--> [Rx] Slave
Master [Rx] <-- 0x05 -------- [Tx] Slave 

ist beunruhigend. Kann der 'Wert' eine beliebige Binärzahl sein? Wenn ja, woher wissen Sie dann, dass es sich nicht um eine Antwort auf einen anderen Befehl handelt? Kritische Antworten wie I_AM_BUSYund ACKsollten eindeutige Werte haben, die nicht in anderen Daten vorkommen können.

Sie könnten den ISR, der das serielle Empfangsinterruot bedient, direkt in Variablen schreiben lassen, er müsste seinen eigenen Zustand nachverfolgen, damit er weiß, wohin er schreiben soll.

Möglicherweise benötigen Sie einen Mutex, da Aktualisierungsfehler ein Problem darstellen könnten.

zum Senden müsste es wissen, welche Dinge gesendet werden müssen