Attribute Keywords for Variable Types

Overview

You can add the following attribute keywords to the declaration of the variable type in order to specify the scope:

Remanent Variables - RETAIN, PERSISTENT

Remanent variables can retain their value throughout the usual program run period. Declare them as retain variables or even more stringent as persistent variables.

The declaration determines the degree of resistance of a remanent variable in the case of resets, downloads, or a reboot of the controller. In applications mainly the combination of both remanent flags is used (refer to Persistent Variables).

NOTE: A VAR PERSISTENT declaration is interpreted in the same way as a VAR PERSISTENT RETAIN or VAR RETAIN PERSISTENT.
NOTE: Use the command Add all instance paths to take variables declared as persistent into the Persistent list object.

Persistence is achieved by the following procedures:

  • Determining the cyclic tasks that access the variable.

  • Copying the variable to the persistent global variable list at the end of the first cyclic task (in each cycle).

  • Copying the value of the persistent variable to the normal variable at controller restart.

As memory is allocated both at the declaration and at the instance path, this persistent variable requires double memory allocation in each cycle. This can lead to extended processing times, especially with large, structured values.

Retain Variables

Variables declared as retain variables are stored in a nonvolatile memory area. To declare this kind of variable, use the keyword RETAIN in the declaration part of a POU or in a global variable list.

Example

VAR RETAIN
 iRem1 : INT; (* 1. Retain variable*)
END_VAR

Retain variables maintain their value even after an unanticipated shutdown of the controller as well as after a normal power cycle of the controller (or when executing the Online command Reset Warm). At restart of the program, the retained values will be processed further on. The other (non-retain) variables are newly initialized, either with their initialization values or with their default initialization values (in case no initialization value was declared).

For example, you may want to use a retained value when an operation, such as piece counting in a production machine, should continue after a power outage.

Retain variables, however, are reinitialized when executing the Online command Reset origin and, in contrast to persistent variables, when executing the Online command Reset cold or in the course of an application download.

NOTE: Only the specific variables defined as VAR RETAIN are stored in nonvolatile memory. However, local variables defined as VAR RETAIN in functions are NOT stored in nonvolatile memory. Defining VAR RETAIN locally in functions is of no effect.

Using interfaces or function blocks out of System Configuration libraries in the retain program section (VAR_RETAIN) will cause system exceptions, which may make the controller inoperable, requiring a re-start.

 WARNING
UNINTENDED EQUIPMENT OPERATION
  • Do not use interfaces out of the SystemConfigurationItf library in the retain program section (VAR_RETAIN).
  • Do not use function blocks out of the SystemConfiguration library in the retain program section (VAR_RETAIN).
Failure to follow these instructions can result in death, serious injury, or equipment damage.
NOTE: The libraries SystemConfigurationItf and SystemConfiguration are only available for PacDrive controllers (PacDrive LMC Eco, PacDrive LMC Pro/Pro2).
NOTE: If one variable in a function block is marked with RETAIN, then the function block instance with its variables is stored in remanent memory. This function is not available for all controllers. Consult the Programming Guide specific to your controller for detailed information.

Persistent Variables

Persistent variables are identified by keyword PERSISTENT (VAR_GLOBAL PERSISTENT). They are only reinitialized when executing the Online command Reset origin. In contrast to retain variables, they maintain their values after a download.

NOTE: Do not use the AT declaration in combination with VAR PERSISTENT.

Application example:

A counter for operating hours, which should continue counting even after a power outage or a download. Refer to the synoptic table on the behavior of remanent variables.

You can only declare persistent variables in a special global variable list of object type persistent variables, which is assigned to an application. You can add only one such list to an application.

NOTE: A declaration with VAR_GLOBAL PERSISTENT has the same effect as a declaration with VAR_GLOBAL PERSISTENT RETAIN or VAR_GLOBAL RETAIN PERSISTENT.
NOTE: Instant paths are added for variables that are marked with the PERSISTENT keyword outside the persistent list editor. For further information, refer to the Add all instance paths command.

Like retain variables, the persistent variables are stored in a separate memory area.

Example

VAR_GLOBAL PERSISTENT RETAIN
  iVarPers1 : DINT; (* 1. Persistent+Retain Variable App1 *)
  bVarPers : BOOL;  (* 2. Persistent+Retain Variable App1 *)
END_VAR
NOTE: Persistent variables can only be declared inside the Persistent list object. If they are declared elsewhere, they will behave like retain variables and they will be reported as a detected Build error in the Messages view. (Retain variables can be declared in the global variable lists or in POUs.)

At each reload of the application, the persistent variable list on the controller will be checked against that of the project. The list on the controller is identified by the application. In case of inconsistencies, you will be prompted to reinitialize all persistent variables of the application. Inconsistency can result from renaming or removing or other modifications of the existing declarations in the list.

NOTE: Carefully consider any modifications in the declaration part of the persistent variable list and the effect of the results regarding reinitialization.

You can add new declarations only at the end of the list. During a download, these are detected as new and will not demand a reinitialization of the complete list. If you modify the name or data type of a variable, this is handled as a new declaration and provokes a reinitialization of the variable at the next online change or download.

NOTE: If one variable in a function block is marked with PERSISTENT, then the function block instance with its variables is stored in remanent memory, but only the one variable is treated as persistent.

Behavior of Remanent Variables

Consult the Programming Guide specific to your controller for further information on the behavior of remanent variables.

Constants - CONSTANT

Constants are identified by the keyword CONSTANT. You can declare them locally (programming object unit) or globally (global variable list). Constant variables can be accessed read-only in the implementation part of a POU.

Syntax

<scope> CONSTANT <identifier>:<type> := <initialization>;
END_VAR

With <scope> : VAR | VAR_INPUT | VAR_STAT | VAR_GLOBAL

Make sure to assign an initialization value when declaring a constant variable.

Example

VAR CONSTANT
c_iCon1:INT:=12; (* 1. Constant*)
END_VAR

Refer to the Operands chapter for a list of possible constants.

Constants - VAR_GENERIC CONSTANT

A generic constant is a variable in the VAR_GENERIC CONSTANT declaration area of a function block which is not assigned an initialization value until the function block instance is assigned.

Syntax: Declaration of the function block:

FUNCTION_BLOCK <function block name>
VAR_GENERIC CONSTANT
    <generic constant name> : <integer data type> := <initial value>; //Initial value will be overwritten
END_VAR
;

You can use the generic constant (integer data type) within a function block for the size of arrays or the length of strings, for example. The initial value <initial value> is only needed for compile checks. At runtime, the value is overwritten.

Syntax: Declaration of the function block instance:

PROGRAM PLC_PRG
VAR
    <fb instance name> : <function block name> < <literal> >;
    <fb instance name> : <function block name> <( <expression> )>;
END_VAR
;

When the function block instances are declared, the constant is assigned a specific value which is valid exclusively for this instance. For this purpose, the value <literal> in angle brackets is appended to the function block <function block name> which acts as the data type.

As an alternative, an expression <expression> can be appended. Enclose it in parentheses to enable usage of symbols such as < or > in an expression and help you preserve the uniqueness of the code.

Example: Generic function block with parameterizable array variable:

The following code example demonstrates how to define a function block that can process arrays of arbitrary length. The function block has an array with a generic but constant length. In this context, the term constant means that although each function block instance varies in its array length, it remains constant during the lifetime of the object.

This can be useful in library programming, for example, for implementing a generic library POU.

FUNCTION_BLOCK FB_MyString 
VAR_GENERIC CONSTANT
    maxlen : UDINT := 1;
END_VAR
VAR
    test : ARRAY[0..maxlen-1] OF BYTE;
END_VAR
;
PROGRAM PLC_PRG
VAR CONSTANT
    cconst: DINT := 1000;
END_VAR
VAR    
    fbMyString1 : FB_MyString<100>;
    fbMyString2 : FB_MyString<(2 * cconst)>;
    arrMyString : ARRAY [0..5] OF FB_MyString<100>;
END_VAR
;

Inheritance

A function block with generic constants can also use the inheritance constructs EXTENDS and IMPLEMENTS.

NOTE: Ensure you insert first the declaration of the generic constants followed by EXTENDS and IMPLEMENTS because generic constants can also be used with base classes.

Inheritance example:

INTERFACE IString 
METHOD Append : BOOL 
VAR_INPUT     
    strAppend : IString; 
END_VAR 
METHOD Assign : BOOL
VAR_INPUT     
    stringIn: String; 
END_VAR 
METHOD ToString : STRING
VAR_INPUT 
END_VAR 
PROPERTY Length : DINT
FUNCTION_BLOCK MyString 
VAR_GENERIC CONSTANT        
    maxlen : UDINT; 
END_VAR 
IMPLEMENTS IString
FUNCTION_BLOCK LongString EXTENDS MyString<1000>
FUNCTION_BLOCK MySpecialString 
VAR_GENERIC CONSTANT        
    maxlen2 : UDINT:= 1; 
END_VAR 
EXTENDS MyString<maxlen2>
METHOD ToLatin1: STRING
PROGRAM PLC_PRG 
VAR CONSTANT     
    cconst: DINT := 1000; 
END_VAR
VAR     
    string1 : MyString<100>;
    string2 : MyString<(2 * cconst)>;
    derived1 : LongString;
    derived2 : MySpecialString<100>;
END_VAR 
string1.Assign ('Welt'); 
string2.Assign ('Hallo '); 
string2.Append(string1); 
derived2.ToLatin1('Hello World');

Typed Literals

Basically, in using IEC constants, the smallest possible data type will be used. If another data type has to be used, this can be achieved with the help of typed literals without the necessity of explicitly declaring the constants. For this, the constant will be provided with a prefix which determines the type.

Syntax

<type>#<literal>;

<type>

specifies the desired data type

possible entries: BOOL, SINT, USINT, BYTE, INT, UINT, WORD, DINT, UDINT, DWORD, REAL, LREAL

Write the type in uppercase letters.

<literal>

specifies the constant

Enter data that fits within the data type specified under <type>.

Example

iVar1:=DINT#34;

If the constant cannot be converted to the target type without data loss, a message is issued.

You can use typed literals wherever normal constants can be used.

Constants in Online Mode

As long as the default setting Replace constants (File > Project Settings > Compile options) is activated, constants in online mode have a symbol preceding the value in the Value column in the declaration or watch view. In this case, they cannot be accessed by, for example, forcing or writing.