Skip to main content

Pragmes conditionnels

Restriction dans le cas des pragmas conditionnels

Utilisez les pragmas pour la compilation conditionnelle uniquement dans les implémentations de POU. Dans les déclarations, ces pragmas sont ignorés et non évalués.

Notez l'exception suivante : le pragma IF avec le project_defined L'opérateur peut être inséré dans les déclarations. Pour plus d'informations, voir : pragma IF avec project_defined (<global define>)

Les pragmas sont évalués par le compilateur lors de la précompilation et de la compilation. Cette opération est appelée compilation conditionnelle. Le langage d'implémentation ST prend en charge ces pragmas.

Le {IF<expression> } pragmas avec {ELSIF<expression> }, {ELSE}, et la conclusion {END_IF} Indique le code des implémentations qui est conservé ou ignoré selon les conditions spécifiées. Les conditions spécifiées dans <expression> sont des expressions constantes entières qui peuvent être composées de différents opérandes et opérateurs.

Lors de la compilation, la première expression du <{IF <expression>} est évaluée. Si sa valeur de retour est FALSE, alors la ramification se produira dans la prochaine {ELSIF <expression>} segment et l'expression évaluée jusqu'à ce qu'un segment renvoie une expression avec TRUE Les expressions sont ainsi évaluées successivement jusqu'à ce que l'une d'elles renvoie une valeur différente de 0. Seul ce segment de code associé à une expression positive sera compilé. Les autres sont ignorés. Si toutes les expressions renvoient 0, le branchement se produit après. {ELSE}. Si le {ELSE} pragma est manquant, il peut alors arriver qu'aucun segment de code ne soit compilé.

Syntaxe

Exemple de fragment de code

Description

{IF <expression> }

{IF defined (DEF0815)}
{info 'DEF0815 has been defined'}
Cnt0815 := iCnt0815 + 1;

Étiquette le début du segment de code qui est compilé dans le cas d'un <expression> condition.

{ELSIF <expression> }

{ELSIF defined (DEF0816)}
{info 'DEF0815 has been defined'}
iCnt0816 := iCnt0816 + 1;

Aucun, un ou plusieurs)

Branche qui étiquette le segment de code alternatif s'il est valide <expression> condition

{ELSE}

{ELSE}
{info 'DEF0815 not defined'}
iCnt0 := iCnt0 - 1;

Facultatif

Branche qui étiquette le segment de code qui est compilé si les conditions précédentes n'ont pas été remplies

{END_IF}

{END_IF}

Étiquette la fin du segment de code conditionnel

<expression>

defined (DEF0815)

Condition

Expression entière qui est constante au moment de la compilation et peut être composée d'opérateurs et d'opérandes, tels que des définitions de compilateur, des variables ou des littéraux

Définition du compilateur

Les définitions du compilateur servent d'étiquettes pour des états spécifiques du code. Une définition du compilateur peut être définie, supprimée ou vérifiée à l'aide des opérateurs définis.

Syntaxe

Exemple

Description

{define <name> }

{define DEF0815}

Définit le compilateur define <name> avec type BOOL

Note

Le compilateur définit <name> est soumis aux règles relatives aux identifiants valides.

{define <name> <string> }

{define DEF0123 '123'}

Définit le compilateur define <name> et attribue la chaîne littérale <string> comme une valeur

{undefine <name>}

{undefine DEF0815}

Supprime la définition du compilateur <name>

Par conséquent, l'identifiant est indéfini. Un pragma dont la définition du compilateur est indéfinie est ignoré.

Astuce

Alternativement, vous pouvez également définir des expressions et des définitions de compilateur localement dans les propriétés d'un POU, ou à l'échelle de l'application dans les propriétés de l'application superordonnée.

Pour ce faire, sélectionnez le POU ou l'application supérieure dans l'arborescence des périphériques. Dans le menu contextuel, cliquez sur Propriétés puis sélectionnez le Construire onglet. Dans le Défini par le compilateur Dans le champ de saisie, vous pouvez définir un littéral ou une expression (exemple : DEF0815). Ce champ n'attend pas d'instruction pragmatique comme {define }, mais simplement un nom.

Vous pouvez spécifier plusieurs définitions de compilateur séparées par des virgules.

Opérateurs

defined (variable: <variable name> )

L'opérateur donne à l'expression la valeur TRUE lorsque la variable <variable name> est déclaré dans le périmètre courant. Autrement FALSE est retourné.

Exemple 293. Exemple

Prérequis : Les deux candidatures App1 et App2 exister. La variable g_bTest est déclaré dans App1, mais pas dans App2.

{IF defined (variable: g_bTest)}
    (* the following code is only processed in App2*)
    g_bTest := x > 300;
{END_IF}


defined (<identifier>)

L'opérateur donne à l'expression la valeur TRUE. L'exigence est que l'identifiant <identifier> a été défini au moyen d'un {define} déclaration et non indéfini après avec un {undefine} déclaration. Autrement FALSE est retourné.

Exigence : Les candidatures App1 et App2 exister. le pdef1 variable est définie par un {define} déclaration dans App1, mais pas dans 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}

Cela inclut également un exemple de pragma de message : seul le message pdef1 defined s'affiche dans la vue des messages lors de la compilation de l'application car pdef1 est en fait défini. Le message pdef1 not defined s'affiche lorsque pdef1 n'est pas défini.

defined (type: <identifier> )

L'opérateur donne à l'expression la valeur TRUE lorsqu'un type de données est déclaré avec l'identifiant <identifier>. Autrement FALSE est retourné.

Exemple 294. Exemple

Prérequis : Les deux candidatures App1 et App2 exister. Le type de données DUT est déclaré dans App1, mais pas dans App2.

{IF defined (type: DUT)}
    (* the following code is only processed in App1*)
    bDutDefined := TRUE;
{END_IF}


defined (pou: <pou name>)

L'opérateur donne à l'expression la valeur TRUE lorsque l'un des objets suivants avec le nom <pou-name> existe :

  • Bloc fonction

  • Fonction

  • Programme

  • Action

  • Méthode

  • Interface

Autrement FALSE est retourné.

Exemple 295. Exemple

Prérequis : Les deux candidatures App1 et App2 exister. Le POU CheckBounds existe dans App1, mais pas dans 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>)

Important

Pas encore mis en œuvre

L'opérateur donne à l'expression la valeur TRUE si un objet ressource nommé <identifier> existe pour l'application ; autrement FALSE est retourné.

Prérequis : Les deux candidatures App1 et App2 exister. Un objet ressource glob_var1 de la liste des variables globales existe pour App1, mais pas pour 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> )

L'opérateur donne à l'expression la valeur TRUE lorsqu'une tâche est définie avec le nom <task name>. Autrement FALSE est retourné.

Syntaxe

{ IF defined (task: <task name> }
{ ELSIF defined (task: <task name> }
Exemple 296. Exemple
{IF defined (task: Task_D)}


Exemple 297. Exemple

Prérequis : Les deux candidatures App1 et App2 exister. La tâche PLC_PRG_Task est défini 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}


defined (IsLittleEndian)

L'opérateur donne à l'expression la valeur FALSE lorsque la mémoire CPU est organisée en Big Endian (ordre des octets Motorola).

defined (IsSimulationMode)

L'opérateur donne à l'expression la valeur TRUE lorsque l'application s'exécute sur un appareil simulé (en mode simulation).

Pour plus d'informations, consultez : Test en mode simulation

defined (IsFPUSupported)

Si l'expression renvoie la valeur TRUE, alors le générateur de code produit un code FPU (pour le processeur d'unité à virgule flottante) lors du calcul avec REAL valeurs. Sinon, les opérations FPU sont émulées, ce qui est beaucoup plus lent.

hasattribute (pou: <pou name>, ' <attribute name> ')

L'opérateur donne à l'expression la valeur TRUE lorsque l'attribut <attribute> est spécifié dans la première ligne de la partie déclaration du bloc fonction <pou name>. Autrement FALSE est retourné.

Exemple 298. Exemple

Prérequis : Les deux candidatures App1 et App2 exister. La fonction fun1 est déclaré dans App1 et App2. Cependant, dans App1 il est également fourni avec le pragma {attribute 'vision'}.

Dans App1:

{attribute 'vision'}
FUNCTION fun1 : INT
VAR_INPUT
    i : INT;
END_VAR
VAR
END_VAR

Dans App2:

FUNCTION fun1 : INT
VAR_INPUT
    i : INT;
END_VAR
VAR
END_VAR

Déclaration pragmatique :

{IF hasattribute (pou: fun1, 'vision')}
    (* the following code is only processed in App1 *)
    ergvar := fun1(ivar);
{END_IF}


hasattribute (variable: <variable name> , ' <attribute name> ')

L'opérateur donne à l'expression la valeur TRUE quand le pragma {attribute '<attribute>'} est affecté à la variable dans la ligne avant la déclaration de la variable. Autrement FALSE est retourné.

Exemple 299. Exemple

Prérequis : Les deux candidatures App1 et App2 exister. La variable g_globalInt est utilisé dans App1 et App2, mais en App1 l'attribut 'DoCount' lui est également attribué.

Déclaration de g_GlobalInt dans App1

VAR_GLOBAL
    {attribute 'DoCount'}
    g_globalInt : INT;
    g_multiType : STRING;
END_VAR

Déclaration g_GlobalInt dans App2:

VAR_GLOBAL
    g_globalInt : INT;
    g_multiType : STRING;
END_VAR

Déclaration pragmatique :

{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> )

L'opérateur vérifie si la constante, qui est identifiée par <constant name>, a été remplacé. Le deuxième paramètre (valeur booléenne) contrôle ce qui est coché :

  • TRUE: Vérifie si la constante a été remplacée

  • FALSE: Vérifie si la constante n'a pas été remplacée

Lorsque le cas respectif se produit, l'opérateur retourne TRUE.

Syntaxe

{ IF hasconstanttype( <constant namne> , <boolean literal> ) }

{ ELSIF hasconstanttype( <constant namne> , <boolean literal> ) }

Exemple 300. Exemple
 {IF hasconstanttype(PLC_PRG.aConst, TRUE)}


. Le remplacement automatique des constantes dépend en principe des éléments suivants :
  • Option de compilation Remplacer les constantes

  • Type constant (par exemple, STRING les types ne sont jamais remplacés.)

  • Utilisation de l'attribut {attribute 'const_non_replaced'}

  • Utilisation de l'attribut {attribute 'const_replaced'}

Exemple 301. Exemple
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> )

L'opérateur compare la valeur de la constante, qui est identifiée par <constant name>, avec la valeur du deuxième paramètre. Le deuxième paramètre peut être spécifié soit comme un littéral <literal> ou comme variable <variable name>.

. Opérateurs de comparaison <comparison operator>:
  • Plus grand que (>)

  • Plus grand ou égal à (>=)

  • Égal à (=)

  • Pas égal à (<>)

  • Inférieur ou égal à (<=)

  • Moins que (<)

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 302. Exemple
{IF hasconstantvalue(PLC_PRG.aConst, 99, >)}
{ELSIF hasconstantvalue(PLC_PRG.aConst, GVL.intconst99, =)}


Exemple 303. Exemple
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> )

L'opérateur donne à l'expression la valeur TRUE lorsque la variable <variable> est du type de données <type-spec>. Autrement FALSE est retourné.

Types de données possibles :

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

Exemple 304. Exemple

Prérequis : Les deux candidatures App1 et App2 exister. La variable g_multitype est déclaré dans App1 avec le type de données LREAL, dans App2 avec le type de données 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> ')

Le mode de pack vérifié dépend de la description de l'appareil, et non du pragma qui peut être spécifié pour les DUT individuels.

hasvalue (RegisterSize, ' <register size> ')

<register size>: Taille d'un registre CPU (en bits)

L'opérateur fait en sorte que l'expression renvoie la valeur TRUE lorsque la taille d'un registre CPU est égale à <register size>.

Valeurs possibles pour <register size>

  • 16 pour C16x,

  • 64 pour X86-64 bits

  • 32 pour X86-32 bits

hasvalue (<define-ident>, ' <character string> ')

L'opérateur donne à l'expression la valeur TRUE lorsqu'une variable est définie avec l'identifiant <define-ident> et a la valeur <char-string>. Autrement FALSE est retourné.

Exemple 305. Exemple

Prérequis : Les deux candidatures App1 et App2 exister. La variable test est utilisé dans les applications App1 et App2. Dans App1, on lui donne la valeur 1. Dans App2, on lui donne la valeur 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>)

Cet opérateur est disponible à partir du CODESYS V3.5 SP20.

L'opérateur fait en sorte que l'expression reçoive la valeur TRUE si la définition globale <global define> est inclus dans la liste des définitions globales dans le Options de compilation des paramètres du projet.

L'opérateur est spécifié comme condition d'un IF et peut être utilisé à la fois dans la partie implémentation et dans la partie déclaration des POU et des bibliothèques ST. Ils peuvent être combinés avec d'autres définitions au moyen du AND et OR opérateurs si ceux-ci sont autorisés à la position respective.

Dans la partie déclaration des POU, IF déclarations avec l'opérateur project_defined (<global define>) peut contenir les constructions suivantes :

  • Déclarations de variables

    Exemple:

    {If project_defined(define1)}
        x : DINT;
    {END_IF}
  • commentaires

  • Déclarations d'attributs

  • Déclarations pragmatiques

Les constructions suivantes sont pas possible:

  • Déclarations de variables complètes

    Exemple

    {If project_defined(define1)}
    VAR
        x : DINT;
    END_VAR
    {END_IF}
  • Déclarations complètes des POU

    Exemple:

    {If project_defined(define1)}
    FUNCTION POU : BOOL
    VAR_INPUT
        x : INT;
    END_VAR
    {END_IF}
  • Portées : VAR_INPUT, VAR_OUTPUT, VAR_IN_OUT

NOT <operator>

L'expression prend la valeur TRUE lorsque la valeur inverse de <operator> renvoie la valeur TRUE. <operator> peut être l'un des opérateurs décrits dans ce chapitre.

Exemple 306. Exemple

Prérequis : Les deux candidatures App1 et App2 exister. PLC_PRG1 existe dans App1 et App2, et le POU CheckBounds n'existe que dans 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>

L'expression prend la valeur TRUE lorsque les deux opérateurs spécifiés reviennent TRUE. <operator> peut être l'un des opérateurs décrits dans ce chapitre.

Exemple 307. Exemple

Exigence : Les candidatures App1 et App2 exister. PLC_PRG1 existe dans App1 et App2, et le POU CheckBounds n'existe que dans 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>

L'expression retourne TRUE lorsque l'un des deux opérateurs spécifiés revient TRUE. <operator> peut être l'un des opérateurs décrits ici.

Exemple 308. Exemple

Prérequis : Les deux candidatures App1 et App2 exister. Le POU PLC_PRG1 existe dans App1 et App2, et le POU CheckBounds n'existe que dans 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>)

() met entre parenthèses les opérateurs.