Die Sprache ExST (Extended ST) unterstützt mehrere bedingte Pragma Anweisungen, die sich auf die Codegenerierung im Vorkompilierungs- oder Kompilierungsprozess auswirken.
Ob ein Implementierungscode bei der Kompilierung berücksichtigt wird, kann von den nachstehenden Bedingungen abhängig sein, nämlich ob:
ein bestimmter Datentyp oder eine bestimmte Variable deklariert ist
ein Datentyp oder eine Variable ein bestimmtes Attribut hat
eine Variable einen bestimmten Datentyp hat
eine bestimmte POU oder eine Task vorhanden bzw. Teil des Aufrufbaums ist usw.
{define...}
zu verwenden. Definitionen in Anwendungen wirken sich nur auf Schnittstellen unterhalb der entsprechenden Anwendung aus.
|
Während des Vorompilierungsprozesses werden alle nachfolgenden Instanzen des Bezeichners (Kennung) durch die angegebene Zeichenfolge (String) ersetzt, wenn diese nicht leer ist (was erlaubt ist). Der Bezeichner bleibt definiert und im Gültigkeitsbereich bis zum Ende des Objekts oder bis seine Definition in einer |
|
Die Vorprozessordefinition des |
...
...
...
|
Dies sind pragmas für die bedingte Kompilierung. Die angegebenen Ausdrücke
Innerhalb der Konstante |
|
Im Konstantenausdruck |
Sie können diese Ausdrücke sowie die Definition, vervollständigt mit {define}
, auch im Textfeld im Dialogfeld eines Objekts verwenden ( ).
defined (identifier)
Dieser Operator bewirkt, dass der Ausdruck den Wert TRUE erhält, sobald identifier
mit einer {define}
-Anweisung definiert und die Definition später nicht durch eine {undefine}
-Anweisung aufgehoben wird. Andernfalls wird der Wert FALSE ausgeliefert.
Beispiel für defined (identifier)
:
Voraussetzung: Es gibt 2 Anwendungen App1
und App2
. Bezeichner pdef1
ist definiert in App2
, aber nicht in App1
.
{IF defined (pdef1)}
(* this code is processed in App1 *)
{info 'pdef1 defined'}
hugo := hugo + SINT#1;
{ELSE}
(* the following code is only processed in application App2 *)
{info 'pdef1 not defined'}
hugo := hugo - SINT#1;
{END_IF}
Zusätzlich ist ein Beispiel für eine Meldung pragma enthalten:
Nur Informationen pdef1 defined
werden in der Ansicht angezeigt, wenn die Anwendung kompiliert wird, da pdef1
definiert ist. Die Meldung wird angezeigt, wenn pdef1
nicht definiert ist.
defined (variable:<variable name>)
Bei einer Anwendung auf eine Variable bewirkt dieser Operator, dass der Ausdruck den Wert TRUE erhält, wenn diese Variable im aktuellen Bereich deklariert ist. Andernfalls entspricht der Wert FALSE.
Beispiel für defined (variable:<variable name>)
:
Voraussetzung: Es gibt 2 Anwendungen App1
und App2
. Variable g_bTest
ist deklariert in App2
, aber nicht in App1
.
{IF defined (variable:g_bTest)}
(* the following code is only processed in application App2 *)
g bTest := x > 300;
{END_IF}
defined (type:identifier)
Bei einer Anwendung auf einen Datentypbezeichner bewirkt dieser Operator, dass der Ausdruck den Wert TRUE erhält, wenn ein Datentyp mit diesem bestimmten Namen deklariert ist. Andernfalls entspricht der Wert FALSE.
Beispiel für defined (type:identifier)
:
Voraussetzung: Es gibt 2 Anwendungen App1
und App2
. Datentyp DUT ist definiert in App2
, aber nicht in App1
.
{IF defined (type:DUT)}
(* the following code is only processed in application App1 *)
bDutDefined := TRUE;
{END_IF}
defined (pou:pou-name)
Bei einer Anwendung auf einen POU-Namen lautet der Wert TRUE, wenn eines der folgenden Objekte mit dem Namen <pou-name>
verfügbar ist:
Funktionsbaustein
Funktion
Programm
Aktion
Methode
Schnittstelle
Ansonsten ist er FALSE.
Weitere Informationen finden Sie im Kapitel POU.
Beispiel für defined (pou: pou-name)
:
Voraussetzung: Es gibt 2 Anwendungen App1
und App2
. POU CheckBounds
ist verfügbar in App2
, aber nicht in App1
.
{IF defined (pou:CheckBounds)}
(* the following code is only processed in application App1 *)
arrTest[CheckBounds(0,i,10)] := arrTest[CheckBounds(0,i,10)] + 1;
{ELSE}
(* the following code is only processed in application App2 *)
arrTest[i] := arrTest[i]+1;
{END_IF}
defined (task:task-name)
Der Ausdruck erhält den Wert TRUE, wenn eine Task mit dem Namen <task name>
definiert ist. Ansonsten ist er FALSE.
Syntax:
{ IF defined (task: <task name> }
{ ELSIF defined (task: <task name> }
Beispiel 1: {IF defined (task: Task_D)}
Beispiel 2:
Voraussetzung: Es gibt 2 Anwendungen App1
und App2
. Die Task PLC_PRG_Task
ist definiert in App1
, aber nicht in App2
.
{IF defined (task: PLC_PRG_Task)}
(* the following code is only processed in App1 *)
erg := plc_prg.x;
{ELSE}
(* the following code is only processed in App2 *)
erg := prog.x;
{END_IF}
hasattribute (pou: pou-name, attribute)
Bei einer Anwendung auf eine POU bewirkt dieser Operator, dass der Ausdruck den Wert TRUE erhält, wenn dieses attribute
in der ersten Zeile des POU-Deklarationsteils angegeben wird.
Beispiel für hasattribute (pou: pou-name, attribute)
:
Voraussetzung: Es gibt 2 Anwendungen App1
und App2
. Funktion fun1 ist definiert in App1
und App2
, aber hat in App1
ein Attribut vision:
Definition von fun1
in App1
:
{attribute 'vision'}
FUNCTION fun1 : INT
VAR_INPUT
i : INT;
END_VAR
VAR
END_VAR
Definition von fun1
in App2
:
FUNCTION fun1 : INT
VAR_INPUT
i : INT;
END_VAR
VAR
END_VAR
Pragma-Anweisung
{IF hasattribute (pou: fun1, 'vision')}
(* the following code is only processed in application App1 *)
ergvar := fun1 ivar);
{END_IF}
hasattribute (variable: variable, attribute)
Bei einer Anwendung auf eine variable
ist der Wert TRUE, wenn dieses Attribut über die {attribute}-Anweisung in einer Zeile vor der Deklaration der Variablen angegeben wird.
Beispiel für hasattribute (variable: variable, attribute)
:
Voraussetzung: Es gibt 2 Anwendungen App1
und App2
. Variable g_globalInt wird verwendet in App1
und App2
, aber hat in App1
ein Attribut DoCount:
Deklaration von g_globalInt in App1
VAR_GLOBAL
{attribute 'DoCount'}
g_globalInt : INT;
g_multiType : STRING;
END_VAR
Deklaration von g_globalInt in App2
VAR_GLOBAL
g_globalInt : INT;
g_multiType : STRING;
END_VAR
Pragma-Anweisung
{IF hasattribute (variable: g_globalInt, 'DoCount')}
(* the following code line will only be processed in App1, because there variable g_globalInt has got the attribute 'DoCount' *)
g_globalInt := g_globalInt + 1;
{END_IF}
hastype (variable:variable, type-spec)
Bei einer Anwendung auf eine variable
ist der Wert TRUE, wenn diese Variable den angegebenen type-spec
aufweist. Andernfalls entspricht der Wert FALSE.
Verfügbare Datentypen von type-spec
BOOL
BYTE
DATE
DATE_AND_TIME
DINT
DWORD
INT
LDATE
LDATE_AND_TIME (LDT)
LINT
LREAL
LTIME
LTIME_OF_DAY (LTOD)
LWORD
REAL
SINT
STRING
TIME
TIME_OF_DAY (TOD)
UDINT
UINT
ULINT
USINT
WORD
WSTRING
Beispiel für Operator hastype (variable: variable, type-spec):
Voraussetzung: Es gibt 2 Anwendungen App1
und App2
. Variable g_multitype wird deklariert in App1
mit Typ LREAL und in der Anwendung App2
mit Typ STRING:
{IF (hastype (variable: g_multitype, LREAL))}
(* the following code line will be processed only in App1 *)
g_multitype := (0.9 + g_multitype) * 1.1;
{ELSIF (hastype (variable: g_multitype, STRING))}
(* the following code line will be processed only in App2 *)
g_multitype := 'this is a multitalent';
{END_IF}
hasvalue (define-ident, char-string)
Wenn der Definierer (define-ident) definiert ist und den angegebenen Wert (char-string) hat, dann ist der Wert TRUE. Andernfalls entspricht der Wert FALSE.
Beispiel für hasvalue (define-ident, char-string)
:
Voraussetzung: Variable test wird verwendet in Anwendungen App1
und App2
. Es erhält den Wert 1 in App1
und den Wert 2 in App2
:
{IF hasvalue(test,'1')}
(* the following code line will be processed in App1, because there variable test has value 1 *)
x := x + 1;
{ELSIF hasvalue(test,'2')}
(* the following code line will be processed in App1, because there variable test has value 2 *)
x := x + 2;
{END_IF}
hasvalue (PackMode, '<pack mode value>')
Der geprüfte Packungsmodus hängt von der Gerätebeschreibung ab und nicht von dem Pragma, das für einzelne DUTs angegeben werden kann.
hasvalue (RegisterSize, '<register size>')
<register size>
: Definiert die Größe eines CPU-Registers (in Bits).
Wenn die Größe eines CPU-Registers gleich <register size>
ist, gibt der Ausdruck den Wert TRUE zurück.
<register size>
kann die folgenden Werte haben:
16
für C16x
64
für X86-64 Bit
32
für X86-32 Bit
hasconstanttype(<constant name>, <boolean literal>)
Der Operator prüft, ob die Konstante, die mit <constant name>
definiert ist, ersetzt wurde. Der zweite Parameter (boolescher Wert) steuert, was überprüft wird:
TRUE: Überprüft, ob die Konstante ersetzt wurde.
FALSE: Überprüft, ob die Konstante nicht ersetzt wurde.
Wenn der entsprechende Fall erkannt wird, gibt der Operator TRUE
zurück.
Syntax:
{ IF hasconstanttype( <constant name> , <boolean literal> ) }
{ ELSIF hasconstanttype( <constant name> , <boolean literal> ) }
Beispiel:
{IF hasconstanttype(PLC_PRG.aConst, TRUE)}
Das automatische Ersetzen von Konstanten hängt von folgenden Faktoren ab:
Compiler-Option
Konstantentyp (STRING-Typen z. B. werden nicht ersetzt)
Verwendung des Attributs {attribute 'const_non_replaced'}
Verwendung des Attributs {attribute 'const_replaced'}
Beispiel:
VAR
iCntMAXIsReplaced: INT;
xErrorOccured : BOOL;
END_VAR
VAR CONSTANT
c_iMAX: INT := 99;
END_VAR
{IF hasconstanttype(c_iMAX, TRUE)}
iCntMAXIsReplaced := iCntMAXIsReplaced + 1; // E.g. this code will be executed in case Project Settings – Compile options – Replace constants was activated
{ELSE}
xErrorOccured := FALSE;; // E.g. this code will be executed in case Project Settings – Compile options – Replace constants was deactivated
{END_IF}
hasconstantvalue(<constant name>, <variable name>, <comparison operator>)
Der Operator vergleicht den Wert der Konstante, der mit <constant name>
definiert ist, mit dem Wert des zweiten Parameters. Der zweite Parameter kann als Literal <literal>
oder als Variable <variable name>
angegeben werden.
Die folgenden Vergleichsoperatoren <comparison operator>
werden unterstützt:
Größer als (>
)
Größer oder gleich (>=
)
Gleich (=
)
Ungleich (<>
)
Kleiner oder gleich (<=
)
Kleiner als (<
)
Syntax:
{ IF hasconstantvalue( <constant name> , <variable name> , <comparison operator> )
{ IF hasconstantvalue( <constant name> , <literal> , <comparison operator> )
{ ELSIF hasconstantvalue( <constant name> , <variable name> , <comparison operator> )
{ ELSIF hasconstantvalue( <constant name> , <literal> , <comparison operator> )
Beispiel 1:
{IF hasconstantvalue(PLC_PRG.aConst, 99, >)}
{ELSIF hasconstantvalue(PLC_PRG.aConst, GVL.intconst99, =)}
Beispiel 2:
PROGRAM PRG_ConditionConstantValue
VAR
iCntMAX: INT;
iCntGlobalMAX : INT;
iCntABC: INT;
iCntGlobalABC : INT;
xErrorOccured : BOOL;
END_VAR
VAR CONSTANT
c_iMAX: INT := 999;
c_sABC: STRING := 'ABC';
{attribute 'const_non_replaced'}
c_iNonReplaceable: INT := 888;
END_VAR
{IF hasconstantvalue(c_iMAX, 999, =)}
iCntMAX := iCntMAX + 1;
{ELSE}
xErrorOccured := FALSE;
{END_IF}
{IF hasconstantvalue(c_iMAX, GVL.gc_iMAX, =)}
iCntGlobalMAX := iCntGlobalMAX + 1;
{ELSE}
xErrorOccured := FALSE;
{END_IF}
{IF hasconstantvalue(c_sABC, 'ABC', =)}
iCntABC := iCntMAX + 1;
{ELSE}
xErrorOccured := FALSE;
{END_IF}
{IF hasconstantvalue(c_sABC, GVL.gc_sABC, =)}
iCntGlobalABC := iCntMAX + 1;
{ELSE}
xErrorOccured := FALSE;
{END_IF}
NOT operator
Der Ausdruck erhält den Wert TRUE, wenn der invertierte Wert von operator
TRUE ist. operator
kann einer der in diesem Kapitel beschriebenen Operatoren sein.
Beispiel für NOT operator
:
Voraussetzung: Es gibt 2 Anwendungen App1
und App2
. POU PLC_PRG1 wird verwendet in App1
und App2. POU CheckBounds
ist nur verfügbar in App1
:
{IF defined (pou: PLC_PRG1) AND NOT (defined (pou: CheckBounds))}
(* the following code line is only executed in App2 *)
bANDNotTest := TRUE;
{END_IF}
AND operator
Der Ausdruck erhält den Wert TRUE, wenn beide Operatoren TRUE sind. operator
kann einer der in dieser Tabelle aufgeführten Operatoren sein.
Beispiel für AND operator
:
Voraussetzung: Es gibt 2 Anwendungen App1
und App2
. POU PLC_PRG1
wird verwendet in Anwendungen App1
und App2
. POU CheckBounds
ist nur verfügbar in App1
:
{IF defined (pou: PLC_PRG1) AND (defined (pou: CheckBounds))}
(* the following code line will be processed only in applications App1, because only there "PLC_PRG1" and "CheckBounds" are defined *)
bORTest := TRUE;
{END_IF}
OR operator
Der Ausdruck ist TRUE, wenn einer der Operatoren TRUE ist. operator
kann einer der in diesem Kapitel beschriebenen Operatoren sein.
Beispiel für OR operator
:
Voraussetzung: POU PLC_PRG1
wird verwendet in Anwendungen App1
und App2
. POU CheckBounds
ist nur verfügbar in App1
:
{IF defined (pou: PLC_PRG1) OR (defined (pou: CheckBounds))}
(* the following code line will be processed in applications App1 and App2, because both contain at least one of the POUs "PLC_PRG1" and "CheckBounds" *)
bORTest := TRUE;
{END_IF}