Remanent Variables - RETAIN, PERSISTENT¶
Remanent variables can retain their value throughout the usual program run period. You can declare remanent variables as RETAIN
variables or, even stricter, as persistent variables in the application. The requirement for full functionality is an appropriate memory range on the controller (NVRam, UPS). If there is no suitable memory range, the values of VAR RETAIN
or VAR PERSISTENT
variables will be lost in the event of a power failure!
Attention
- CODESYS treats a
VAR PERSISTENT
declaration in the same way as aVAR PERSISTENT RETAIN
orVAR RETAIN PERSISTENT
declaration. - If you open a CoDeSys V2.3 project, the declarations of Retain variables are retained and remain effective. However, you must revise the declarations of persistent variables or create new ones. You must prepare a global variable list of its own for V3!
- The
AT
declaration may not be used in combination withVAR RETAIN
orVAR PERSISTENT
!
RETAIN variables
You declare RETAIN
variables by adding the keyword RETAIN
behind the keyword for the type of variable (VAR
, VAR_GLOBAL
, etc.) in the declaration part of programming objects.
RETAIN
variables retain their value after an uncontrolled termination (or online command Reset warm). On restarting the program the system continues to operate with the stored values. In this case CODESYS re-initializes ‘normal’ variables either with their explicitly specified initial values or with the standard initializations.
Variables declared as RETAIN
are managed depending on the target system, but typically in their own memory range, which must be secured against power failure.
CODESYS re-initializes RETAIN
variables in the case of
- the command Reset origin
- the command Reset cold (as opposed to persistent variables)
- a repeated program download
Examples
In a POU:
VAR RETAIN
iRem1 : INT;
END_VAR
In a GVL:
VAR_GLOBAL RETAIN
gvarRem1 : INT;
END_VAR
The degree of the value retention of RETAIN
variables is automatically contained in that of PERSISTENT
variables.
One possible application is a piece counter in a manufacturing plant that should continue to count after a power failure.
Attention
- If you declare a local variable in a program as
RETAIN
, CODESYS stores precisely this variable in the Retain range (like a global Retain variable). - If you declare a local variable in a function block as
RETAIN
, CODESYS stores the complete instance of this function block in the Retain range (all data of the function block); however, only the declaredRETAIN
variable is treated as such. - If you declare a local variable in a function as
RETAIN
, this has no effect. CODESYS does not store the variable in the Retain range. If you declare a local variable in a function asPERSISTENT
, this similarly has no effect.
Persistent variables
Unlike in CoDeSys V2.3, CODESYS treats persistent variables in V3 as follows:
You declare persistent variables by adding the keyword PERSISTENT
behind the keyword for the type of variable (VAR
, VAR_GLOBAL
, etc.) in the declaration part of programming objects.
Like the RETAIN
variables, PERSISTENT
variables retain their values in the case of a Reset cold, a repeated download of the application and a Reset warm (therefore VAR PERSISTENT
always corresponds to a VAR PERSISTENT RETAIN
or VAR RETAIN PERSISTENT
declaration). CODESYS thus re-initializes PERSISTENT
variables only in case of Reset origin
.
One example application for persistent variables is an operating hour meter, which should continue to count after a power failure and also after a repeated download of the application.
2 possibilities to define persistent variables
- Declaration with the persistence editor in a special global variable list of the object type Persistent variables, which belongs to an application (
VAR_GLOBAL PERSISTENT
). There can only be ONE such list per application and CODESYS treats only the variables declared asPERSISTENT
in this list as persistent.VAR PERSISTENT
declarations that are present in other POUs are added to the list using the menu command . GlobalPERSISTENT
declarations in other modules are not permitted. As with Retain variables, there must be an appropriately secured memory range on the controller for persistent variable lists in order to guarantee the retention of values in the case of a power failure! - Definition in the Persistence Manager of the Application Composer. This takes place via a completely different mechanism to that for the declaration of the
VAR PERSISTENT
in the persistence editor and requires, for example, no special memory. Further information about this can be found in the chapters on the Persistence Manager of the Application Composer.
Note
From CODESYS V3.3.0.1 a declaration with VAR_GLOBAL PERSISTENT
has the same effect as a declaration with VAR_GLOBAL PERSISTENT RETAIN
or VAR_GLOBAL RETAIN PERSISTENT
.
Example
Persistent variable list:
VAR_GLOBAL PERSISTENT RETAI
iVarPers1 : DINT; (* 1. persistent+retain variable App1 *)
bVarPers : BOOL; (* 2. persistent+retain variable App1 *)
// instance path of the persistent variables created
PLC_PRG.PERS: INT;
END_VAR
Attention
- you should avoid the use of the data type
POINTER TO
in persistent variable lists, since the address values can change in the case of repeated downloads of the application! CODESYS displays corresponding compiler warnings. - Each time the application is reloaded, CODESYS compares the persistent variable list on the controller with that of the project. In case of inconsistencies, i.e. changes of declarations and positions within the list, CODESYS requests you to re-initialize all persistent variables before the download. Inconsistency results from the renaming or deleting or some other change of existing persistent variable declarations.
Mechanism of persistence via VAR PERSISTENT
Changes in an existing persistent variable listcan lead to re-initializations, i.e. to loss of persistence. If you anticipate frequent changes due to the area of application, such a list is not recommended in principle. This mainly concerns the change of name or data type of a variable that has already been declared (see below: ‘Changing an existing declaration’). The editor treats the insertion of new declarations or the deletion of existing declarations with newer CODESYS versions (> V3.5 SP1) as follows:
The editor for the persistent variable list arranges the persistent variables in the way the variables are expected on the controller. The technique is as follows: CODESYS stores a checksum and the length of the persistent variables on the controller. During a download, CODESYS uploads these values and compares them with the current values. All variables up to the specified length are compared with the current variables in the project. If the variables are still identical, then they remain uninitialized; the new variables are initialized. The editor intervenes in the variable list, i.e. it replaces deleted variables in the memory by placeholder variables and moves newly inserted variables to the end of the list. As a result you can apparently modify them as desired, but you create gaps. The consequence of these gaps is that the memory may no longer suffice for placeholder variables. Therefore, you should clean the gaps after a while (command Reorder list and clear gaps). After cleaning, however, the list will no longer match the list on the controller and the persistent variables will be initialized.
In order to retain the values beyond such a cleaning process, you must store the values in a recipe with the help of the recipe manager before the cleaning process and reload them afterwards.
Changing an existing declaration in the persistent variable list: if you change the name or data type of a variable, this is interpreted as a new declaration and causes a re-initialization of the variables at the next online change or download! It is a case of a change of a user-defined data type, for example: if a new variable is added in a structure, or if the type of a variable changes from INT to UINT in the depth of a used structure. Hence, complex user-defined data types are not suitable for the management in a persistent variable list, at least if it is anticipated that the definition of the user-defined data type will have to be continually changed.
Generally you should not have to continually change a persistent variable list. If you expect this to be necessary in practice, however, it is better to set up the persistence via the Persistence Manager of the Application Composer, since this offers better value retention mechanisms for such cases (disadvantage: considerable losses of performance in the case of large numbers of persistent variables). In special cases you can consider storing the current values of variables in a recipe from the outset in order to reload the variable values to the controller after the next download.
Overview table for the behavior with RETAIN and PERSISTENT declared variables
after online command | :code:`VAR`\ | :code:`VAR RETAIN`\ | :code:`VAR RETAIN PERSISTENT`\ :code:`VAR PERSISTENT RETAIN`\ |
---|---|---|---|
Reset warm | - | x | x |
Cold reset | - | - | x |
Reset origin | - | - | - |
Download | - | - | x |
Online Change | x | x | x |
See also
- Programming of Applications
- Declaring VAR PERSISTENT Variables
- Persistence Manager: ac_pm_overview