ISOTP
Das wichtigste aktuelle Transportprotokoll für CAN ist ISOTP (ISO 15765-3). Hier werden vier verschiedene Botschaftstypen definiert:
- Single-Frame
- First-Frame
- Consecutive-Frame
- Flow-Control
Der Single-Frame wird dann verwendet, wenn die Botschaft kleiner gleich 7 Bytes lang ist, siehe Abbildung.
ISOTP - Single-Frame |
Grund: Eine CAN-Botschaft kann insgesamt 8 Byte fassen und das erste Byte dient als Protokollsteuerinformation PCI. Bei einem Single-Frame werden die ersten vier Bits des PCI-Bytes auf 0 gesetzt. Die zweiten vier Bit dieses Bytes enthalten die Datenlänge der folgenden Daten. Der Nutzdatenblock kann nun zwischen einem und sieben Byte groß sein.
ISOTP - First-Frame |
Sollte eine Diagnosebotschaft aus mehr als 7 Datenbytes bestehen, wird eine Segmentierung benötigt. Dazu wird als erste Botschaft ein sogenannter First-Frame versendet, siehe Abbildung. Hier gibt es ebenfalls ein PCI. Es besteht jedoch aus zwei Bytes. In den ersten 4 Bit des ersten Bytes steht der Wert 1. Daraus erkennt der Empfänger einen First-Frame. Die restlichen vier Bits und das gesamte nächste Byte zusammen, also insgesamt 12-Bit, entsprechen der Anzahl der Daten der gesamten Diagnosebotschaft. Insgesamt also maximal 4095 Byte. Die restlichen sechs verbleibenden Bytes dieser ersten Botschaft werden mit Daten gefüllt.
ISOTP - Consecutive-Frame |
Danach folgen so viele Consecutive-Frames bis die gesamte Botschaft versendet wurde. Im Consecutive-Frame wird nur noch das erste Byte als PCI-Byte eingesetzt. Mit den oberen vier Bits auf den Wert 2 und den folgenden vier Bit mit einer so genannten Sequenznummer. Diese zählt einfach bei 1 beginnend die einzelnen Consecutive-Frames. Und weil wir nur vier Bit zur Verfügung haben, wird Modulo 16 gerechnet. Der erste Consecutive-Frame hat die Sequenznummer eins und so weiter bis fünfzehn. Dann geht es wieder bei null los.
Diese drei Botschaftstypen werden vom Sender gesendet. Der vierte Botschaftstyp, der so genannte Flow-Control-Frame, wird im Gegensatz zu den Vorigen vom Empfänger versendet. Der Flow-Control-Frame besteht aus drei Bytes, die zusammen ein PCI bilden. Das erste Byte beginnt in den oberen 4 Bits mit dem Wert 3, der anzeigt, dass es sich um einen Flow-Control handelt. Dann folgt der Flow-Status. Dieser Flow-Status kann entweder 0 sein. Das zeigt dem Sender, der den Datenblock versenden will, dass er tatsächlich senden kann. Der Wert kann aber auch eins sein. Damit zeigt der Empfänger an, dass er noch Zeit braucht und dass der Sender warten möge. Mit dem Wert zwei kann der Empfänger anzeigen, dass es bei ihm zu einem Speicherüberlauf gekommen ist, dass der Datenblock ignoriert wurde und das Senden gegebenenfalls wiederholt werden muss.
ISOTP - Flow-Control |
Mit dem zweiten Byte, der Blockgröße, wird der Sender darüber informiert, wie viele Consecutive-Frames er hintereinander senden darf, bevor der Empfänger wieder Zeit zur Verarbeitung braucht. Als letztes zeigt die Minimum-Separation-Time den Mindestabstand zwischen aufeinanderfolgenden Consecutive-Frames, den der Sender einhalten muss. Der Gesamtablauf wird an folgendem kleinen Beispiel deutlich, siehe Bild:
{{{3}}} |
Wir nehmen an, dass wir eine Diagnosebotschaft mit 35 Byte haben und der Empfänger lediglich 24 Byte puffern kann. Der ganze Ablauf beginnt vom Sender aus mit einer First-Frame-Botschaft. Sie hat in den obersten 4 Bits eine eins gesetzt. Danach folgen zwölf Bits, die die gesamte Datenlänge anzeigen. Da wir hier 35 Bytes haben, dies entspricht 0x23 hexadezimal, folgt hier der Wert 0x23. Danach kommen die ersten 6 Datenbytes.
Der Empfänger reagiert auf den First-Frame, indem er einen Flow-Control-Frame zurücksendet, in dem die obersten 4 Bit als Anzeige für den Flow-Control auf 3 gesetzt sind. Wir nehmen an, dass der Empfänger in der Lage ist, 24 Byte zu puffern. Er ist außerdem bereit, Daten zu empfangen. Daher wird in den untersten 4 Bits des ersten Bytes ClearToSend auf 0 gesetzt. Das folgende Byte enthalt die Anzahl der Blöcke. Dies sind hier 3 Blöcke (=24/8). Im letzten Byte wird hier die Minimum-Separation-Time auf zehn Millisekunden (=0x0A) eingestellt.
Auf den Flow-Control-Frame reagiert der Sender indem er beginnt, seine Consecutive-Frames mit den restlichen Daten zu senden. Der Consecutive-Frame beginnt wieder mit einem PCI-Byte, in dem die oberen 4 Bits auf 2 gesetzt sind. Dann folgt die Sequenznummer eins, da es der erste Consecutive-Frame ist. Die restlichen 7 Byte der CAN-Botschaft werden mit den nächsten 7 Nutzdatenbytes gefüllt. Da wir eine Blockgröße von insgesamt drei haben, geht dieser Ablauf unter Einhaltung der Separation-Time von zehn Millisekunden so weiter: Der nächste Consecutive-Frame folgt, die Sequenznummer hat sich geändert und die 7 nächsten Datenbytes werden gesendet. Dann folgt der dritte Consecutive-Frame mit ebenfalls wieder 7 Datenbytes, die Sequenznummer hat sich auf 3 erhöht.
Da die Blockgröße auf drei festgelegt wurde, kann nun kein weiterer Consecutive-Frame folgen. Der Sender wartet darauf, dass der Empfänger ihm jetzt über einen zweiten Flow-Control-Frame mitteilt, dass das Senden weitergehen kann. Hier stehen nun in unserem Beispiel dieselben Werte wie im ersten Flow-Control-Frame. Theoretisch könnte der Empfänger an dieser Stelle zum Warten auffordern oder er könnte mit einer anderen Blockgröße oder einer anderen Separation-Time arbeiten.
Nachdem der eigentliche Sender nun diesen zweiten Flow-Control-Frame empfangen hat, setzt er das Senden des Datenblocks fort. Es folgt ein weiterer Consecutive-Frame mit der Sequenznummer 4 und ein letzter mit der Sequenznummer 5. Insgesamt sind damit die 35 Datenbytes erfolgreich versendet worden.
Der Ablauf dieser segmentierten Datenübertragung ist doch einigermaßen komplex, deswegen sieht das Protokoll eine Reihe von Fehlererkennungs- und Überwachungsmechanismen vor, die nachfolgend stichwortartig aufgelistet werden:
Timeout Bedingungen
- Für den Sender: Abstand zwischen der FF-Botschaft und der FC-Antwort: max. 1s
- Für den Empfänger: Abstand zwischen zwei CF-Botschaften: max. 1s
- Falls der Empfänger Zeit zur Verarbeitung benötigt, kann er mit einer Flow Control Botschaft mit Flow Status FS = Wait eine Pause erzwingen, bis er nach max. 1s mit einer weiteren Flow Control Botschaft zum Weitersenden oder erneut zum Warten auffordert
- Für Diagnosetester wird BS=0 und STMin=0 gefordert, d.h. Empfang auf der Testerseite effektiv ohne Flusssteuerung
Fehlererkennung
- Sender und Empfänger überwachen die segmentierte Übertragung durch die entsprechenden Timeouts, der Empfänger zusätzlich über die Sequenznummer
- Im Fehlerfall wird eine empfangene Botschaft ignoriert und die darüber liegende Schicht informiert.
- In der Transportschicht erfolgt keine Fehlerbehandlung, d.h. weder Sendewiederholung noch Fehlerbotschaft
Zu den Überwachungsmechanismen gehören eine Reihe von Zeitbedingungen, also Time-Out-Mechanismen. Zwischen First- und Flow-Control-Frame darf maximal ein zeitlicher Abstand von einer Sekunde liegen. Wenn also der Empfänger nicht schnell genug mit einer Flow-Control-Frame-Botschaft reagiert, weiß der Sender, dass etwas nicht in Ordnung ist. Umgekehrt überwacht der Empfänger den zeitlichen Abstand der Consecutive-Frames. Auch da darf maximal eine Sekunde als Abstand dazwischen liegen. Dazu kommt bei der segmentierten Übertragung, dass die Segmentnummern überwacht werden. Falls es zu einem Fehler in den Segmentnummern oder einem Timeout kommt, wird die empfangene Botschaft einfach ignoriert. Ob der Sender die fehlgeschlagene Übertragung wiederholt, ist nicht in der Transportschicht festgelegt, sondern muss auf der Applikationsebene geklärt sein.
Siehe auch