Aus RN-Wissen.de
Version vom 4. März 2006, 18:32 Uhr von PicNick (Diskussion | Beiträge)

(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche
LiFePO4 Speicher Test

Network Controller/PC

Wenn einmal die Terminalemulation nicht mehr als Partner für den Microcontroller genügt, um Sensorwerte anzuzeigen oder Aktionen auszulösen, tauchen meist bei der Entwicklung der Software (in jedweder Sprache) einige Fragen zu der Kommunikation auf.

Für weitere Überlegungen über den Nachrichtenaustausch ist es günstig, ein einfaches Modell als Ausgangspunkt zu nehmen

Network1.png

  • Auf dem Controller (links) sollen drei Ports verwendet werden, zwei als Output, eins als Input, wobei die Pin-Änderungen entweder durch Polling oder durch Interrupt erkannt werden könnten.
  • Auf dem PC (rechts) soll eine Applikation laufen, die einerseits die Pins der Output-Ports setzen (vielleicht durch Check-boxen) und andererseits den Status des Inputports darstellen kann.

Anmerkung: mit Hardware kann man nicht reden. Kommunikation ist etwas, was sich grundsätzlich nur zwischen Programmen (-teilen) abspielt. Hardwarefunktionen müssen durch Software-Funktionen repräsentiert werden. D.h. vor jedem PortPin sitzt ein Stück Software, das auf Verlangen dann dieses Pin manipuliert.

Die Aufgabenstellung Es geht also darum, wie kann die PC-Applikation eine bestimmte Aktion beim Controller auslösen (diesen oder jenen Pin setzen), beziehungsweise wie kann der Controller dem Modul des PC-Programmes, das zuständig ist, mitteilen, daß sich etwas bei den Pins geändert hat. Da alle Nachrichten offensichtlich über den gleichen Draht gehen müssen, wird also eine "Dispatch" Funktion auf beiden Rechnern notwendig sein, die anhand einer Art Adresse in dieser Nachricht immer die angesprochenen Programmteile benachrichtigen kann. Also wurden als Adressen einerseits "Pout/1", "Pout/2" und "Pinp/1" vergeben, auf dem PC einfach "MODA/1", "MODA/2" und "MODB/1". Und wir nehmen auch einmal an, daß jeder davon weiß, wie sein richtiger Partner auf der anderen Seite heißt.

Der erste Ansatz

Wenn ModA/1 "sein" Port Pout/1 anweisen will, die Port-Pins neu zu setzen, sollte eine Message also beinhalten

  • PC->MC
    • Addr: Pout/1
    • Cmd: set
    • Argument: alle 8 Pins = ein byte 0x00 - 0xFF

Umgekehrt würde wohl Pinp/1 wegschicken

  • MC->PC
    • Addr: ModB/1
    • Cmd: set
    • Argument: alle 8 Pins = ein byte 0x00 - 0xFF

Nun kann so einem Kommando allerhand passieren: Der ganze Controller kann gerade abgeschaltet worden sein, der Dispatcher findet kein Pout/1, oder Pout/1 hat irgendwelche Probleme, das Kommando auch auszuführen. Also wäre eine positive oder negative Bestätigung nicht schlecht.

  • wenn die Nachricht erstmal Pout/1 erreicht und der nur einen einzigen potentiellen Auftraggeber hat, könnte der also antworten
    • Addr: ModA/1
    • Cmd: ACK od. NAK
    • Argument: irgendeine zusätzliche Information (optional)
  • Aber für alle anderen Komponenten gibt's bei Problemen zwei Möglichkeiten: entweder wissen auch sie, daß Pout/1 und ModA/1 zusammengehören, dann können sie ja antworten wie Pout/1 selbst. Wenn sie das aber nicht wissen, wird es schwierig, denn wer bekommt nun die NAK-Meldung ?

Nun, auf einem PC kann man die Sache mit einem "Timeout" Intervall theoretisch ganz einfach lösen:

Wenn innerhalb einer gewissen Zeit kein "ACK" zurückkommt, gilt das als "NAK", dann ist eben irgendwas passiert.

Oder man verzichtet überhaupt darauf, wie bei einem RC-Modell, das ja auch nicht antworten kann.

Der zweite Ansatz

Man erweitert Nachrichten um eine "Absender"-Adresse.

  • Ziel-Addr:
  • Absender-Addr:
  • Cmd:
  • Argument:

Jede (Zwischen-) Komponente, die Probleme hat, vertauscht einfach Ziel und Absender und schickt die Message zurück. Dadurch ist für den ursprünglichen Sender auch immer klar, WER da geantwortet hat, könnte ja sein, daß ein Modul an verschiedene Adressen sendet.

Dann brauchen wir aber irgendein Kennzeichen, daß es sich um eine Retour-Message handelt, damit nicht gegebenenfalls diese Nachricht auch wieder eine ACK/NAK-Bestätigung auslösen kann.

Noch eine Frage: woran merkt das PC-Comm-Modul eigentlich, daß der Controller nicht ansprechbar (abgeschaltet) ist ? Bei einer Rs232 Verbindung nur mit Rx/Tx bleibt die Leitung einfach stumm. Jetzt wird die Sache mit dem "Timeout" überlegenswert. Wenn gar nichts zurückkommt, gilt der Controller als abgängig.

Wenn aber eine Zeitlang gar keine Nachrichten gesendet werden ? Dann könnte jemand den Controller wegtragen und wir würden es garnicht merken. Dem können wir eigentlich nur abhelfen, indem wir auf jeden Fall regelmäßig irgendeine Nachricht schicken. Auf einem PC mit unbegrenzten Timern kein Problem. Und wem schicken wir diese "Ping" Messages ?

Ganz einfach, wir erzeugen auf dem Controller und dem PC ein Pseudo-Device/Modul "PING". Das auf dem PC schickt regelmäßig

  • Ziel-Addr: PING
  • Absender-Addr: PING
  • Cmd: xx

und das MC-Module tut nichts anderes, als darauf zu antworten

  • Ziel-Addr: PING
  • Absender-Addr: PING
  • Cmd: ACK

Fehlt diese Antwort, ist der Controller nicht ansprechbar.

Gut. Aber es sollen auch schon PCs gestorben sein. Also auch der Controller sollte merken, daß sein Partner veschieden ist. Wenn noch ein Timer frei ist, sollte auch er merken können, daß die "Pings" fehlen und vielleicht irgendein Notfall-Prozedere auslösen. (z.B. Antrieb STOP, wenn es ein Fahrzeug ist).

Zusammenfassung

  • Die Nachrichten haben unterschiedliche Längen und teilweise einen verschiedenen Aufbau.
  • Bei den Port-"SET" Nachrichten sollen als Wert Bytes mit dem Wertebereich 0x00 - 0xFF gesendet und empfangen werden. Daher können wir normale RS232-Steuerzeichen als "Nachricht-Ende" nicht mehr verwenden. Man kann natürlich eine Konversion auf ASCII oder HEX-ASCII machen, das ist aber für den Controller eine mühsame Sache.

Schichten (Layer)

Zweckmäßig ist auf jeden Fall eine Aufgabenteilung:

  • COMM beschränkt sich darauf, Daten variabler Länge sicher über die Leitung zu senden und zu empfangen. Eventuell auch den Medium-Zugriff zu handhaben (wenn es nicht RS232, sondern eine Bus-Verbindung ist).
  • DISPATCH übernimmt die Schnittstelle zu den Module und baut Sende-Pakete mit Ziel- und Absender auf, die es dem Comm-Modul übergibt. Andererseits nimmt es von diesem Empfangspakete entgegen und liefert sie bei den Modulen ab.
  • Module (Applications) Für sie erfolgt der Zugang aufs Netz transparent, d.h. nicht sichtbar. Sie scheinen über die Dispatch-Schnittstellen "direkt" mit ihren Partnern auf der gleichen oder anderen Maschine zu kommunizieren.

Eine besondere Nähe zur OSI-Nomenklatur wurde hier nicht gesucht. Es scheint dem Verfasser nicht zweckmäßig, z.B. auf einem Tiny-Controller alle Schichten explizit auszuführen.

Messages, ganz allgemein

Unabhängig von der Übertragungsart (also RS232 oder I2C) sind hier die Elemente bzw. die Events einer Message dargestellt. Einige davon können auch entfallen, wenn es technische Eigenheiten erlauben.

Network2.png

COMM

  • Start

Jede Message braucht einen für alle Teilnehmer erkennbaren und eindeutigen Beginn. Bei I2C ist es die "Start-Bedingung" (fallende Flanke auf SDA, wenn SCL auf High ist) bei SPI gilt die SS-Leitung, bei RS232 Protokollen oft der 9-Bit-Mode benutzt, wobei das 9.Bit als Kennzeichen gilt.

Der Start ist eigentlich das Wichtigste. Die Empfangsfunktion muß dadurch in der Lage sein, die weiteren Bytes einwandfrei zu lesen. Hier müßten auch Kennzeichen enthalten sein, wenn es mehrere verschiedene Paket-Typen gibt (eventuell auch die Version, das ist gut für eine spätere Weiterentwicklung)

Der Message-Start unterbricht auch immer eine eventuell laufende Bearbeitung und setzt das Empfangsmodul zurück.

  • Nutzdaten: Das ist das schraffierte Bereich, dessen Inhalt für den Transport keine Rolle spielt.
  • End: Das Ende muß nun wieder für die Transportfunktionen erkennbar sein.

Es kann auch im Start eine Längenangabe enthalten sein, dadurch ist dann ein explizites Ende-Kennzeichen nicht nötig, die Empfangsroutine muß dann halt mitzählen. Beim I2C-Bus hingegen ist es zum Beispiel so, daß sowohl die Empfangseinrichtung (durch Unterlassung des ACK) als auch der Senders durch eine Stop- oder eine neue Start-Bedingung die Übertragung jederzeit beenden können.

  • Cks (optional): An die Nachricht kann auch eine Kontrollsumme angefügt werden.

COMM-Aufgaben

  • Initialize: Muß man hier nicht näher beschreiben, kann je nach Hardware sehr unterschiedlich ablaufen.
  • Shutdown: Auf einem Controller kann das wohl entfallen, bei einem PC sollten hier alle Ressourcen wieder freigegeben werden.
  • Send: Bei größeren Systemen mit mehr SRAM werden wohl die bereitgestellten Daten mit Adresse und Länge übergeben werden, bei kleinen Systemen könnte das auch byteweise gewissermaßen on-the-fly geschehen. Bei Bus-Verbindungen muß entweder die physikalische "NODE" Adresse des Zielsystems angegeben werden. Es können aber die Nachrichten auch als "Broadcast" an alle verschickt werden, wenn sich ohnehin nur der Partner rührt, der durch die enthaltene Ziel-Adresse angegeben ist.
  • Receive: Nach Möglichkeit sollte das wohl freilaufend asynchron erfolgen können. Bei kleinen Systemen mit wenig Buffer kann es auch sinnvoll sein, den Comm-Partnern erstmal eine "Ready" Message zu senden, damit alle wissen, daß man empfangsbereit ist.

Jedenfalls ist zu einem Zeitpunkt dann eine komplette Message empfangen worden. Und nun ruft das COMM-Modul die Schicht darüber, den "Dispatcher" auf, damit die Nachricht weitergibt. Wenn der fertig ist, sollte der inzwischen belegte Buffer wieder für neue Nachrichten zur Verfügung stehen.


Transparente Messages über UART

Der Forderung nach transparenten Daten und dem damit verbundene Verlust der üblichen Steuerzeichen kann man auf verschiedene Weise Rechnung tragen

  • 9-Bit Datenformat. Dieses 9.Bit zeigt an, daß die 8 anderen Bits ein Kontrollzeichen darstellen. Bei 0 sind es normale Daten.
  • 8-Bit Format, aber Umkodierung. z.B. BASE64, ein gängiges Verfahren für die Übertragen von Binärdaten im Internet und Mail
  • Verwendung der RS232 Steuerleitungen.
  • Byte Stuffing

Alles davon hat Vor- und Nachteile. Wenn man die Daten umkodiert, hat man den Vorteil, wieder die ASCII-Steuerzeichen verwenden zu können. Der Nachteil: es sind mehr Bytes je Message zu übertragen. Ähnliches gilt für die 9-Bit Variante und auch das Byte-Stuffing. Die RS232 Steuerleitungen brauchen wiederum eine Hardware-Erweiterung.

DISPATCH

  • Destination: Das ist die Ziel-Angabe. Nun würde eine Nachricht auch richtig ankommen. Es ist gut, gleich nach dem Start diese Angabe zu machen. Denn dann kann jeder Netzwerkteilnehmer sofort erkennen, ob er angesprochen wird und anderenfalls alles, was da kommt, bis zum nächsten Start ignorieren. Das ist am wenigsten belastend, und wird bei den meisten Netzwerken so gemacht.

Um aber z.B. eine Bestätigung zurückzusenden, wird wohl auch eine Angabe zur

  • Source erforderlich. Das ist die äquivalente Absender-Adresse als Backlink.

Das Wichtigste an einer Adresse ist wohl die Eindeutigkeit. So gesehen ist jede Nummer recht, wenn sie den Teilnehmern bekannt ist. Aber für größere Systeme kann eine Strukturierung günstig sein.

  • Node bezeichnet einen bestimmten Rechner, also einen PC oder eine Microcontroller (da gibt es aber unterschiedliche Terminologien).
  • Class bezeichnet eine Modul- oder GeräteKlasse
  • Ident ist dann eine spezifische Ausprägung.

Beim Absender kann es auch notwendig sein, irgendwelche "Tags" einzufügen, damit bei einer Rückantwort der Absender eine Zuordnung treffen kann. Nicht immer ist ja das Sende-Empfangsverhältnis 1:1.

  • Data: auch auf dieser Ebene sind das reine Nutzdaten.


DISPATCH-Aufgaben

Shutdown braucht wohl nicht besprochen zu werden.

  • Initialize: Was der Dispatcher zur Arbeit braucht, sind einige Tabellen. Er muß die empfangenen Modul-Adressen umsetzen können auf eine CALL-Entry-Adresse und einen Verweis auf die privaten Daten dieses Modules.
    • Bei einem PC kann die Initiative auch von den einzelnen Modulen ausgehen, die durch einen "RegisterCallback" Aufruf an den Dispatcher ihre Adresse und den DatenVektor hinterlegen. Bevor sie das nicht getan haben, sind sie eben nicht da.
    • Auf den MC werden diese Tabellen und Verweise wohl schon im Source-Programm festgelegt werden, da hier zur Laufzeit wohl nicht mit einer Dynamik gerechnet werden muß
  • Send: Auch der Dispatcher braucht zum Senden die User-Daten, als Liste oder gesamt, das kann verschieden gemacht werden. Dazu natürlich die Zielangabe und etwas, mit dem eine Rückantwort mittels der ob. genannten Tabelle zugeordent werden kann. Wir haben ausgeführt, daß für Rückantworten einfach Ziel und Absender vertauscht werden. Die Rückadresse braucht also nur beim Absendersystem wirklich eine Bedeutung zu haben. Wenn das Comm-Modul on-the-fly arbeitet, muß das natürlich in der Schnittstelle berücksichtigt werden.
  • Receive: Synchron oder asynchron. Bei einem Aufruf durch das Comm-Module, daß Daten hier sind, werden jedenfalls mittels der Zieladresse in der Mapping-Table Call- und Daten-Vektor gesucht. Zusammen mit einem Verweis (Adresse, Länge) auf die Userdaten in der Message kann nun das Modul gerufen werden.

Applikations-Schnittstelle

Wenn von der Applikations eine Sendung veranlaßt werden soll, ist offensichtlich erforderlich

  • Eine vollständige Zielangabe.
  • Die Absenderangabe, eventuell mit einen "Tag" um auch diese spezielle Message eindeutig zu machen.

Die "Node"-Angabe kann wohl entfallen, denn das Kommunikationsmodul wird wohl wissen, auf welchem Rechner es sich befindet.

  • Fields/Daten: Das sind die eigentlichen "Nutz"-Daten, deren Inhalt, Aufbau und Bedeutung nur dem eigentlichen Sender und Empfänger bekannt sein müssen. Ob diese Daten gleich gesamt übergeben werden oder in einer Feld-Liste, kann beliebig gestaltet werden.

Wenn es wundert, daß der Begriff "CMD" hier nirgends auftaucht: Es hat für den Transport von Messages eigentlich keine Bedeutung, denn eine Nachricht kann man so oder so immer nur weiterleiten. Dadurch ist es sinnvoll und flexibler, eine CMD-Feld innerhalb der User-Fields anzusiedeln.

Spezielle Applikationen

Wie schon oben erwähnt, kann es sinnvoll sein, einige spezielle Module anzuwenden, die der Betrieb sicherer und vielleicht auch einfacher machen.

  • PING

Eine Art Anwesenheitskontrolle. Kann auch leicht mit der allgemeinen "Timeout" Funktionalität verbunden werden. Auch ein Timestamp könnte damit verteilt werden.

  • Enumerator/Enlisten

Beim Startup (oder auf Anforderung) sendet jedes System eine Liste mit den aktiven Module, eventuell mit einer "Kurz-Adresse", der dem Dispatcher die Tabellenarbeit erleichtert. DIe Gültigkeit dieser "short-cuts" muß natürlich gewährleistet sein (Änderung durch Umprogrammieren eines Controllers). Das kann geschehen, indem jedes System eine "Session"-Nummer (im EEPROM) führt. Die wird bei jedem Start oder Änderung inkrementiert. Hat ein anders System sich die letzte Nummer gemerkt, kann es durch die Unstimmigkeit die Änderung erkennen und eine aktuelle Liste anfordern.

Gateways

Ein Gateway ist ein Übergang zwischen Netzwerken, die völlig unterschiedlich funktionieren und auch andere (Netzwerk-)Begriffe haben. Im Zusammenhang mit einer Vernetzung zwischen Controller und PC kann es sinnvoll sein,

  • auf einem oder mehreren PC einen eigenständigen Prozess zu implementieren, der das Controller-Netz als Server abbildet.
  • die verfügbaren Controller und die Geräte darauf werden durch IP-Sockets und Ports abgebildet.
  • Die eigentlichen PC-Applikationen zur Kontrolle oder Darstellung können ein oder mehrere Programme sein, die den Traffic als IP-Sessions über eines oder mehrere Ports abwickeln.
  • Der Vorteil wäre die Plattform- und Sprachunabhängigkeit, denn Kommunikation über Sockets werden überall unterstützt.

Autor

Siehe auch


LiFePO4 Speicher Test