Forum: Mikrocontroller und Digitale Elektronik Kommunikationsprotokoll als Baum definieren?


von Hank (Gast)


Lesenswert?

Wie definiert man Kommunikationsprotokolle?
Es geht um einen einfachen Fall mit wenigen Befehlen und Unterbefehlen 
bei unterschiedlicher Befehlslänge sowie unterschiedlichen Antworten.
Ist es zweckmäßig, die Schnittstelle mit allen Befehlen und Antworten 
als Baum darzustellen?

Beispiel:
1
Befehl 1
2
  Unterbefehl 1
3
    Daten 1
4
      Daten 2
5
        <- Antwort
6
  Unterbefehl 2
7
    Daten
8
      <- Antwort 1
9
        <- Antwort 2
10
Befehl 2
11
  <- Antwort
12
Befehl 3
13
  Unterbefehl 3
14
...

Eine Kommunikation ist demnach ein Weg durch den Baum. Der Baum stellt 
also alle Möglichkeiten dar.

Vorteil ist: es ist eindeutig. Nachteil ist, dass es viele Baumebenen 
sind. Was sind die Alternativen?

von PittyJ (Gast)


Lesenswert?

Ich kenne mehr so formale Sprachen BNF, EBNF, Charts in Form von 
Eisenbahnen usw. (So ein Chart lag der ersten Version von K&R bei)

Bäume kenne ich nicht. Das Beispiel finde ich total unübersichtlich.

von Rene K. (xdraconix)


Lesenswert?

Hank schrieb:
> Befehl 1
>   Unterbefehl 1
>     Daten 1
>       Daten 2
>         <- Antwort
>   Unterbefehl 2
>     Daten
>       <- Antwort 1
>         <- Antwort 2
> Befehl 2
>   <- Antwort
> Befehl 3
>   Unterbefehl 3
> ...

Wenn dann ist das irgendwie falsch... Das müsste meiner Meinung nach 
dann für eine Baumstruktur so sein:

1
 Befehl 1
2
   Unterbefehl 1
3
     Daten 1
4
     Daten 2
5
       <- Antwort
6
   Unterbefehl 2
7
     Daten
8
       <- Antwort 1
9
       <- Antwort 2
10
 Befehl 2
11
   <- Antwort
12
 Befehl 3
13
   Unterbefehl 3
14
 ...

Weil Daten 1 und 2 sowieo Antwort 1 und 2 liegen ja auf den gleichen 
Ästen.

von S. R. (svenska)


Lesenswert?

Mit einem Baum kannst du keine Schleifen abbilden. Sowas wie "Header - 
beliebige Anzahl an Parametern - Footer" für eine Nachricht geht damit 
nicht sinnvoll, weil du für jede mögliche Parameterreihenfolge einen 
eigenen Teilbaum erzeugen musst.

Ein einfaches Protokoll kannst du mit einem Baum aber durchaus 
beschreiben, beim Reverse Engineering fällt anfangs auch einer raus.

von Hank (Gast)


Lesenswert?

Rene K. schrieb:
> Weil Daten 1 und 2 sowieo Antwort 1 und 2 liegen ja auf den gleichen
> Ästen.

Das ist beabsichtigt, denn Daten 2 folgen auf Daten 1 - sie sind nicht 
alternativ. Jeder Ast ist eine alternative Kommunikation.

Es sollte besser Datenpaket heißen. Was drin steckt, ist erstmal egal.

BNF ist wahrscheinlich kompakter, aber auch schwerer zu lesen.

von Hank (Gast)


Lesenswert?

PittyJ schrieb:
> Charts in Form von
> Eisenbahnen usw. (So ein Chart lag der ersten Version von K&R bei)

Was ist die genaue Bezeichnung?

von Pandur S. (jetztnicht)


Lesenswert?

Geht es um ein Protokoll das alle moeglichen Datenstrukturen, resp 
Protokolle umfassen soll ? Die eierlegende Wollmilchsau ? Baut man 
nicht. Bei embedded & mikrocontroller baut man etwas, das schnell und 
einfach implementiert werden kann, also eher etwas flaches.
zB

[SYN][START][LAENGE][COMMAND][DATA][CRC]
[SYN][START][LAENGE][DESTINATION][COMMAND][DATA][CRC]
[SYN][START][LAENGE][SOURCE][DESTINATION][COMMAND][DATA][CRC]

dh es gibt nur eine Ebene Commands. Die muss man naemlich erst mal 
implementieren und testen. Der Anspruch bei embedded & mikrocontroller 
ist fehlerfreier code ! Daher sollte der moeglichst einfach sein.

von Jack (Gast)


Lesenswert?

Hank schrieb:
> Wie definiert man Kommunikationsprotokolle?

In hunderten von verschiedenen Arten und weisen. Ohne zu wissen was 
genau du machen willst ist ein Vorschlag schwer.

Offensichtlich bist du auf der Anwendungsschicht (Schicht 7). Dort sind 
hierarchische Strukturen (Baumstruktur) bei Management-Protokollen 
gängig. Geht es bei dir um das Gerätemanagement?

Die hierarchische Struktur wird beim Gerätemanagement, je nach 
Management-Protokoll, in einer sogenannten Management Information Base 
(MIB) https://de.wikipedia.org/wiki/Management_Information_Base 
beschrieben (Aber Vorsicht, nur weil in dem Artikel eine MIB anhand von 
SNMP erklärt wird sollte man allerdings nicht SNMP nehmen. SNMP kann 
einen in den Wahnsinn treiben).

Grundsätzlich hast du bei einer Baumstruktur immer das Problem, welche 
Ordnungskriterien man nimmt. Wenn man Hardware verwaltet dann 
strukturiert man die MIB häufig entlang der Hardware. Beim Managen von 
Software hat man häufig nicht mal Anhaltspunkte für eine natürliche 
Struktur. In beiden Fällen bleibt das Problem, dass die Struktur 
trotzdem nicht immer zwingend ist.

Zum Beispiel kann bei einer Spannungsüberwachung sowohl eine Struktur 
der Form

Modul-X/Rail-Y

Also auch

Rail-X/Modul-Y

sinnvoll sein.

> Es geht um einen einfachen Fall mit wenigen Befehlen und Unterbefehlen
> bei unterschiedlicher Befehlslänge sowie unterschiedlichen Antworten.

Befehls- und Antworten-Längen sind doch das kleinste Problem. Entweder 
verwendet man ein Ende-Zeichen (beliebt ist bei ASCII-Kodierung zum 
Beispiel das Neue-Zeile Zeichen :-)), oder man kodiert die Länge mit 
rein.

> Ist es zweckmäßig, die Schnittstelle mit allen Befehlen und Antworten
> als Baum darzustellen?

Siehe oben. Das hat sich bei bestimmten Anwendungen bewährt.

von Peter D. (peda)


Lesenswert?


von Hank (Gast)


Lesenswert?

Danke soweit für die Anregungen.
Die zwei Ebenen sind bereits festgelegt. Ich suche nur noch nach einem 
Modell.
Ein Baum zur Darstellung möglicher Sequenzen ist wohl nicht ganz falsch. 
Evtl. lassen sich Datensequenzen (Daten 1, Daten 2) als Datenstruktur 
zusammenfassen. Aber das ist Sache des Protokolls, nicht unbedingt der 
Abbildung.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Oh D. schrieb:
> einfach implementiert werden kann, also eher etwas flaches.
> zB
>
> [SYN][START][LAENGE][COMMAND][DATA][CRC]
> [SYN][START][LAENGE][DESTINATION][COMMAND][DATA][CRC]
> [SYN][START][LAENGE][SOURCE][DESTINATION][COMMAND][DATA][CRC]

 Ich mache es mit:
 [SOF][DESTINATION][SOURCE][COMMAND][LENGTH][DATA][CS][EOF]

 Vorteil ist, dass schon beim zweiten Byte, wenn die Zieladresse
 nicht stimmt, rausgesprungen werden kann, so dass die ISR schnell
 abgearbeitet wird - nur check auf EOF und neues SOF.

 Was das mit Befehl und Unterbefehl sein soll, ist mir ein bißchen
 unklar.
 Ich habe Befehle von 0x10 - 0x70, bei Antwort wird bit7 auf 0
 gesetzt, demzufolge gehen mögliche Antworten von 0x90 - 0xF0.
 Befehle 0x00-0x0F und 0xF1-0xFF sind reserviert.

 Mit bits4-6 werden 8 Gruppen bezeichnet, jede mit 16 Befehlen und
 es wird eine select-case Abfrage nach Gruppen gemacht, z.B. ist
 Gruppe 1 Sensoren, Gruppe 2 Aktuatoren, Gruppe 3 Displays usw.

 Jede Gruppe wird dann wieder mit select-case abgefragt.
 Da ich in meinem Editor Collapse und Expand habe, bleibt das Ganze
 ziemlich übersichtlich, wobei übersichtlich auch relativ ist - bei
 mehr als 100 Befehlen kann das nie so übersichtlich werden wie ich
 es gerne möchte...

von Amateur (Gast)


Lesenswert?

Da ist wohl vieles Meinungssache!

Ich ziehe ein Protokoll vor, bei dem die Blocklänge möglichst früh 
festliegt.
Also ist die Länge konstant, oder implizit durch das Schlüsselbyte 
festgelegt, so sollte das Schlüsselbyte möglichst früh erscheinen. Ist 
die Länge variabel, so sollte das Längenbyte möglichst früh kommen.
Der Hintergedanke dabei ist der, dass einer der wichtigsten Schritte die 
vollständige Sammlung des jeweiligen Befehls ist.
Vorher ist keine Vollständigkeitsprüfung möglich und eine Überprüfung 
einer CRC-Kennung ist auch nicht machbar.

von Jack (Gast)


Lesenswert?

S. R. schrieb:
> Mit einem Baum kannst du keine Schleifen abbilden. Sowas wie "Header -
> beliebige Anzahl an Parametern - Footer" für eine Nachricht geht damit
> nicht sinnvoll, weil du für jede mögliche Parameterreihenfolge einen
> eigenen Teilbaum erzeugen musst.

Da wird bei einem Baum gerne mittels einer Tabelle oder Liste gepfuscht. 
Das Protokoll bekommt neben einer normalen Lese-Funktion (get) noch eine 
Lese-weiter-Funktion (getNext), mit der durch die Zeilen einer Tabelle 
durch-iteriert wird, ohne dass man jede Zeile einzeln adressieren muss.

Hank schrieb:
> PittyJ schrieb:
>> Charts in Form von
>> Eisenbahnen usw. (So ein Chart lag der ersten Version von K&R bei)
>
> Was ist die genaue Bezeichnung?

"Railroad Diagram" oder "Syntax Diagram". Letzteres sagt dann auch was 
es wirklich ist, eine Darstellung einer Syntax. Das kann man enbensogut 
mit BNF machen. Ob das was man darstellt eine Baumstruktur hat 
interessiert weder BNF noch Railroad-Diagramme.

von Pandur S. (jetztnicht)


Lesenswert?

Es gibt eine Uebertragungsschicht, die ist mit der Uebertragung selbst 
beschaeftigt, und das andere packt man in das Datenpacket.

Der Sender zaehlt einfach die Anzahl Zeichen runter bis keins mehr da 
ist.
Der Empfaenger zaehlt die Anzahl Zeichen hoch, bis alle da sind. Dann 
wird die Meldung auseinandergenommen und bearbeitet.
Es gibt je nach Anforderung praktischere Wege, und weniger praktische. 
Es gibt Wege, beim Verwerfen einer Meldung moeglichst schnell wieder 
aufsetzen zu koennen, Wege zum Fehler detektieren, korrigieren, je nach 
erwartbarem Fehler. Dann sollte man sich Gedanken machen was bei einer 
ungueltigen Meldung geschehen soll.

Ich lass die Meldung jeweils abgezaehlt aus dem Interrupt uebergeben, 
und pruefe dann im Main, ob Adressierung und CRC passen. Und dann erst 
kommt die Verarbeitung. Es ist aber auch denkbar eine Meldung vorher zu 
verwerfen, wenn schon das erste Feld nicht passt.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Amateur schrieb:
> Da ist wohl vieles Meinungssache!
>
> Ich ziehe ein Protokoll vor, bei dem die Blocklänge möglichst früh
> festliegt.

 Wenn die Nachricht nicht für mich ist, wozu brauche ich die Länge ?
 In diesem Fall wird ganz einfach auf EOF und dann neues SOF gewartet
 um die ISR so schnell wie nur möglich wieder verlassen zu können.

> Vorher ist keine Vollständigkeitsprüfung möglich und eine Überprüfung
> einer CRC-Kennung ist auch nicht machbar.

 SOF und die eigene Adresse bleiben immer konstant, damit fängt die CRC
 an, das wird nicht gerechnet.
 Und die CRC sollte sowieso in main() berechnet, bzw. überprüft werden.

: Bearbeitet durch User
von Mehmet K. (mkmk)


Lesenswert?

Marc V. schrieb:
> Ich mache es mit:
>  [SOF][DESTINATION][SOURCE][COMMAND][LENGTH][DATA][CS][EOF]

Wegen [LENGTH] und [CS] ist meiner Meinung nach [EOF] unnötig.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Mehmet K. schrieb:
> Wegen [LENGTH] und [CS] ist meiner Meinung nach [EOF] unnötig.

 Wenn die Nachricht nicht für mich ist oder der uC hat sich irgendwie
 verlaufen, warte ich auf:
 [EOF][SOF][DESTINATION], das sind 1:16,777,216 Möglichkeiten, dass
 die Bytes in [DATA] in exakt dieser Reihenfolge kommen.
 Kritische Befehle müssen sowieso innerhalb von 5ms bestätigt werden,
 ansonsten werden die wiederholt, somit kann kein Gerät am Bus länger
 als 5ms in undefiniertem Zustand bleiben.

von Strubi (Gast)


Lesenswert?

Amateur schrieb:
> Da ist wohl vieles Meinungssache!

Und noch mehr Möglichkeiten gibt's, sich ins Knie zu schiessen.

Grundsätzlich stellt sich immer die Frage:
a) Paketbasiert oder
b) Streambasiert (SOF/EOF)

(b) ist für Zero-Copy (DMA) ungeeignet wegen der Escape-Problematik, man 
ergo für ein Paket nie die Länge genau voraussagen kann, aber wenn eh 
bei jedem eintreffenden Zeichen ein ISR angesprungen wird, lässt sich 
damit arbeiten. Mein Fazit ist, nach vielen Jahren Gefriemel mit div. 
Protokollen: Lieber paketbasiert mit sauber definierten 
Timeout-Szenarien.

>
> Ich ziehe ein Protokoll vor, bei dem die Blocklänge möglichst früh
> festliegt.

Dito :-)

Was die Befehle angeht: auch so ein Streitpunkt, aber ich würde mal 
behaupten, dass sich in der Industrie die einfachen Registerprotokolle 
durchgesetzt haben. Alles kommandobasierte wird tendentiell schwerfällig 
und aufwendiger zu implementieren.
D.h. man sollte eigentlich von so einer Beschreibung wie einem Baum auf 
der Protokoll-Ebene eher wegwollen.
Die Baumstruktur ist dann auf dem Endgerät sinnvoll, wenn man eine 
Möglichkeit haben will, abstrahierte Eigenschaften (nicht zwingend 
Register) des Geräts abzufragen. Dafür benötigt man aber nur wenige 
Primitiven. Siehe Bibliotheken wie div. modbus-Implementationen, 
wireless-Ansätze wie SWAP oder abstrahierendere Protokolle wie netpp 
(quelloffene Eigenentwicklung) oder Google protocol buffers.

von Tobias P. (hubertus)


Lesenswert?

@Strubi

das interessiert mich jetzt. Was ist ein einfaches Registerprotokoll?

von Strubi (Gast)


Lesenswert?

Tobias:

Take a pick:
- Datenblatt eines einfachen i2c-GPIO: PCA9534
- Etwas komplexer: modbus

Also, statt Befehle parsen gibts Protokoll-Primitiven:
a) [READ] [REGISTER_ADDR] ¦ [ACK] ¦ [RDATA]
b) [WRITE] [REGISTER_ADDR] [DATA] ¦ [ACK]

Der ¦ trennt die Protokoll-Phasen (state-Maschine), ACK (acknowledge): 
Gut gelaufen, oder eben nicht.

Die End-Hardware muss so nur noch die REGISTER_ADDR (also eine Zahl) 
decodieren. Leichtgewichtiger gehts kaum.

von Pandur S. (jetztnicht)


Lesenswert?

Ja, sinnvollerweise ist ein Command etwas Kurzes, ein Register lesen 
oder schreiben waere optimal, manchmal muss man noch etwas kurzes 
Rechnen. Wenn man zB Werte lieber als ASCII uebertragen will, das 
Register aber Integer oder float ist. Einen Prozess anstossen und 
abwarten ist nicht so praktisch.

Ebenso sinnvoll ist es das Protokoll Zustandslos zu entwerfen. Also, 
dass die Packete unabhaengig voneinander sind, und auch einzeln 
wiederholt werden koennen. Das bedeutet dann zB, dass bei einem 
Datentransfer eine Blocknummer dabei ist, jeder Block einzeln abgefragt 
werden kann.

: Bearbeitet durch User
von Moritz M. (moritz_m793)


Lesenswert?

Moin!

Ich verwende für meine seriellen Protokolle eine simple Bibliothek.
Sie arbeitet binär und verwendet zur Identifikation ein einzelnes Byte.
Die Befehle werden mit fixen Längen in einem Array definiert, dass macht 
es simpel neue Befehle hinzuzufügen.

Nachteil: Gehen tatsächlich Bytes verloren kann es zu 
missinterpretierten Daten kommen :/


Hier die lib:
https://github.com/momagu/CommandAggregator

Viele Grüße,
Moritz

von Armin G. (Firma: Rentenvers. Bund (Frührentner)) (armin_g)


Lesenswert?

Hey!

Ein häufig verwendeter Ansatz für Bäume in der Vergangenheit war der 
'logische Token Ring'. Wurde bzw. wird teilweise auch heute noch 
verwendet im Zusammenhang mit ARCnet.

Beste Grüße!

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.