Siehe auch: CAN-Tester Übersicht
Das Kommandoprogramm besteht im einfachsten Fall aus einer Reihe von CAN-Messages, die gesendet werden sollen.
Das Format ist normalerweise:
<CAN-Identifier> <Datenbyte0> <Datenbyte1> ... <Datenbyte7>
Der CAN-Identifier wird normalerweise in hexadezimaler Form erwartet. Moeglich
ist auch die dezimale Form, die durch ein vorgestelltes '#' gekennzeichnet
werden muss. Direkt nach dem Identifier kann ein
spezieller Suffix angegeben werden,
um z.B. auch bei einem Identifier <= 0x3FF diesen mit 29 Bit ("extended" frame) zu codieren,
oder um statt "Classic CAN" einen CAN-FD-Rahmen zu senden.
Die Datenbytes werden i.A. auch hexadezimal erwartet. Statt einfacher Zahlenwerte koennen auch beliebige Ausdrücke verwendet werden. Diese sollten in Klammern umschlossen werden, um Fehlinterpretationen auszuschliessen. Auch Variablen sind möglich (s.U.).
Statt einer CAN-Message kann eine Zeile auch eine Anweisung an den Kommando-Interpreter enthalten.
Anweisungen sind z.B. (vgl. komplette Befehlsübersicht):
A := 10*I;
CommPar := 0x1800; // OD-index for first TPDO communication parameter
PdoCobId[CommPar] := sdo.r( (CommPar).01, U32, 0);
Die Verzögerungszeit bei der Abarbeitung der Zeilen des Kommandoprogrammes kann im Systemmenü eingestellt werden. Sie sollte mindestens 5 ms (pro Zeile) betragen. Zusaetzliche Verzögerungen innerhalb des Kommandoprogramms koennen mit dem @delay - Befehl realisiert werden.
Zur Dokumentation des Kommandoprogrammes können Kommentare eingefügt
werden. Im Anlehnung an ASSEMBER beginnen Kommentare mit einem Semikolon;
C++-Freaks dürfen (seit August 2006) auch den doppelten Schrägstrich
( // ) als Anfang eines einzeiligen Kommentares verwenden.
Als 'Sprungziel' für manche Befehle dienen Label im Programmtext.
Als Label-Namen werden möglichst 'sprechende' Symbole verwendet, z.B. AnalogOutputTest.
Im Programmtext sind Labels an mindestens einem nachgestellten Doppelpunkt erkennbar.
Labels mit zwei nachfolgenden Doppelpunkten werden bei der Aufzählung
im Menü 'Run' .. 'Run from Label' bevorzugt. Solche Labels dienen als Startpunkt, wenn in
einer einzelnen Applikation (*.cts-Datei) mehrere Testabläufe implementiert sind.
Hier ein Beispiel aus der Applikation 'EaDIO8Test.cts' :
Kommandozeilen mit CAN-Telegrammen (als Text) führen zum Senden der
Telegramme in der Reihenfolge der Programmabarbeitung.
Das Format von CAN-Telegrammen im Kommandointerpreter ist normalerweise:
<CAN-Identifier> <Datenbyte0> <Datenbyte1> ...
<Datenbyte7>
Der CAN-Identifier wird normalerweise in hexadezimaler Form erwartet.
Möglich ist auch die dezimale Form, die durch ein vorgestelltes '#'
gekennzeichnet werden muss. Zwei einfache Beispiele:
Die Datenbytes werden i.A. hexadezimal erwartet. Statt einfacher Zahlenwerte
koennen auch beliebige Ausdrücke verwendet werden. Diese sollten in
Klammern umschlossen werden, um Fehlinterpretationen auszuschliessen. Auch
Variablen sind möglich (s.U.).
Ohne weitere Zusätze werden CAN-Telegramme mit Identifier <= 2047
als 11-BIT-Frames gesendet. Bei IDs >= 2048 ohne Zusatz (s.U.) wird
automatisch ein Telegramm mit 29-Bit-Identifier ("extended frame") gesendet.
Um definitiv unabhängig vom Zahlenwert des Identifiers 11- oder
29-Bit-Identifier zu senden, kann der Suffix ".s" (für Standard-Frames
mit 11 Bit-ID) bzw. ".x" (für eXtended-Frames mit 29-Bit-ID) verwendet
werden. Beispiele:
Hinweis: Bei der Anzeige im RX/TX-Fenster können 11- und 29-Bit-Identifer
wahlweise nur durch die Anzahl Ziffern unterschieden werden, der Suffix ".s"
oder ".x" (bzw. ".S" oder ".X" für CAN FD) ist dort optional.
Sowohl CAN-ID als auch Datenfeld kann -wie in den obigen Beispielen- als
einfache Konstante angegeben werden, es sind aber auch beliebige numerische
(geklammerte) Ausdrücke realisierbar.
Der optionale Suffix (z.B. ".w" oder ".iw") im CAN-Datenfeld hat folgende Bedeutung:
Die folgenden Kommandos und Funktionen sind im Interpreter des CAN-Testers
mindestens implementiert (darüberhinaus weitere Befehle, für
deren Dokumentation bislang die Zeit fehlte ;-) .
Sprünge, Schleife, Steuerung des Programmablaufes
Anzeige und Ausgabe
Numerische Funktionen
CAN-Senden und Empfangen (Decodieren einzelner CAN-Signale)
Siehe auch: "delay"-Kommando für eine einmalige
Wartezeit.
Sonderkommandos für CANopen
Beispiele für den Format-String:
Näheres siehe Handbuch eines beliebigen "C"-Compilers bei der Beschreibung
des " printf"-Befehls. Die Parameter sind immer 32-Bit-Integer-Zahlen, daher
die Eingabegrößen-Modifikation '%l' (kleines "L"). Beispiel:
Beispiele:
Zulässige Farbwerte : red, green, blue, yellow, white, black, oder
RGB-Farbmischungen als Integerwerte (z.B. 0x0000FF=Rot, 0x00FF00=Grün,
0xFF0000=Blau).
Keine weitere Dokumentation, weil dieser Befehl noch "in Arbeit" ist. Als
Vorlage für eigene Programme kann das Testprogramm "EaIP65Test" dienen,
in das benutzerdefinierte Fenster verwendet wird um den Bediener schrittweise
durch einen halbautomatischen Testablauf zu führen.
Hinweis: Nach dem Befehl "OpenWindow" druckt das Kommando
Beispiel: @A = canrx(0x181, 48, I16, 1234 )
Durchsucht den Empfangspuffer nach dem zuletzt empfangenen CAN-Telegramm
mit dem CAN-Identifier 0x181 (hexadezimal). Wurde ein entsprechendes Telegramm
im Puffer gefunden, wird ein vorzeichenbehafteter 16-Bit-Integerwert ("I16")
aus dem empfangenen Datenfeld gebildet, beginnend mit Bit 48 des CAN-Datenfeldes
(Bitzählung beginnt bei 0, ein Datenfeld mit 8 Bytes enthält Bit
0 bis 63). Die 16-Bit-Zahl wird als Funktionsergebnis zurückgeliefert,
und -in diesem Beispiel- an die Variable "A" zugewiesen.
Der im CAN-Tester verwendete Empfangspuffer fasst 1024 CAN-Telegramme. Dies
hat zur Folge, daß bei hoher CAN-Bus-Auslastung mit vielen verschiedenen
Identifiern das gewünschte Telegramm eventuell nicht mehr im Puffer
vorhanden ist, wenn das Interpreterprogramm die canrx-Funktion abarbeitet.
Für periodisch übertragene Signale (z.B. zyklisch gesendete
Prozessdaten) eignet sich diese Funktion allerdings sehr gut, auch für
den Einsatz im Watch/Plot-Fenster .
Siehe auch: Plot-Fenster zur Darstellung
des zeitlichen Verlaufs einzelner Signale in Echtzeit.
Diese Interpreterfunktionen können in der Zeile nach dem
'wcan'-Kommando verwendet werden, um auf das bei 'wcan'
empfangene Telegramm zuzugreifen. Die folgenden Funktionskomponenten sind
bislang implementiert (Stand 2006-03-31):
Verfügbare Befehle:
Beispiel: Ausschnitt aus einem Kommandoprogramm mit Parametrierung des
Scope-Fensters, inkl. Definition von vier Messkanälen :
Siehe auch: Beschreibung des
Plot-Fensters zur Darstellung des
zeitlichen Verlaufs einzelner Signale in Echtzeit.
Einige Interpreterbefehle (und -Funktionen) benötigen als Parameter
den Typ eines zu empfangenden oder zu sendenden Wertes. Dazu werden in erster
Linie CANopen-kompatible Datentypen eingesetzt. Der Interpreter erwartet
diese Typen in symbolischer Schreibweise (nicht als Zahlencode wie in der
CANopen-Spezifikation ! ! ).
Zur Zeit unterstützt werden :
Siehe auch:
Senden von CAN-Telegrammen aus dem Kommando-Interpreter
Beginnt eine Kommandozeile mit einer ZAHL (oder geklammerten numerischen Ausdruck),
so geht der Interpreter davon aus dass es sich um ein zu sendendes
CAN-Telegramm handelt.
07FF 01 02 03 04 05 06 07 08 ; hexadezimaler ID
#2047 01 02 03 04 05 06 07 08 ; dezimal geschriebener ID
07FF.s 01 02 03 04 05 06 07 08 ; senden mit 11-Bit-ID
07FF.x 01 02 03 04 05 06 07 08 ; senden mit 29-Bit-ID
N:=123 : X:=1
Loop:
(N).s 01 02 03 04 05 06 07 08 ; sendet mit CAN-ID 123,124,..
(N) (X+1) (X+2) (X+3) (X+4) ; sendet 4 variable
Datenbytes
(N) (X).w (X).l (X).mw (X).ml ; sendet INTEL + MOTOROLA..
N:=N+1 : X:=X+1
goto Loop
(least significant byte first, wie bei CANopen)
(most significant byte first, d.h. Bits 15..8 im ersten Byte, Bits 8..0 im zweiten Byte)
(Bits 31..24, 23..16, 15..8 und zum Schluß 7..0 jeweils in ein Byte im CAN-Telegramm gepackt)
Dieses exotische Format wird tatsächlich in der Praxis verwendet (2013-12-09) !
Vermutlich steckt beim 'Motorola-32-Bit-Fliesskomma-Format' der EXPONENT im ersten Byte (entsprechend 'MSB');
Offizielle Details (von GM) waren bei der Erstellung dieser Beschreibung (2013-12-09) nicht bekannt.
Befehlsübersicht Kommando-Interpreter
Aus Gründen der Abwärtskompatibilität darf den meisten Befehlen
noch ein '@'-Zeichen (at) vorangestellt werden. In der aktuellen Version ist dies nicht mehr nötig.
repeat
until
<Bedingung>
repeat
, wenn <Bedingung> == 0.
goto
<Sprungziel>
gosub
<Unterprogramm>
return
if
<Bedingung>
if
folgenden Anweisungen werden nur ausgefuehrt, wenn
<Bedingung> ungleich Null. Das "if"-Kommando gibt's (wie in der
Programmiersprache BASIC) in einer einzeiligen Variante (bei der die Anweisung
in der gleichen Zeile wie die if-Abfrage steht) und in einer mehrzeiligen
Variante (mit "endif" und möglicherweise "else"). Siehe Kapitel
"Verzweigungen und Schleifen".
stop
delay
(<Zeitintervall in Sekunden>)
OnError
ResumeError
print
("<Format-String>",
<Parameter>.. )
OpenWindow, CloseWindow
MoveTo
Die aktuelle Position des Ausgabecursors (Pixel-Koordinate) kann per
cursor.x, cursor.y abgefragt werden.
Dies kann z.B. beim periodischen Aktualisieren von Teilen eines Fensters verwendet werden.
Ein Beispiel finden Sie in der "PDO-Anzeige" in der Applikation EaDIO8Test.cts
(im Installationsarchiv des CAN-Testers enthalten).
SetFont( "<FontName>", <FontSize>, <FontAttributes> )
0 = normal, 1 = unterstrichen, 2 = Fett, 4 = kursiv. Diese Attribute können
auch bitweise kombiniert werden (bitte sparsam einsetzen).
Beispiel: SetFont("Arial",8,1) selektiert einem mittelgroßen Zeichensatz
in der Schrift "Arial", mit Unterstrich.
ClearScreen( x )
x : 0=benutzerdefiniertes Fenster, 1=RX-Fenster, 2=TX-Fenster, 3=Meldungsfenster
ClearVars()
Hinweis: Der CAN-Tester speichert Variablen zwischen zwei Sitzungen.
Mit der Anweisung ClearVars() am Anfang des Scripts kann die Verwendung 'alter' Werte verhindert werden.
scope.xxx
sound
(frequenz, dauer, modulation)
freeze
Dadurch wird viel 'Rechenleistung' eingespart, wodurch nachfolgende Zeilen im Script deutlich schneller
abgearbeitet werden können (z.B. zum Senden einiger Tausend CAN-Messages pro Sekunde).
Alte Syntax:
freeze; // stop RX- and TX message display
Neue Syntax:
freeze := TRUE; // stop ('freeze') RX- and TX-message display
freeze := FALSE; // let RX- and TX-message display run again
was_frozen := freeze; // stop RX- and TX message display and save old setting
freeze := was_frozen; // restore old state for RX- and TX-message display
def_watch
@def_watch(0) "Ain1", canrx(0x181,0,U16), 0, 32768
isin( <argument> [,<period> [,<amplitude>]] )
table[Index]( Value0, Value1, Value2, Value3, ... ValueN )
time
canrx
(<Identifier>, <erstes Bit>,
<Datentyp>)
tx_interval
=<neues Sendeintervall
in Sekunden>
Fehlt dieses Kommando in der Anweisungsliste, wird das in der
Konfiguration definierte Intervall
verwendet.
Hinweise:
can.send( <Identifier>, <Zeichenkette> )
can.send(0x7F0,g=50,"Hallo ! Dies ist ein Test für die
can-String-Sendefunktion !")
Fehlt die Verzögerungszeit, wird als Default-Wert eine Pause von 20
Millisekunden zwischen zwei Telegrammen verwendet.
Hinweis: Dieser Befehl wirkt blockierend ! Erst nach dem Senden setzt der
Interpreter seine Arbeit fort.
can.show_msgs_as_strings( <Identifier-Liste> )
Hinweis: Nicht druckbare Zeichen werden z.T. hexadezimal angezeigt, z.B.
"Hallo" 0D 0A
Siehe auch: CAN-Text-Terminal
can.reset
wcan <CAN-ID> <Länge>
<Datenbytes>..
wcan 123 8 11 22 33 44 55 66 77 88 ; Wartet auf ID=0x123
und GENAU diesen Bytes
wcan 7FF x xx xx xx xx xx xx xx xx ; wartet auf ID=0x7FF, beliebiges
Datenfeld
wcan XXX 3 xx AA xx ; w.a. beliebige ID, 3 Bytes, 0xAA im zweiten
Byte
Um nach dem Empfang einer "passenden" CAN-Message auf deren Datenfeld
zuzugreifen, oder um den tatsächlich verwendeten Identifier abzufragen,
verwenden Sie die Interpreterfunktionen
wcan.id
,
wcan.len
, und
wcan.dat
.
Zum Testen der "wcan"-Funktion eignen sich die Programme Wait_Test_Server.txt
und Wait_Test_Client.txt, die seit März 2006 im Installationsarchiv
des CAN-Testers enthalten sind.
Hinweis: Sie verwenden WINDOWS... erwarten Sie daher vom CAN-Tester nicht,
daß das Kommandoprogramm wenige Millisekunden nach Empfang des erwarteten
CAN-Telegramms fortgesetzt wird ! Typische Verzögerungen liegen im Bereich
von 5 bis 200 Millisekunden, je nach Rechnertakt. Manchmal läßt
sich das Kommandoprogramm beschleunigen, indem die Anzeige im TX- und RX-Fenster
gestoppt wird.
obj (alias obd)
Diverse Befehle zum Zugriff auf das eigene (lokale)
CANopen-Objekt-Directory.
sdo
print (Kommando)
Im Normalfall wird nach 'print' eine neue Zeile begonnen (wie in uralten Basic-Dialekten).
Um dies zu vermeiden, kann am Ende der Parameterliste (direkt vor der schließenden Klammer) ein Semikolon
eingefügt werden. Beispiel:
print("Erster Teil der Ausgabe,";); // ohne Zeilenvorschub
print("zweiter Teil der Ausgabe."); // mit Zeilenvorschub
print( "Es ist jetzt %02ld:%02ld:%02ld Uhr .",23,59,59 ); // drei Zahlen mit je zwei Ziffern
Sind in der Parameterliste mehr auszugebende Werte vorhanden als Platzhalter im
Format-String, dann wird automatisch das zum Typ der Variablen passende 'Default-Format' verwendet.
Aus dem Grund kann auch komplett auf den Format-String verzichtet werden. Bespiel:
print( "Es ist jetzt",23;":";59;":";59,"Uhr ." );
Wird print wie im oben gezeigten Beispiel ohne Format-String verwendet,
gelten folgende Regel für das Trennzeichen in der Parameterliste:
Der vom oben gezeigten Beispiel ausgegebene Text lautet daher:
Es ist jetzt 23:59:59 Uhr .
|________|___ per Komma ausgegebene Leerzeichen
OpenWindow, CloseWindow
(Kommandos)
print
nicht mehr in die Meldungsliste
des CAN-Testers, sondern in das benutzerdefinierte Fenster.
goto, gosub (Kommando)
goto
<Label>
gosub
<Label>
gosub
merkt sich die aktuelle Programmposition für einen
späteren Rücksprung mit return
.
Siehe auch: Beispiel mit 'goto'; Labels .
return (Kommando)
return
gosub
"-Befehl fort.
Wird normalerweise als letzter Befehl eines Unterprogramms eingesetzt, welches
von verschiedenen Stellen aufgerufen wird.
canrx (Decodieren empfangener CAN-Signale)
canrx
( <CAN-Identifier>, <erstes Bit im Datenfeld
der Message>, <Datentyp> [ , < Defaultwert > ] )
Falls kein passendes CAN-Telegramm im Puffer gefunden wird, ist das
Funktionsergebnis identisch mit dem Default-Wert (hier: 1234). Ist kein
Defaultwert angegeben, und kein passendes Telegramm im Puffer, bricht der
Interpreter die Bearbeitung mit einer Fehlermeldung ab.
canrx.latch (Für die Verarbeitung 'eingefrorenes' CAN-Telegramm)
Zusätlich zur weiter oben beschriebenen Form bietet 'canrx' auch die Möglichkeit,
ein CAN-Telegramm mit einem bestimmten Message-ID für die weitere Verarbeitung
in einem eigenen Zwischenpuffer (latch) abzulegen.
Dadurch wird die Konsistenz sichergestellt, wenn mehrere Signale aus einem
CAN-Telegramm enthalten sind, die vom Script im CAN-Tester verabeitet werden sollen.
Mit dem folgenden Beispiel wird zunächst das zuletzt empfangene CAN-Telegramm mit Message-ID 0x1800
'eingefroren', um daraus anschließend verschiedene Signale (Bitfelder) zu isolieren.
Mit der Funktion canrx.latch kann auch auf die Länge des Datenfelds (0 bis 8 Bytes),
den Message-Identifier, und den Zeitstempel zugegriffen werden.
if( canrx.update_latch( 0x1800 ) ) // try to capture the last message with this ID
print( "Received %ld messages with ID %lX .", canrx.latch.count, canrx.latch.id );
print( "Number of data bytes : %ld", canrx.latch.len );
print( "Digital inputs 1..16 : %04lX", canrx.latch(0, U16) );
print( "Digital inputs 17..31 : %04lX", canrx.latch(16,U16) );
else
print( "Nothing received yet" );
endif;
wcan.id, wcan.len,
wcan.dat (Abfragefunktionen nach dem wcan-Kommando)
greift auf das Datenfeld der zuvor empfangenen Message zu, ähnlich wie
beim canrx-Kommando.
Die Bitzählung beginnt bei 0 (NULL); der Datentyp wird in der
hier definierten symbolischen Form
übergeben.
scope.xxx
(Kommandos zum Steuern
des Watch/Plot-Fensters durch den Interpreter)
@scope.show(0)
Schließt das Watch/Plot-Fenster (ehemals "Oszilloskopfenster")
@scope.show(1)
Öffnet das Watch/Plot-Fenster und schaltet auf die Registerkarte "Plotter"
um
@scope.show(2)
Öffnet das Watch/Plot-Fenster und schaltet auf die Registerkarte
"Kanaldefinitionen" (watches) um
@scope.ch[N]={ <Name>, <Expression>, <ScaleMin>,
<ScaleMax> }
Ändert die Definitionen für Kanal Nummer N (N: 0..14). Diese werden
auch in der Kanaldefinitionstabelle angezeigt.
Die gleichen Daten (mit einer etwas anderen Syntax) können auch per
"def_watch"-Kommando gesetzt werden.
@scope.run
Startet das "Oszilloskop" (und die Aktualisierung des Watch-Fensters)
@scope.stop
Stoppt das "Oszilloskop" (und die Aktualisierung des Watch-Fensters)
; Prepare SCOPE/Plotter to show values from PDO :
@scope.show(2) ; REM show channel definition tab in the scope window
@scope.timing=0.005 ; REM set scope sampling interval (seconds)
; REM scope.ch[x]={ Name, Expression, ScaleMin, ScaleMax }
@scope.ch[0]={"PDO1_W0", canrx(0x181,0,I16), -32768, 32768 }
@scope.ch[1]={"PDO1_W1", canrx(0x181,16,I16), -32768, 32768 }
@scope.ch[2]={"PDO1_W2", canrx(0x181,32,I16), -32768, 32768 }
@scope.ch[3]={"PDO1_W3", canrx(0x181,48,I16), -32768, 32768 }
@scope.show(1) ; REM open the "plotter" tab in the scope window
Symbole für CANopen- und andere
Datentypen
Ein-Bit-Variable: 0=FALSE, 1=TRUE
8-Bit Integer mit Vorzeichen
16-Bit Integer mit Vorzeichen
32-Bit Integer mit Vorzeichen
8-Bit Integer ohne Vorzeichen ("Byte")
16-Bit Integer ohne Vorzeichen ("Word")
32-Bit Integer ohne Vorzeichen ("doubleword")
32-Bit Fliesskomma nach CANopen (IEEE)
Nullterminierter ASCII- (oder ANSII?-) String. Nur von wenigen Funktionen
unterstützt, z.B. SDO-Zugriffsfunktionen
16-Bit Integer im Motorola-Format (most significant byte first)
32-Bit Integer im Motorola-Format (most significant byte first)
Zurück zur
Übersicht
Zuletzt bearbeitet: 2019-08-28 (ISO 8601), Wolfgang Büscher