Bedingte Pragmas
Wichtig
Sie verwenden bedingte Pragmas meist in den Implementierungen von ST-POUs. Wenn Sie diese bedingten Pragmas im Deklarationsteil verwenden, wertet CODESYS diese Pragmas nicht aus!
Ausnahme bildet das bedingte Pragma mit dem Operator {project_define (<global define>)}
, das in der Implementierung und im Deklarationsteil von POUs verwendet werden kann, siehe project_defined (<global define>)
Bedingte Pragmas dienen dazu, die Codegenerierung im Vorübersetzungsprozess oder Übersetzungsprozess zu beeinflussen. Die Implementierungssprache ST unterstützt diese Pragmas.
Mit bedingten Pragmas beeinflussen Sie, ob Implementierungscode für die Übersetzung berücksichtigt wird. Dies können Sie beispielsweise davon abhängig machen, ob eine bestimmte Variable deklariert ist, ob ein bestimmter Baustein vorhanden ist etc.
Pragma | Beschreibung |
---|---|
| Der Wert kann später mit |
| Die |
| Dies sind Pragmas für die bedingte Kompilierung. Die angegebenen Ausdrücke |
| Innerhalb des konstanten Ausdrucks |
Tipp
Sie können Ausdrücke und define
-Definitionen als Compiler-Defines in der Registerkarte Build im Eigenschaftendialog von POUs eintragen. Wenn Sie define
-Definitionen im Eigenschaftendialog eintragen, müssen Sie den Begriff {define}
weglassen, im Gegensatz zur Definition im Implementierungscode. Außerdem können Sie im Eigenschaftendialog mehrere define
-Definitionen durch Kommas getrennt angeben.
Operatoren
defined (variable: <variable name> )
Der Operator bewirkt, dass der Ausdruck den Wert TRUE
erhält, wenn die Variable <variable name>
innerhalb des aktuellen Gültigkeitsbereichs deklariert ist; ansonsten wird FALSE
geliefert.
Voraussetzung: Es gibt zwei Applikationen App1
und App2
. Die Variable g_bTest
ist in App1
deklariert, nicht aber in App2
.
{IF defined (variable: g_bTest)} (* the following code is only processed in App2*) g_bTest := x > 300; {END_IF}
defined (<identifier>)
Der Operator bewirkt, dass der Ausdruck den Wert TRUE
erhält. Voraussetzung ist, dass der Bezeichner <identifier>
mit Hilfe einer {define}
-Anweisung definiert wurde und danach nicht mit einer {undefine}
-Anweisung wieder undefiniert wurde; ansonsten wird FALSE
geliefert.
Voraussetzung: Es gibt die Applikationen App1
und App2
. Die Variable pdef1
ist durch eine {define}
-Anweisung in App1
definiert, nicht aber in App2
.
{IF defined (pdef1)} (* This code is processed in App1 *) {info 'pdef1 defined'} hugo := hugo + SINT#1; {ELSE} (* the following code is only processed in App2 *) {info 'pdef1 not defined'} hugo := hugo - SINT#1; {END_IF}
Hier ist zusätzlich ein Beispiel eines Meldungspragmas enthalten: Nur die Meldung pdef1 defined
wird im Meldungsfenster angezeigt, wenn die Applikation kompiliert wird, weil pdef1
tatsächlich definiert ist. Die Meldung pdef1 not defined
wird ausgegeben, wenn pdef1
nicht definiert ist
defined (type: <identifier> )
Der Operator bewirkt, dass der Ausdruck den Wert TRUE
erhält, wenn ein Datentyp mit dem Bezeichner <identifier>
deklariert ist; ansonsten wird FALSE
geliefert.
Voraussetzung: Es gibt zwei Applikationen App1
und App2
. Datentyp DUT
ist in App1
deklariert, nicht aber in App2
.
{IF defined (type: DUT)} (* the following code is only processed in App1*) bDutDefined := TRUE; {END_IF}
defined (pou: <pou name>)
Der Operator bewirkt, dass der Ausdruck den Wert TRUE
erhält, wenn eines der folgenden Objekte mit dem Namen <pou-name>
vorhanden ist:
Funktionsbaustein
Funktion
Programm
Aktion
Methode
Schnittstelle
Ansonsten wird FALSE
geliefert.
Voraussetzung: Es gibt zwei Applikationen App1
und App2
. Der Baustein CheckBounds
ist in App1
vorhanden, nicht aber in App2
.
{IF defined (pou: CheckBounds)} (* the following code is only processed in App1 *) arrTest[CheckBounds(0,i,10)] := arrTest[CheckBounds(0,i,10)] + 1; {ELSE} (* the following code is only processed in App2 *) arrTest[i] := arrTest[i]+1; {END_IF}
defined (resource: <identifier>)
Wichtig
Noch nicht implementiert
Der Operator bewirkt, dass der Ausdruck den Wert TRUE
erhält, wenn ein Ressourcen-Objekt mit dem Namen <identifier>
für die Applikation vorhanden ist; ansonsten wird FALSE
geliefert.
Voraussetzung: Es gibt zwei Applikationen App1
und App2
. Ein Ressourcen-Objekt glob_var1
der Globalen Variablenliste ist für App1
vorhanden, nicht aber für App2
.
{IF defined (resource:glob_var1)} (* the following code is only processed in App1 *) gvar_x := gvar_x + ivar; {ELSE} (* the following code is only processed in App2 *) x := x + ivar; {END_IF}
defined (task: <task name> )
Der Operator bewirkt, dass der Ausdruck den Wert TRUE
erhält, wenn eine Task mit dem Namen <task name>
definiert ist; ansonsten wird FALSE
geliefert.
Syntax
{ IF defined (task: <task name> } { ELSIF defined (task: <task name> }
{IF defined (task: Task_D)}
Voraussetzung: Es gibt zwei Applikationen App1
und App2
. Task PLC_PRG_Task
ist in App1
definiert, nicht aber 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}
defined (IsLittleEndian)
Der Operator bewirkt, dass der Ausdruck den Wert FALSE
erhält, wenn der Speicher der CPU in Big-Endian (Motorola Byte Order) organisiert ist.
defined (IsSimulationMode)
Der Operator bewirkt, dass der Ausdruck den Wert TRUE
erhält, wenn die Applikation auf einem simulierten Gerät läuft, also im Simulationsbetrieb ist.ei
Weitere Informationen finden Sie unter Testen im Simulationsbetrieb.
defined (IsFPUSupported)
Wenn der Ausdruck den Wert TRUE
liefert, erzeugt der Codegenerator bei der Berechnungen mit REAL
-Werten einen FPU-Code (für den Floating Point Unit-Porzessor). Ansonsten werden die FPU-Operationen emuliert, was jedoch bedeutend langsamer ist.
hasattribute (pou: <pou name>, ' <attribute name> ')
Der Operator bewirkt, dass der Ausdruck den Wert TRUE
erhält, wenn das Attribut <attribute name>
in der ersten Zeile des Deklarationsteils des Bausteins <pou name>
angegeben ist; ansonsten wird FALSE
zurückgeliefert.
Voraussetzung: Es gibt zwei Applikationen App1
und App2
. Die Funktion fun1
ist in App1
und App2
deklariert, aber in App1
ist sie zusätzlich mit dem Pragma {attribute 'vision'}
versehen.
In App1
:
{attribute 'vision'} FUNCTION fun1 : INT VAR_INPUT i : INT; END_VAR VAR END_VAR
In App2
:
FUNCTION fun1 : INT VAR_INPUT i : INT; END_VAR VAR END_VAR
Pragmaanweisung:
{IF hasattribute (pou: fun1, 'vision')} (* the following code is only processed in App1 *) ergvar := fun1(ivar); {END_IF}
hasattribute (variable: <variable name> , ' <attribute name> ')
Der Operator bewirkt, dass der Ausdruck den Wert TRUE
erhält, wenn der Variablen das Pragma {attribute '<attribute name>'}
in der Zeile vor der Variablendeklaration zugewiesen ist; ansonsten wird FALSE
zurückgeliefert.
Voraussetzung: Es gibt zwei Applikationen App1
und App2
. Die Variable g_globalInt
wird in App1
und App2
verwendet, aber in App1
ist ihr zusätzlich das Attribut 'DoCount'
zugewiesen.
Deklaration g_GlobalInt
in App1
VAR_GLOBAL {attribute 'DoCount'} g_globalInt : INT; g_multiType : STRING; END_VAR
Deklaration g_GlobalInt
in App2
:
VAR_GLOBAL g_globalInt : INT; g_multiType : STRING; END_VAR
Pragmaanweisung:
{IF hasattribute (variable: g_globalInt, 'DoCount')} (* the following code is only processed in App1 *) g_globalInt := g_globalInt + 1; {END_IF}
hasconstanttype( <constant name> , <boolean literal> )
Der Operator prüft, ob die mit <constant name>
bezeichnete Konstante ersetzt oder nicht ersetzt wurde. Auf was geprüft wird, wird mit dem zweiten Parameter (Boolescher Wert) gesteuert:
TRUE
: Prüft, ob Konstante ersetzt wurdeFALSE
: Prüft, ob Konstante nicht ersetzt wurde
Wenn der jeweilige Fall eintritt, liefert der Operator TRUE
zurück.
Syntax
{ IF hasconstanttype( <constant namne> , <boolean literal> ) } { ELSIF hasconstanttype( <constant namne> , <boolean literal> ) }
{IF hasconstanttype(PLC_PRG.aConst, TRUE)}
Compile-Option Konstanten ersetzen
Konstantentyp (beispielsweise werden
STRING
-Typen nie ersetzt)Verwendung des Attributs
{attribute 'const_non_replaced'}
Verwendung des Attributs
{attribute 'const_replaced'}
VAR iCntMAXIsReplaced: INT; xErrorOccured : BOOL; END_VAR VAR CONSTANT c_iMAX: INT := 99; END_VAR {IF hasconstanttype(c_iMAX, TRUE)} iCntMAXIsReplaced := iCntMAXIsReplaced + 1; {ELSE} xErrorOccured := FALSE; {END_IF}
hasconstantvalue( <constant name> , <variable name> , <comparison operator> )
Der Operator vergleicht den Wert der mit <constant name>
bezeichneten Konstante mit dem Wert des zweiten Parameters. Der zweite Parameter kann entweder als Literal <literal>
oder als Variable <variable name>
angegeben werden.
<comparison operator>
:größer (
>
)größer oder gleich (
>=
)gleich (
=
)ungleich (
<>
)kleiner oder gleich (
<=
)kleiner (
<
)
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> )
{IF hasconstantvalue(PLC_PRG.aConst, 99, >)}
{ELSIF hasconstantvalue(PLC_PRG.aConst, GVL.intconst99, =)}
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}
hastype (variable: <variable name>, <data type> )
Der Operator bewirkt, dass der Ausdruck den Wert TRUE
erhält, wenn die Variable <variable>
vom Datentyp <type-spec>
ist; ansonsten wird FALSE
zurückgeliefert.
Mögliche Datentypen <data type>
:
BOOL | BYTE | DATE | DATE_AND_TIME | DT | DINT | DWORD | INT | LDATE | LDATE_AND_TIME | LDT | LINT | LREAL | LTIME | LTIME_OF_DAY | LTOD | LWORD | REAL | SINT | STRING | TIME | TIME_OF_DAY | TOD | ULINT | UDINT | UINT | USINT | WORD | WSTRING
Voraussetzung: Es gibt zwei Applikationen App1
und App2
. Die Variable g_multitype
ist in App1
mit Datentyp LREAL
deklariert, in App2
mit Datentyp STRING
.
{IF (hastype (variable: g_multitype, LREAL))} (* the following code is only processed in App1 *) g_multitype := (0.9 + g_multitype) * 1.1; {ELSIF (hastype (variable: g_multitype, STRING))} (* the following code is only processed in App2 *) g_multitype := 'this is a multitalent'; {END_IF}
hasvalue (PackMode, ' <pack mode value> ')
Der abgeprüfte PackMode hängt von der Gerätebeschreibung ab, nicht vom Pragma, das für einzelne DUTs angegeben werden kann.
hasvalue (RegisterSize, ' <register size> ')
<register size>
: Größe eines CPU-Registers in Bit
Der Operator bewirkt, dass der Ausdruck den Wert TRUE
liefert, wenn die Größe eines CPU-Registers gleich <register size>
ist.
Mögliche Werte für <register size>
16
für C16x,64
für X86-64 Bit32
für X86-32 Bit
hasvalue (<define-ident>, ' <character string> ')
Der Operator bewirkt, dass der Ausdruck den Wert TRUE
erhält, wenn eine Variable mit Bezeichner <define-ident>
definiert ist und den Wert <character string>
hat; ansonsten wird FALSE
zurückgeliefert.
Voraussetzung: Es gibt zwei Applikationen App1
und App2
. Variable test
wird in den Applikationen App1
und App2
verwendet; in App1
erhält sie den Wert 1
, in App2
den Wert 2
.
{IF hasvalue(test,'1')} (* the following code is only processed in App1 *) x := x + 1; {ELSIF hasvalue(test,'2')} (* the following code is only processed in App2 *) x := x + 2; {END_IF}
project_defined (<global define>)
Dieser Operator steht ab CODESYS V3.5 SP20 zur Verfügung.
Der Operator bewirkt, dass der Ausdruck den Wert TRUE
erhält, wenn das globale Define <global define>
in der Liste der globalen Defines in den Compile-Optionen der Projekteinstellungen enthalten ist.
Der Operator wird als Bedingung einer IF
-Anweisung angegeben und kann sowohl in der Implementierung als auch im Deklarationsteil von ST-POUs und von Bibliotheken verwendet werden. Sie können mithilfe der Operatoren AND
und OR
mit anderen Defines kombiniert werden, wenn diese an der jeweiligen Position erlaubt sind.
Im Deklarationsteil von POUs können IF
-Anweisungen mit dem Operator project_defined (<global define>)
folgende Konstrukte enthalten:
Variablendeklarationen
Beispiel:
{If project_defined(define1)} x : DINT; {END_IF}
Kommentierungen
Attribut-Deklarationen
Pragma-Anweisungen
Folgende Konstrukte sind nicht möglich:
Komplette Variablendeklarationen
Beispiel
{If project_defined(define1)} VAR x : DINT; END_VAR {END_IF}
Komplette Deklarationen von POUS
Beispiel:
{If project_defined(define1)} FUNCTION POU : BOOL VAR_INPUT x : INT; END_VAR {END_IF}
Gültigkeitsbereiche:
VAR_INPUT
,VAR_OUTPUT
,VAR_IN_OUT
NOT <operator>
Der Ausdruck erhält den Wert TRUE
, wenn der Umkehrwert von <operator>
den Wert TRUE
liefert. <operator>
kann einer der in diesem Kapitel beschriebenen Operatoren sein.
Voraussetzung: Es gibt zwei Applikationen App1
und App2
. PLC_PRG1
ist in App1
und App2
vorhanden, die POU CheckBounds
gibt es nur in App1
.
{IF defined (pou: PLC_PRG1) AND NOT (defined (pou: CheckBounds))} (* the following code is only processed in App2 *) bANDNotTest := TRUE; {END_IF}
<operator> AND <operator>
Der Ausdruck erhält den Wert TRUE
, wenn die beiden angegebenen Operatoren TRUE
liefern. <operator>
kann einer der in diesem Kapitel beschriebenen Operatoren sein.
Voraussetzung: Es gibt die Applikationen App1
und App2
. PLC_PRG1
ist in App1
und App2
vorhanden, die POU CheckBounds
nur in App1
.
{IF defined (pou: PLC_PRG1) AND (defined (pou: CheckBounds))} (* the following code is only processed in App1 *) bANDTest := TRUE; {END_IF}
<operator> OR <operator>
Der Ausdruck liefert TRUE
, wenn einer der beiden angegebenen Operatoren TRUE
liefert. <operator>
kann einer der hier beschriebenen Operatoren sein.
Voraussetzung: Es gibt zwei Applikationen App1
und App2
. Die POU PLC_PRG1
ist in App1
und App2
vorhanden, die POU CheckBounds
nur in App1
.
{IF defined (pou: PLC_PRG1) OR (defined (pou: CheckBounds))} (* the following code is only processed in App1 and in App2 *) bORTest := TRUE; {END_IF}
(<operator>)
()
klammert die Operatoren.