You can add the following attribute keywords to the declaration of the variable type in order to specify the scope:
RETAIN
: refer to Retain Variables
PERSISTENT
: refer to Persistent Variables
CONSTANT
: refer to Constants - CONSTANT, Typed Literals
VAR_GENERIC CONSTANT
: refer to Constants - VAR_GENERIC CONSTANT
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).
VAR PERSISTENT
declaration is interpreted in the same way as a VAR PERSISTENT RETAIN
or VAR RETAIN PERSISTENT
.
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.
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
command ). 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
command and, in contrast to persistent variables, when executing the command or in the course of an application download.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 | |
---|---|
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 are identified by keyword PERSISTENT
(VAR_GLOBAL PERSISTENT
). They are only reinitialized when executing the command . In contrast to retain variables, they maintain their values after a download.
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.
VAR_GLOBAL PERSISTENT
has the same effect as a declaration with VAR_GLOBAL PERSISTENT RETAIN
or VAR_GLOBAL RETAIN PERSISTENT
.
PERSISTENT
keyword outside the persistent list editor. For further information, refer to the 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
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.
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.
PERSISTENT
, then the function block instance with its variables is stored in remanent memory, but only the one variable is treated as persistent.
Consult the Programming Guide specific to your controller for further information on the behavior of remanent variables.
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.
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
.
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');
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.