Jetzt mal was konkretes

Nachdem ich es neulich schon mal angekündigt habe, kommt jetzt
ein Vorschlag, wie man meine Schichten in der Praxis implementieren
könnte.


Schicht 1 - Übertragung

Übertragen werden Datenblöcke mit einer bestimmten
Länge entweder direkt oder als Broadcast. Sollte als
serielle Variante problemlos auf einem uC implementierbar
sein.
  • Seriell:
    Für seriell ist die direkte und die broadcast-übertragung gleich.
    Es existieren verschiedene Möglichkeiten, das Datenpaket zu
    übertragen. Meines Erachtens am besten wäre hier das von PicNick
    genannte Byte Stuffing, bzw. eine ähnliche Form davon mit Escape-
    sequenzen und Framing. Im Gegensatz zum ByteStuffing ist das
    Kontrollzeichen hier absolut eindeutig im Datenstrom, was die
    die Fehlertoleranz noch etwas verbessert.

    LAN:
    Am einfachsten und performantesten ist wohl die Übertragung durch
    UDP-Pakete über einen festgelegten Port. Dabei können broadcasts
    und direkte Nachrichten über die entsprechenden UDP-Äquivalente
    verschickt werden. Interessant am LAN ist noch das 'Finden' der
    anderen Teilnehmer. Dafür würde ich Lan Kontrollpakete vorschlagen,
    mit denen neue Teilnehmer auf dem LAN sich bei den anderen
    Teilnehmern bekanntmachen.


Schicht 2 - Adressierung/Routing

Adressierung:
  • Einzelne Knoten werden über zwei Bytes adressiert. Dabei ist
    ein Byte die eigentliche Adresse, das andere Byte das Subnetz.
    Zusammen bilden sie eine eindeutige Adresse für jeden Knoten.

    Bei jedem der beiden Bytes gibt es zwei 'spezielle' Werte. Der
    Wert 0 ist eine Broadcast-Adresse, der Wert 0xff die eigene
    Adresse. Bei Broadcasts kann also nicht nur in das 'lokale'
    Subnetz gebroadcastet werden. Wird für die Adresse ein konkreter
    Wert eingetragen und für das Subnetz die Broadcastadresse, so
    wird die Nachricht an die bestimmte Adresse in jedem Subnetz
    übertragen. Dadurch kann man nahezu einen Multicast realisieren,
    indem man z.B. alle Komponenten zur Variablensynchronisation
    auf eine bestimmte Adresse legt.

    Auch der Wert 0xff für die 'eigene Adresse' bedarf noch einer
    Erläuterung. Setzt ein uC diesen Wert für sein Subnetz ein, so
    kann er kommunizieren, ohne sein eigenes Subnetz kennen zu
    müssen.


Auf der Adressierung baut nun der Router auf. Er muss entscheiden,
wohin eine eingehende Nachricht weitergeleitet wird. Der Router kennt
seine(n) lokale(n) Knoten und eine Menge an Übertragungs-HW (Segmente)
Im folgenden stelle ich zwei Möglichkeiten vor, wie es das tun könnte:
  • Statisches Routing (problemlos auf uCs verwendbar)
    Besonders leicht, wenn nur ein Segment existiert (z.B. seriell)
    Die Routen sind in diesem Fall statisch eingetragen. Der uC
    weis also das er selbst (unveränderlich) der Knoten X ist
    und das es einen 'Uplink' gibt, der für alles andere
    zuständig ist. Das Routing beschränkt sich also darauf,
    Nachrichten auf die eigene Adresse zu überprüfen und entweder
    nach oben oder an das 'Default' Segment weiterzugeben.

    Als Erweiterung kann er ein zweites Lokales Interface mit der
    Adresse Y kennen, das z.B. am I2C Bus hängt. Auch dieses wird
    statisch eingetragen und bedient.

    Dynamisches Routing (aufwändiger)
    Auf irgendeiner Ebene des Systems, meistens wohl auf den
    Knoten mit LAN-interface wird die Sache aufwändiger. Jetzt
    gibt es plötzlich sehr viel mehr direkte Kommunikationspartner.
    Natürlich könnte man auch die alle statisch konfigurieren, das
    ist jedoch nicht besonders Flexibel.

    Für die 'Königslösung' müsste der Router nun für jede Adresse
    herausfinden und speichern über welches Interface sie erreichbar ist.
    Um das effizient zu tun brauchts entweder eine lookup-Table mit
    64k Einträgen oder einen guten Hashalgorithmus. Das ganze ist imho
    nicht so wahnsinnig praktikabel, auf uCs mit Ethernet vmtl. gar nicht
    implementierbar.

    Ein Zwischenlösung könnte sein, wenn der Router nicht alle Adressen
    speichert, sondern lediglich nach Subnetzen routet. Nur innerhalb des1
    'eigenen' Subnetzes wird nach Adressen geroutet. Adressen aus anderen
    Subnetzen werden nur nach ihrem Subnetz einem Sebment zugeordnet. An
    dieses Segment wird die Nachricht dann übertragen. Im Normalfall wird
    die Gegenstelle dann die Nachricht entweder selbst korrekt zustellen
    (wenn sie zur ihrem Subnetz gehört und existiert), weiterleiten (auf
    anderes Segment) oder fallenlassen (richtiges Subnetz, nicht existierende
    lokale Adresse).

    Klingt kompliziert - ist es aber nicht. Vor allem hoffe ich genau
    diesen Teil komplett in libraries verstecken zu können.


Schicht 3 - Verbindung/Sicherung

Im ersten Schritt will ich nur verbindungslose, unsichere Nachrichten.
Diese Schicht ist also quasi leer und hat (noch) nicht viel zu tun.

Schicht 4 - Dienste

Auf dieser Schicht kommt nur ein Datenpaket mit festgelegter Länge an.
Wie genau dieses verarbeitet wird, bleibt noch festzustellen. Da ihr
alle schon ganz fleissig über diese Schicht diskutiert und diese Schicht
wenig mit der eigentlichen Übertragung zu tun hat, werde ich ihr demnächst
einen eigenen Post widmen.


Anmerkung: Natürlich sind meine heutigen Vorschläge noch lange kein
hartes Interface. Ich hoffe ihr könnte euch trotzdem schon vorstellen,
worauf ich hinaus will. Ich werde in den nächsten Tagen mal eine
konkrete Definition schreiben, dann sollte es ganz klar werden.

ciao,
Georg