Skip to main content

Pragma condizionali

Restrizione nel caso di pragma condizionali

Utilizzare i pragma per la compilazione condizionale solo nelle implementazioni di POU. Nelle dichiarazioni, questi pragma vengono ignorati, non valutati.

Notare la seguente eccezione: la pragma IF con il project_defined L'operatore può essere inserito nelle dichiarazioni. Per ulteriori informazioni, vedere quanto segue: pragma IF con project_defined (<global define>)

I pragma vengono valutati dal compilatore durante l'operazione di pre-compilazione e durante l'operazione di compilazione. Questa operazione è chiamata compilazione condizionale. Il linguaggio di implementazione ST supporta questi pragma.

Las pragmas {IF<expression> } insieme a {ELSIF<expression> }, {ELSE} e la conclusione {END_IF} indica il codice nelle implementazioni che viene mantenuto o ignorato a seconda delle condizioni specificate. Le condizioni specificate in <expression> sono espressioni costanti intere che possono essere composte da diversi operandi e operatori.

Durante la compilazione, la prima espressione nel <{IF <expression>} viene valutato. Se il suo valore di ritorno è FALSE, quindi la ramificazione avverrà nel prossimo {ELSIF <expression>} segmento e l'espressione valutata lì finché un segmento non restituisce un'espressione con TRUE Le espressioni vengono quindi valutate in successione finché una non restituisce un valore diverso da 0. Verrà compilato solo questo segmento di codice associato a un'espressione positiva. Gli altri vengono ignorati. Se tutte le espressioni restituiscono 0, si verifica una diramazione dopo {ELSE} Se il {ELSE} pragma è mancante, allora potrebbe succedere che non venga compilato alcun segmento di codice.

Sintassi

Esempio di frammento di codice

Descrizione

{IF <expression> }

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

Etichetta l'inizio del segmento di codice che viene compilato nel caso di un valido <expression> condizione.

{ELSIF <expression> }

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

Nessuno, uno o più)

Ramo che etichetta il segmento di codice alternativo se valido <expression> condizione

{ELSE}

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

Opzionale

Ramo che etichetta il segmento di codice che viene compilato se le condizioni precedenti non sono state soddisfatte

{END_IF}

{END_IF}

Etichetta la fine del segmento di codice condizionale

<expression>

defined (DEF0815)

Condizione

Espressione intera che è costante in fase di compilazione e può essere composta da operatori e operandi, come definizioni del compilatore, variabili o letterali

Definizione del compilatore

Le definizioni del compilatore vengono utilizzate come etichette per stati specifici nel codice. Una definizione del compilatore può essere impostata, eliminata o verificata utilizzando gli operatori definiti.

Sintassi

Esempio

Descrizione

{define <name> }

{define DEF0815}

Definisce la definizione del compilatore <name> con tipo BOOL

Nota

Il compilatore definisce <name> è soggetto alle regole per gli identificatori validi.

{define <name> <string> }

{define DEF0123 '123'}

Definisce la definizione del compilatore <name> e assegna la stringa letterale <string> come valore

{undefine <name>}

{undefine DEF0815}

Rimuove la definizione del compilatore <name>

Di conseguenza, l'identificatore non è definito. Un pragma con una definizione del compilatore non definita viene ignorato.

Suggerimento

In alternativa, è anche possibile definire espressioni e definizioni del compilatore localmente nelle proprietà di un POU oppure a livello di applicazione nelle proprietà dell'applicazione sovraordinata.

Per fare ciò, selezionare il POU o l'applicazione sovraordinata nell'albero dei dispositivi. Nel menu contestuale, fare clic su Proprietà e poi seleziona il Costruire scheda. Nella Compiler-Defines campo di input, è possibile definire un letterale o un'espressione (esempio: DEF0815). Il campo di input non si aspetta un'istruzione pragma come {define }, ma semplicemente un nome.

È possibile specificare più definizioni del compilatore separate da virgole.

Operatori

defined (variable: <variable name> )

L'operatore fa in modo che all'espressione venga assegnato il valore TRUE quando la variabile <variable name> è dichiarato nell'ambito di applicazione attuale. Altrimenti FALSE viene restituito.

Esempio 293. Esempio

Requisito: le due applicazioni App1 e App2 esistere. La variabile g_bTest è dichiarato in App1, ma non dentro App2.

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


defined (<identifier>)

L'operatore fa in modo che all'espressione venga assegnato il valore TRUE. Il requisito è che l'identificatore <identifier> è stato definito mediante a {define} enunciato e non indefinito successivamente con an {undefine} dichiarazione. Altrimenti FALSE viene restituito.

Requisito: le applicazioni App1 e App2 esistere. Il pdef1 variabile è definita da a {define} dichiarazione in App1, ma non dentro 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}

Ciò include anche un esempio di messaggio pragma: solo il messaggio pdef1 defined viene visualizzato nella visualizzazione dei messaggi quando l'applicazione viene compilata perché pdef1 è effettivamente definito. Il messaggio pdef1 not defined viene visualizzato quando pdef1 non è definito.

defined (type: <identifier> )

L'operatore fa in modo che all'espressione venga assegnato il valore TRUE quando un tipo di dati viene dichiarato con l'identificatore <identifier>. Altrimenti FALSE viene restituito.

Esempio 294. Esempio

Requisito: le due applicazioni App1 e App2 esistere. Il tipo di dati DUT è dichiarato in App1, ma non dentro App2.

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


defined (pou: <pou name>)

L'operatore fa in modo che all'espressione venga assegnato il valore TRUE quando uno dei seguenti oggetti con nome <pou-name> esiste:

  • Blocco funzione

  • Funzione

  • Programma

  • Azione

  • Metodo

  • Interfaccia

Altrimenti FALSE viene restituito.

Esempio 295. Esempio

Requisito: le due applicazioni App1 e App2 esistere. Il POU CheckBounds esiste in App1, ma non dentro 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>)

Importante

Non ancora implementato

L'operatore fa in modo che all'espressione venga assegnato il valore TRUE se un oggetto risorsa denominato <identifier> esiste per l'applicazione; altrimenti FALSE viene restituito.

Requisito: le due applicazioni App1 e App2 esistere. Un oggetto risorsa glob_var1 dell'elenco delle variabili globali esiste per App1, ma non per 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'operatore fa in modo che all'espressione venga assegnato il valore TRUE quando un'attività è definita con il nome <task name>. Altrimenti FALSE viene restituito.

Sintassi

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


Esempio 297. Esempio

Requisito: le due applicazioni App1 e App2 esistere. L'obiettivo PLC_PRG_Task è definito in App1, ma non dentro 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'operatore fa in modo che all'espressione venga assegnato il valore FALSE quando la memoria della CPU è organizzata in Big Endian (ordine dei byte di Motorola).

defined (IsSimulationMode)

L'operatore fa in modo che all'espressione venga assegnato il valore TRUE quando l'applicazione viene eseguita su un dispositivo simulato (in modalità simulazione).

Per ulteriori informazioni, vedere: Test in modalità simulazione

defined (IsFPUSupported)

Se l'espressione restituisce il valore TRUE, quindi il generatore di codice produce un codice FPU (per l'unità di elaborazione a virgola mobile) durante il calcolo con REAL i valori. In caso contrario, le operazioni FPU vengono emulate, il che è molto più lento.

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

L'operatore fa in modo che all'espressione venga assegnato il valore TRUE quando l'attributo <attribute> è specificato nella prima riga della parte di dichiarazione del blocco funzione <pou name>. Altrimenti FALSE viene restituito.

Esempio 298. Esempio

Requisito: le due applicazioni App1 e App2 esistere. La funzione fun1 è dichiarato in App1 e App2. Tuttavia, nel App1 è fornito anche del pragma {attribute 'vision'}.

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

Dichiarazione pragmatica:

{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'operatore fa in modo che all'espressione venga assegnato il valore TRUE quando il pragma {attribute '<attribute>'} viene assegnato alla variabile nella riga prima della dichiarazione della variabile. Altrimenti FALSE viene restituito.

Esempio 299. Esempio

Requisito: le due applicazioni App1 e App2 esistere. La variabile g_globalInt è usato in App1 e App2, ma in App1 l'attributo 'DoCount' gli è assegnato anche.

Dichiarazione di g_GlobalInt in App1

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

Dichiarazione g_GlobalInt in App2:

VAR_GLOBAL
    g_globalInt : INT;
    g_multiType : STRING;
END_VAR

Dichiarazione pragmatica:

{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'operatore verifica o meno la costante con cui si identifica <constant name>, È stato sostituito. Il secondo parametro (valore booleano) controlla ciò che viene verificato:

  • TRUE: Controlla se la costante è stata sostituita

  • FALSE: Controlla se la costante non è stata sostituita

Quando si verifica il rispettivo caso, l'operatore ritorna TRUE.

Sintassi

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

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

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


. La sostituzione automatica delle costanti in linea di principio dipende da quanto segue:
  • Opzione di compilazione Sostituisci le costanti

  • Tipo costante (ad esempio, STRING i tipi non vengono mai sostituiti.)

  • Utilizzo dell'attributo {attribute 'const_non_replaced'}

  • Utilizzo dell'attributo {attribute 'const_replaced'}

Esempio 301. Esempio
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'operatore confronta il valore della costante identificata con <constant name>, con il valore del secondo parametro. Il secondo parametro può essere specificato sia come valore letterale <literal> o come variabile <variable name>.

. Operatori di confronto <comparison operator>:
  • Più grande di (>)

  • Maggiore o uguale a (>=)

  • Uguale a (=)

  • Non uguale a (<>)

  • Minore o uguale a (<=)

  • Meno di (<)

Sintassi

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

Esempio 302. Esempio
{IF hasconstantvalue(PLC_PRG.aConst, 99, >)}
{ELSIF hasconstantvalue(PLC_PRG.aConst, GVL.intconst99, =)}


Esempio 303. Esempio
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'operatore fa in modo che all'espressione venga assegnato il valore TRUE quando la variabile <variable> è del tipo di dati <type-spec>. Altrimenti FALSE viene restituito.

Possibili tipi di dati:

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

Esempio 304. Esempio

Requisito: le due applicazioni App1 e App2 esistere. La variabile g_multitype è dichiarato in App1 con tipo di dati LREAL, in App2 con tipo di dati 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> ')

La modalità pacchetto selezionato dipende dalla descrizione del dispositivo, non dal pragma che può essere specificato per i singoli DUT.

hasvalue (RegisterSize, ' <register size> ')

<register size>: Dimensione di un registro della CPU (in bit)

L'operatore fa in modo che l'espressione restituisca il valore TRUE quando la dimensione di un registro della CPU è uguale a <register size>.

Possibili valori per <register size>

  • 16 per C16x,

  • 64 per X86-64 bit

  • 32 per X86-32 bit

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

L'operatore fa in modo che all'espressione venga assegnato il valore TRUE quando una variabile è definita con l'identificatore <define-ident> e ha il valore <char-string>. Altrimenti FALSE viene restituito.

Esempio 305. Esempio

Requisito: le due applicazioni App1 e App2 esistere. La variabile test viene utilizzato nelle applicazioni App1 e App2. In App1, viene assegnato il valore 1. In App2, viene assegnato il valore 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>)

Questo operatore è disponibile a partire da CODESYS V3.5 SP20.

L'operatore fa sì che l'espressione riceva il valore TRUE se il globale definisce <global define> è incluso nell'elenco delle definizioni globali in Opzioni di compilazione delle impostazioni del progetto.

L'operatore è specificato come condizione di an IF dichiarazione e può essere utilizzata sia nella parte di implementazione che nella parte di dichiarazione delle POU e delle librerie ST. Possono essere combinati con altre definizioni tramite il AND E OR operatori se questi sono ammessi nella rispettiva posizione.

Nella parte dichiarativa delle POU, IF dichiarazioni con l'operatore project_defined (<global define>) può contenere i seguenti costrutti:

  • Dichiarazioni variabili

    Esempio:

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

  • Dichiarazioni di attributi

  • Affermazioni pragmatiche

I seguenti costrutti sono non possibile:

  • Dichiarazioni complete di variabili

    Esempio

    {If project_defined(define1)}
    VAR
        x : DINT;
    END_VAR
    {END_IF}
  • Dichiarazioni complete delle POU

    Esempio:

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

NOT <operator>

All'espressione viene assegnato il valore TRUE quando il valore inverso di <operator> restituisce il valore TRUE. <operator> può essere uno degli operatori descritti in questo capitolo.

Esempio 306. Esempio

Requisito: le due applicazioni App1 e App2 esistere. PLC_PRG1 esiste in App1 e App2, e la POU CheckBounds esiste solo 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>

All'espressione viene assegnato il valore TRUE quando i due operatori specificati ritornano TRUE. <operator> può essere uno degli operatori descritti in questo capitolo.

Esempio 307. Esempio

Requisito: le applicazioni App1 e App2 esistere. PLC_PRG1 esiste in App1 e App2, e la POU CheckBounds esiste solo 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>

L'espressione ritorna TRUE quando uno dei due operatori specificati ritorna TRUE. <operator> può essere uno degli operatori qui descritti.

Esempio 308. Esempio

Requisito: le due applicazioni App1 e App2 esistere. Il POU PLC_PRG1 esiste in App1 e App2, e la POU CheckBounds esiste solo 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>)

() tra parentesi gli operatori.