Le langage ST étendu (ExST) prend en charge plusieurs Instructions Pragma conditionnelles qui affectent la génération du code pendant le processus de précompilation ou de compilation.
Le code d'implémentation pris en compte pour la compilation varie en fonction des conditions suivantes :
Un type de données ou une variable spécifique a-t-il été déclaré ?
Un attribut spécifique est-il associé à un type ou une variable ?
Une variable est-elle associée à un type de données spécifique ?
Un POU ou une tâche spécifique est-il disponible ou fait-il partie de l'arborescence d'appels, etc.
{define...}
déclaré dans une application. Les définitions des applications n'affectent que les interfaces insérées sous l'application correspondante.
|
Lors du prétraitement, toutes les instances suivantes de l'identificateur sont remplacées par la séquence indiquée de jetons, dans le cas où la chaîne de jeton n'est pas vide (ce qui est autorisé et clairement défini). L'identificateur reste défini et dans le domaine de validité jusqu'à la fin de l'objet ou jusqu'à ce que sa définition soit annulée dans une directive |
|
La définition du |
...
...
...
|
Ces pragmas s'appliquent à la compilation conditionnelle. Les expressions
Dans l'expression constante |
|
L'expression constante |
Vous pouvez également utiliser ces expressions ainsi que la définition réalisée par {define}
dans la zone de texte de la boîte de dialogue d'un objet ( ).
defined (identifier)
Avec cet opérateur, l'expression prend la valeur TRUE dès lors que identifier
a été défini via une instruction {define}
et que cette définition n'a pas été annulée ultérieurement via une instruction {undefine}
. Sinon, elle prend la valeur FALSE.
Exemple pour defined (identifier)
:
Conditions préalables : Il y a 2 applications App1
et App2
. L'identificateur pdef1
est défini dans App2
, mais pas dans 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}
Un exemple de pragma de message est également inclus :
Seules les informations pdef1 defined
s'affichent dans la vue lors de la compilation de l'application, car pdef1
est défini. Le message s'affiche lorsque pdef1
n'est pas défini.
defined (variable:<variable name>)
Lorsque l'opérateur s'applique à une variable, l'expression prend la valeur TRUE si la variable est déclarée au sein du domaine de validité en cours. Sinon, elle prend la valeur FALSE.
Exemple pour defined (variable:<variable name>)
:
Conditions préalables : Il y a 2 applications App1
et App2
. La variable g_bTest
est déclarée dans App2
, mais pas dans App1
.
{IF defined (variable:g_bTest)}
(* the following code is only processed in application App2 *)
g bTest := x > 300;
{END_IF}
defined (type:identifier)
Lorsque l'opérateur s'applique à un identificateur de type, l'expression prend la valeur TRUE si un type portant ce nom est déclaré. Sinon, la valeur est FALSE.
Exemple pour defined (type:identifier)
:
Conditions préalables : Il y a 2 applications App1
et App2
. Le type de données DUT est défini dans App2
, mais pas dans App1
.
{IF defined (type:DUT)}
(* the following code is only processed in application App1 *)
bDutDefined := TRUE;
{END_IF}
defined (pou:pou-name)
Lors de son application à un nom de POU, la valeur est TRUE si l'un des objets suivants porte le nom <pou-name>
:
Bloc fonction
Fonction
Programme
Action
Méthode
Interface
Sinon, la valeur est FALSE.
Pour plus d'informations, reportez-vous au chapitre POU.
Exemple pour defined (pou: pou-name)
:
Conditions préalables : Il y a 2 applications App1
et App2
. Le POU CheckBounds
est disponible dans App2
, mais pas dans 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)
L'expression prend la valeur TRUE si une tâche est définie avec le nom <task name>
. Sinon, la valeur est FALSE.
Syntaxe :
{ IF defined (task: <task name> }
{ ELSIF defined (task: <task name> }
Exemple 1 : {IF defined (task: Task_D)}
Exemple 2 :
Conditions préalables : Il y a 2 applications App1
et App2
. La tâche PLC_PRG_Task
est définie dans App1
, mais pas dans 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)
Lors de l'application à un POU, la valeur est TRUE si le attribute
en question est indiqué sur la première ligne de la partie déclarative des POU.
Exemple pour hasattribute (pou: pou-name, attribute)
:
Conditions préalables : Il y a 2 applications App1
et App2
. La fonction fun1 est définie dans App1
et App2
, mais dans App1
elle présente un attribut vision :
Définition de fun1
dans App1
:
{attribute 'vision'}
FUNCTION fun1 : INT
VAR_INPUT
i : INT;
END_VAR
VAR
END_VAR
Définition de fun1
dans App2
:
FUNCTION fun1 : INT
VAR_INPUT
i : INT;
END_VAR
VAR
END_VAR
Instruction Pragma
{IF hasattribute (pou: fun1, 'vision')}
(* the following code is only processed in application App1 *)
ergvar := fun1 ivar);
{END_IF}
hasattribute (variable: variable, attribute)
Lors de l'application à une variable
, la valeur est TRUE si l'attribut en question est spécifié via l'instruction {attribute} sur une ligne précédant la déclaration de la variable.
Exemple pour hasattribute (variable: variable, attribute)
:
Conditions préalables : Il y a 2 applications App1
et App2
. La variable g_globalInt est utilisée dans App1
et App2
, mais dans App1
elle présente un attribut DoCount :
Déclaration de g_globalInt dans App1
VAR_GLOBAL
{attribute 'DoCount'}
g_globalInt : INT;
g_multiType : STRING;
END_VAR
Déclaration de g_globalInt dans App2
VAR_GLOBAL
g_globalInt : INT;
g_multiType : STRING;
END_VAR
Instruction Pragma
{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)
Lors de l'application à une variable
, la valeur est TRUE si la variable en question présente le type-spec
spécifié. Sinon, la valeur est FALSE.
Types de données disponibles pour 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
Exemple pour l'opérateur hastype (variable: variable, type-spec) :
Conditions préalables : Il y a 2 applications App1
et App2
. La variable g_multitype est déclarée dans App1
avec le type LREAL et dans App2
avec le type 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)
Si define-ident est défini et présente la valeur spécifiée (char-string), la valeur est TRUE. Sinon, la valeur est FALSE.
Exemple pour hasvalue (define-ident, char-string)
:
Conditions préalables : La variable test est utilisée dans les applications App1
et App2
. Elle prend la valeur 1 dans App1
et la valeur 2 dans 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>')
Le mode de compactage qui est vérifié dépend de la description de l'équipement, et non du pragma qui peut être spécifié pour chaque DUT.
hasvalue (RegisterSize, '<register size>')
<register size>
: définit la taille d'un registre CPU (en bits).
Lorsque la taille d'un registre CPU est égale à <register size>
, l'expression renvoie la valeur TRUE.
<register size>
peut avoir les valeurs suivantes :
16
pour C16x
64
pour X86-64 bits
32
pour X86-32 bits
hasconstanttype(<constant name>, <boolean literal>)
L'opérateur vérifie si la constante définie avec <constant name>
a été remplacée. Le deuxième paramètre (valeur booléenne) contrôle ce qui est vérifié :
TRUE : vérifie si la constante a été remplacée.
FALSE : vérifie si la constante n'a pas été remplacée.
Si le cas concerné est détecté, l'opérateur renvoie TRUE
.
Syntaxe :
{ IF hasconstanttype( <constant name> , <boolean literal> ) }
{ ELSIF hasconstanttype( <constant name> , <boolean literal> ) }
Exemple :
{IF hasconstanttype(PLC_PRG.aConst, TRUE)}
Le remplacement automatique des constantes dépend des éléments suivants :
Option de compilation
Type de constante (par exemple, les types STRING ne sont pas remplacés)
Utilisation de l'attribut {attribute 'const_non_replaced'}
Utilisation de l'attribut {attribute 'const_replaced'}
Exemple :
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>)
L'opérateur compare la valeur de la constante (définie avec <constant name>
) à la valeur du deuxième paramètre. Le deuxième paramètre peut être spécifié en tant que littéral (<literal>
) ou en tant que variable (<variable name>
).
Les opérateurs de comparaison <comparison operator>
suivants sont pris en charge :
Supérieur à (>
)
Supérieur ou égal à (>=
)
Egal à (=
)
Différent de (<>
)
Inférieur ou égal à (<=
)
Inférieur à (<
)
Syntaxe :
{ 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> )
Exemple 1 :
{IF hasconstantvalue(PLC_PRG.aConst, 99, >)}
{ELSIF hasconstantvalue(PLC_PRG.aConst, GVL.intconst99, =)}
Exemple 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
L'expression prend la valeur TRUE lorsque la valeur inversée de operator
est TRUE. operator
peut être l'un des opérateurs décrits dans ce chapitre.
Exemple pour NOT operator
:
Conditions préalables : Il y a 2 applications App1
et App2
. Le POU PLC_PRG1 est utilisé dans App1
et App2. Le POU CheckBounds
n'est disponible que dans 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
L'expression prend la valeur TRUE si les deux opérateurs sont TRUE. operator
peut être l'un des opérateurs répertoriés dans ce tableau.
Exemple pour AND operator
:
Conditions préalables : Il y a 2 applications App1
et App2
. Le POU PLC_PRG1
est utilisé dans les applications App1
et App2
. Le POU CheckBounds
n'est disponible que dans 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
L'expression est TRUE si l'un des opérateurs est TRUE. operator
peut être l'un des opérateurs décrits dans ce chapitre.
Exemple pour OR operator
:
Conditions préalables : Le POU PLC_PRG1
est utilisé dans les applications App1
et App2
. Le POU CheckBounds
n'est disponible que dans 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}