Aus RN-Wissen.de
Version vom 10. Oktober 2006, 12:50 Uhr von PicNick (Diskussion | Beiträge)

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

Erzielt werden soll eine sichere, transparente Daten-Übertragung zwischen µCs und PCs sowie uCs bzw PCs untereinander. Die geplanten Übertragungsmedien sind im Moment:

  • UART (RS232), vor allem zur Anbindung von uCs an PCs
  • LAN (IP), vor allem zur Anbindung von PCs untereinander (z.B. Steuerrechner - GUI)

Dabei betrachtet dieses Projekt die IP-Funktionalitäten als "black-box" und alles unterhalb der üblichen Schnittstelle (sockets) wird elegant als Level-0 betrachtet.

  • i2c (spätere Ausbaustufe), vor allem zur Anbindung von uCs untereinander

Ziel der Schicht 0 muß es sein für die oberen Schichten Datenpakete mit einer bestimmten Länge zu übertragen. Dabei sollen die oberen Schichten nichts über das Medium (UART, LAN, i2c) wissen müssen. Da die Datenbytes alle Werte von 0-255 einnehmen können, muß die jeweilige Schicht geeignete Kontrollmechanismen definieren.

Level-0 UART (point-to-point)

Die Implementierung der Schicht 0 hängt stark von den verwendeten Medien ab. Die Arbeitsgruppe ist übereins gekommen, Daten über den UART wie folgt zu übertragen: Die Nachrichten wird mit einem STX-Zeichen begonnen, dann die Daten, eine Kontrollsumme und als Abschluß ein ETX-Zeichen.

START....daten....CHECK.ENDE

Jetzt kann natürlich zwischen den Daten jederzeit ein Zeichen drin sein, das denselben Wert hat wie eine Start- oder Endekennung. Daher wird "Bytestuffing" verwendet

Byte-Stuffing

Es gibt drei besondere Zeichen

  • STX als Start-Kennung
  • ETX als Ende-Kennung UND
  • PFX als Daten-Kennung (durch dieses Zeichen wird das nachfolgende zu einem normalen Datenbyte)

Am besten ein Beispiel:

Oben ist eine Nachricht, die ein Zeichen enthält, das denselben Wert hat wie die Endekennung (ETX) Bis zu dem Zeichen werden die Daten normal übertragen. Dann wird aber das PFX eingefügt und danach der Rest.


Stuffing.png

Der Empfänger findet das Startzeichen STX und beginnt, die Zeichen nach der Reihe zu übernehmen. Dann entdeckt er PFX. Das speichert er zwar nicht, aber dadurch enterpretiert er das Folgezeichen, das ja eigentlich eine Endekennung wäre, nicht als solches und gibt es zu den normalen Daten dazu. So gehts weiter bis zum Ende ETX, das ja "blank" dasteht, also sozusagen "echt" ist.

Es ist immerhin möglich, daß ein Teilnehmer beim Empfangen irgendwie nicht gut drauf ist, und er erst genau zwischen PFX und Folgezeichen die Bytes wieder richtig mitkriegt. Er würde also denken, daß dieses Folgezeichen ein Kontrollzeichen ist und letzlich Müll empfangen. Für diesen Fall wurde vorgeschlagen, dieses Folgezeichen gleich überhaupt durch eine Addition unkenntlich zu machen. Derjenige, der das PFX mitgekriegt hat, weiß das ja und kann wieder subtrahieren, unser Schläfer weiß das aber eben nicht, kann aber auch kein (falsches) Steuerzeichen erkennen. Beim Wiedereinstieg an einer beliebigen anderen Stelle kann sowieso nicht Schlimmes passieren, denn bis zum nächsten un-prefixten STX wird ja alles ignoriert.

Kontrollsumme BCC

  • Beginnend mit NULL, werden alle Datenzeichen (ohne PFX, STX, ETX und andere Kontrollzeichen) mit Exklusiv-Oder "übereinandergelegt". Das Ergebnis hängt der Sender an die Daten an. Es wird zusammen mit den Daten geprefixed.
  • Der Empfänger tut das Gleiche, dann aber vergleicht er sein Ergebnis mit dem Prüf-Byte, das der Sender weggeschickt hat.

Stimmt das Prüfbyte nicht, wird die Nachricht verworfen. Das ist zwar auch nicht todsicher, aber immerhin beruhigend. Wenn sich das nicht bewährt, kann immer noch ein CRC-Verfahren festgelegt werden.

Praxis

  • Maximale Frame-Size
#define FRAME_C_MAX   127     

Das ist die maximale Netto-Länge zwischen STX und ETX, exklusive. Auch das scheint für µC etwas groß, aber es wird davon ausgegangen, daß die real benötigten Messages weit kürzer sein werden, d.h. das regelt sich vermutlich von selbst durch die Vereinbarungen und Restriktionen in den oberen Layern

  • Kontrollzeichen
#define CTL_M_MASK   0xF8 
#define CTL_M_ADON   0x08 
#define CTL_C_BASE   0xA8 
#define CTL_C_STX   CTL_C_BASE + 1 
#define CTL_C_ETX   CTL_C_BASE + 2 
#define CTL_C_PFX   CTL_C_BASE + 3 
  • Code-Beispiel/Muster für Paket-senden

( transmit() stellt die Funktion für den tatsächlichen physischen Output dar).

static unsigned char bTxBcc;            // Checksum für BCC 
// --------------------------------------------------------------
void TxStartFrame ( void )
{
  bTxBcc = 0
  transmit ( CTL_C_STX )                         
}
// --------------------------------------------------------------
void TxCloseFrame ( void )
{
  TxSendStuffByte ( bTxBcc )  // auch das BCC mit ev. prefixed werden
  transmit ( CTL_C_ETX )                         
}
// --------------------------------------------------------------
void TxSendFrameByte ( unsigned char bTxChar)
{
     bTxBcc ^= bTxChar
     TxSendStuffByte ( bTxChar ) 
}
// --------------------------------------------------------------
void TxSendStuffByte ( unsigned char bTxChar)
{
     if (bTxChar & CTL_M_MASK) == CTL_C_BASE) 
     { 
       transmit ( CTL_C_PFX )
       transmit ( bTxChar + CTL_M_ADON )      
     } 
     else 
     { 
       transmit ( bTxChar )        
     } 
}
  • Die entsprechende Empfangsroutine ist etwas komplexer und wird wesentlich mehr vom Geschick und den Gewohnheiten des Programmieres bestimmt.

LiFePO4 Speicher Test