LIN-Bus-Unterstützung für MKT-View III/IV
Autor: Wolfgang Büscher, MKT Systemtechnik
Datum: 2016-02-26 (ISO 8601)
Quelldatei ("Master"): <WoBu><ProgrammingTool>..help\LIN_Bus_49.htm
Online: www.mkt-sys.de/MKT-CD/upt/help/LIN_Bus_49.htm
Inhalt
- Einleitung
- LIN-Bus-Konfiguration im Programmiertool
- Zusammenspiel von LIN-Bus und dem Script (in der Applikation)
- Siehe auch (Links zu weiteren Dokumenten):
-
Handbuch zum Programmiertool : 'Display-Variablen mit Anbindung an openABK',
Stichwort-Verzeichnis ('von A bis Z'),
Feature Matrix (mit Übersicht in welchen MKT-Geräten ein LIN-Bus-Monitor, Slave oder Master enthalten ist),
Wikipedia : Grundlagen zum Thema 'Local Interconnect Network' (LIN).
1. Einleitung
Dieses Dokument beschreibt die LIN-Bus-Funktionalität, die in verschiedenen
(aber nicht allen) programmierbaren
Anzeige-Geräten von MKT Systemtechnik optional zur Verfügung steht.
LIN (Local Interconnect Network) ähnelt in einigen Punkten dem CAN-Netzwerk, basiert aber (bis auf das 'Break-Feld') auf einer
einfachen UART-Schnittstelle (Universal Asynchronous Recever / Transmitter). Da (im Gegensatz zu CAN) nahezu jeder Mikrocontroller
mindestens eine UART-Schnittstelle enthält, ist LIN (als Slave) kostengünstig implementierbar. Der Konfigurationsaufwand auf der
Master-Seite ist allerdings nicht zu unterschätzen.
In jedem LIN-Bus-Frame ("Rahmen") ist ein Identifier, und ein bis zu 8 Bytes großes Datenfeld enthalten. Aufgrund dieser Ähnlichkeit
zwischen LIN und CAN wird im MKT-View (und ähnlichen Anzeigegeräten von MKT) auf der Applikationsebene für beide Bussysteme
die gleiche Funktionalität verwendet:
- Empfangene Frames werden, abhängig vom Identifier (6 Bit für LIN, 11 oder 29 Bit für CAN) in 'Signale' zerlegt
- Jedem im Frame enthaltenen Signal kann eine Display-Variable zugeordnet werden
- Jede mit CAN oder LIN verbundene Display-Variable enthält eine Beschreibung des Frame-Aufbaus
- Bei CAN stammt diese Beschreibung i.A. aus einer DBC-Datei
- Bei LIN stammt diese Beschreibung evtl. aus einer LDF-Datei
(geplant aber bislang nicht realisiert: Import von LDF, ähnlich wie DBC, im UPT-Programmiertool) - Notfalls kann der Aufbau eines LIN-Frames auch wie hier beschrieben direkt
im Programmiertool eingegeben werden
Um eine RS-232-kompatible Schnittstelle 'als LIN-Bus' nutzen zu können, ist ggf. ein Pegelwandler erforderlich.
Bei RS-232 erscheint ein logisches '0'-Bit als positive Spannung am 'TXD'-Ausgang des Senders.
Bei LIN wird ein logisches '0'-Bit als 'dominantes Signal' ausgegeben, indem der Sender die LIN-Bus-Leitung per Transistor auf Masse zieht.
Am Ausgang des RS232/LIN-Adapters erscheint das LIN-Signal daher 'positiv' (logisch '0' = 0 Volt, logisch '1' = ca. 12 Volt, je nach Bordspannung).
Ein geeigneter RS232/LIN-Adapter (passend zum MKT-View III / IV) kann ggf. über MKT Systemtechnik bezogen werden.
2. LIN-Bus-Konfiguration im Programmiertool
2.1 Verknüpfen von LIN-Bus-Signalen mit UPT-Display-Variablen
(Die LIN-Bus-Anbindung an UPT-Variablen war 2016 in Planung; mangels Interesse an der Option 'LIN' wurde der Support im Programmiertool aber nicht weiter entwickelt.)
2.2 Optionen (Einstellungen) für die LIN-Bus-Schnittstelle(n)
Bei neueren Geräten (z.B. MKT-View III / IV) stehen zwei asynchrone serielle Schnittstellen zur Verfügung, die prinzipiell auch als LIN-Bus-Schnittstellen geeignet sind.
Dazu ist allerdings ein externer Pegel-Konverter erforderlich, da weder die Schnittstelle mit 'RS-232'-Pegel, noch die serielle 'GPS-Schnittstelle' (im MKT-View III/IV) mit dem LIN-Bus kompatibel sind.
Abbildung 1: Konfiguration der logischen Schnittstelle 'CAN4' als LIN-Bus im Programmiertool
- Hinweis
- Serielle Schnittstellen, die wie oben beschrieben 'als LIN-Bus' betrieben werden,
sollten von der Applikation nicht mit den
Funktionen zum Zugriff auf die serielle Schnittstelle
umkonfiguriert werden.
Die Zuordnung von 'logischen' CAN-Ports zu 'physikalischen' als LIN-Bus nutzbaren seriellen Schnittstellen kann gegebenenfalls auch am Gerät im Setup kontrolliert werden. Rufen Sie dazu im Setup den Eintrag 'User Settings' .. 'more CAN settings' auf. Wenn das Gerät neben CAN auch LIN unterstützt, finden Sie unterhalb der Einstellungen für CAN1 und CAN2 auch z.B. die folgenden Einträge für CAN3 und CAN4 (die nur bei manchen MKT-Views auch als LIN-Port nutzbar sind) :
nach dem Laden der weiter oben per Programmiertool erstellten Konfiguration.
Der eingestellte Wert '1' bedeutet in diesem Zusammenhang 'Ja', '0' = 'Nein'.
Durch die oben beschriebene Verknüpfung der Schnittstelle "CAN4" (eventuell auch "CAN3") mit einer seriellen
Schnittstelle als LIN-Interface werden fehlerfrei empfangene LIN-Frames automatisch auch an den
CAN-Logger / CAN-Snooper weitergegeben.
Diese ursprünglich nur für den CAN-Bus entwickelten Zusatzfunktionen sind daher auch als LIN-Logger bzw. LIN-Monitor
einsetzbar. Ein kleiner 'Schönheitsfehler' sind dabei noch die z.T. als "CAN3" / "CAN4" angezeigten LIN-Frames.
Ferner muss der LIN-Frame-Decoder z.T. 'raten', aus wievielen Datenbytes ein empfangener Frame besteht,
denn im Gegensatz zu CAN (mit dem "Data Length Code") fehlt bei LIN-Frames die Angabe der Größe des Datenfelds
völlig. Die Entwickler der LIN-Spezifikation gingen wohl davon aus, dass der Empfänger eines LIN-Frames
immer die Länge eines empfangenen LIN-Frames 'kennt' (anhand des Frame-Identifiers).
Ein nicht konfiguierter LIN-Bus-Monitor, der zu Testzwecken an ein LIN-Netzwerk ("Cluster") angeschlossen wird,
hat dieses 'Wissen' nicht. Solange nicht mit den im folgenden Kapitel vorgestellten LIN-spezifischen
Script-Befehlen etwas anderes eingestellt wurde, geht die Firmware im MKT-View davon aus, dass empfangene LIN-Frames
genau acht Nutzdatenbytes enthalten.
2.3 Testen der LIN-Bus-Schnittstelle(n)
Zum Testen der LIN-Bus-Schnittstelle (bzw des externen Pegel-Konverters) eignet sich z.B. die im Programmiertool enthaltene Applikation script_demos/LINbusT1.cvt.
Laden Sie diese in zwei geeignete MKT-Views. Verbinden Sie beide per LIN. Starten Sie auf dem einen Gerät die 'Slave'-Emulation (Button 'Slave'), und auf dem anderen Gerät den 'Master mit SCAN-Funktion' (Button 'Scan').
Mit etwas Glück kann als Ersatz für das eine Gerät auch der PC verwendet werden, mit dem im Programmiertool laufenden Simulator. Ein präzises Timing (im Bereich weniger Mikrosekunden) für LIN-spezifischen Besonderheiten wie dem Senden von BREAK und der Slave-Response (nachdem der Slave vom Master zum Senden eines Datenfelds aufgefordert wurde) ist unter Windows nur schwer realisierbar. Das von der LIN-Spezifikation geforderte Timing ist daher nur mit dem 'echten' Gerät erreichbar.
LIN-Bus-Timing mit vom Master gesendeten LIN-Header (gelb, mit RS-232-Pegeln)
und der vom Slave (MKT-View IV) gesendeten Antwort (blau).
LIN-Frames können dort (mit der unten gezeigten Einstellung) wie CAN-Messages angezeigt werden.
|
→ |
|
→ |
|
→ |
|
3. Zusammenspiel von LIN-Bus und Script
Da LIN-Bus-Frames ähnlich wie CAN-Bus-Telegramme einen eindeutigen Identifier, und bis zu acht Datenbytes enthalten können, wird zur Kommunikation per LIN (statt CAN) -bis auf eine Ausnahme- keine spezielle API (Application Interface) verwendet.Stattdessem können LIN-Frames (nicht "LIN-Messages"! (*) ) mit den gleichen Script-Funktionen und Event-Handlern gesendet und empfangen wie CAN-Telegramme. Zur Unterscheidung zwischen CAN und LIN dienen die höchstwertigen Bits (Bit 31 und 30) im Identifier-Feld des Script-Datentyps tCANmsg :
- durch eine bitweise ODER-Verknüpfung des LIN-Frame-Identifiers (0..63) mit der Konstanten cCanIdBit_LIN (0xC00000000)
werden die oben genannten höchstwertigen Bits gesetzt; - wie in Kapitel 2.2 erläutert wurde, muss eine der seriellen Schnittstellen
per Konfiguration (im Programmiertool) für die Verwendung als LIN-Bus-Port konfiguriert werden; - eine derart initialisierte Variable vom Typ tCANmsg kann zum Senden
an die Funktion can_transmit übergeben werden.
Statt einer CAN-Message wird dann ein LIN-Frame gesendet.
(*) Man beachte die unterschiedliche Bedeutung von 'frames' und 'messages' in der LIN-Spezifikation !
Ein 'Frame' ist der 'Transport-Rahmen', eine 'Message' wird nur im Zusammenhang mit der Transportschicht (transport layer) verwendet.
3.1 Senden eines (kompletten) LIN-Frames
Hinweis: Das Senden eines 'kompletten' LIN-Frames (mit 'Header' und Datenfeld und Prüfsumme) ist nur für einen LIN-Master zulässig. Ein LIN-Slave darf lediglich Datenfelder senden, nachdem er vom Master dazu aufgefordert wurde ! Details zu dieser LIN-spezifischen Besonderheit folgen in Kapitel 3.3 .
Zum Senden eines kompletten LIN-Frames verwenden Sie die auch für CAN geeignete Funktion can_transmit.
Beispiel zum Senden eines LIN-Frames per Script :
//----------------------------------------------------------------------------
proc LIN_SendRequest(int lin_frame_id)
local tCANmsg myFrame;
myFrame.id := lin_frame_id | cCanIdBit_LIN;
myFrame.len := 8;
myFrame.dw[0] := 0x44332211; // first four bytes in the data field (as a 32-bit 'DWORD')
myFrame.dw[1] := 0x88776655; // last four bytes in the data field (as a 32-bit 'DWORD')
can_transmit( myFrame ); // if LIN is supported by the hardware, use the CAN-API for LIN !
endproc; // LINSendRequest()
Bei LIN darf nur der 'Master' auf eigene Initiative hin senden. Alle Slaves dürfen nur nach Aufforderung senden,
d.h. direkt nachdem sie vom LIN-Master dazu aufgefordert sind. Der (LIN-Frame-)Identifier wird auch in dem Fall
nur (aussschliesslich) vom Master 'auf den Bus gelegt'; der (oder die) angesprochenen Slaves müssen innerhalb
einer genau festgelegten Zeitspanne ihr Datenfeld.Details dazu finden Sie in der LIN-Spezifikation (ehemals bei www.lin-subbus.org), z.B. in V2.2A auf Seite 34 ... 36, Kapitel 2.3.3.2, "Event Triggered Frame" :
Auch bei 'Event Triggered Frames' bestimmt der Master, wer / wann / was sendet !
Die Implementierung eines 'kompletten' LIN-Masters in der Terminal-Firmware war bei der Erstellung dieser Beschreibung noch nicht vorgesehen. Das Senden von LIN-Frames ist zwar möglich, die Komplexität eines LIN-Masters geht aber weit darüber hinaus (Stichwörter: Scheduling, Signal Management, Task Behaviour, Collision Handling, ....)
Um einen einfachen LIN-Bus-Slave auch im Script implementieren zu können, wurden die folgenden Kapitel beschriebenen LIN-spezifischen Befehle in der Script-Sprache implementiert.
3.2 Empfang eines (kompletten) LIN-Frames
Zum Empfangen kompletter LIN-Frames (mit 'Header' und Datenfeld und Prüfsumme) verwenden Sie die auch für CAN geeignete Funktion can_receive.
3.3 LIN.SetResponse() : Vorbereiten einer vom LIN-Slave zu sendenden Antwort
Dieser Befehl ist ausschliesslich für einen 'per Script' implementierten LIN-SLAVE einsetzbar.Durch den Aufruf wird dem LIN-Bus-Treiber mitgeteilt, welche Daten als Slave Response gesendet werden sollen, wenn ein externer LIN-MASTER den Slave durch Senden eines bestimmten Frame-Identifiers (im Header) dazu auffordert. Die folgende Abbildung verdeutlicht den zeitlichen Ablauf:
Struktur eines LIN-Frames (nach LIN-Spezifikation Rev. 2.2A, Kapitel 2.3.1, Seite 29) "break "inter-byte "response space" delimiter" space" . "Break . . "Protected . maximal 8 Field" . Sync field . Identifier" . Datenbytes Prüfsumme |<----->|. |<------------->| . |<------------->| . |<-------->| |<---------->| rezessiv ____ __ _ _ _ _ ___ _ _ _ _ _ _ _ _ ___..............._ _ _ _ _ ____ (logisch "H") | min. | |s| | | | | | | | |s| |s| | | | | | | | |s| :::::::::: s |s| | | | |s| | 13 | |t|b|b|b|b|b|b|b|b|t |t|b|b|b|b|b|b|p|p|t :::::::::: t |t|b|b|..|b|t | Bits | |a|0|1|2|3|4|5|6|7|o |a|0|1|2|3|4|5|0|1|o :::::::::: o |a|0|1| |7|o dominant |_______| |_| |_| |_| |_| |_|p |_|_|_|_|_|_|_|_|_|p :::::::::: p |_|_|_|..|_|p (logisch "L") ^ 0x55 ^ 0x3D + Parity ^ ^ ^ /|\ /|\ /|\ /|\ /|\ | | | | | (a) (b) (c) (d) (e) |<------------ vom LIN-Master gesendet ------------->| |<--- Antwort vom SLAVE -->| |<-- "T_frame,max" = 9 ms für eine LIN-Botschaft mit 8 Datenbytes bei 19.2 kBit/s -->| |
- (a) Ende des vom LIN-Master gesendeten, mindestens 13 Bit langen 'Break'-Felds.
- (b) Ende des Sync-Felds, 1 Startbit, 8 Datenbits (Konstante 0x55), 1 Stopbit.
- (c) Ende des Frame-Identifiers. Der adressierte Empfänger (LIN-Slave) erkennt daran, ob und wie viele Datenbytes gesendet werden müssen.
- (d) Der Slave (in der Lin-Spezifikation: "die Slave-Task") beginnt mit dem Senden des Datenfelds.
- (e) Der Slave sendet das Stopbit nach der Prüfsumme. Der LIN-Bus ist wieder 'frei' (rezessiver Zustand).
- (b) Ende des Sync-Felds, 1 Startbit, 8 Datenbits (Konstante 0x55), 1 Stopbit.
Würde das vom Slave zu sendende Datenfeld (d) erst in dem Moment per Script erstellt, in dem der vom Master gesendete Frame-Identifier empfangen wurde (c), dann stünden im Script maximal etwa 2.5 Millisekunden (Differenz zwischen "T_frame,max" und "T_frame,min") dafür zur Verfügung. Selbst ein einzelner Task-Wechsel könnte diese Zeit überschreiten. Abhilfe:
Der Slave stellt die von ihm zu sendenden Daten bereits vorher zusammen (z.B. nach dem Empfang eines entsprechenden 'Master-Requests' mit dem Frame-ID 0x3C), und gibt dabei den Frame-ID an, bei dessem Empfang das Datenfeld gesendet werden soll (z.B. 'Slave-Response' mit dem Frame-ID 0x3D).
Ein Beispiel für den Einsatz der Funktion LIN.SetResonse() finden Sie in der Applikation script_demos/LINbusT1.cvt .