Preserving Data with Persistent Variables

Persistent variables retain their values after reloading the application, and after a download, warm start, or cold start.

A special non-volatile memory area on the controller, for example as NVRAM or UPS, is required to extend the lifespan. Securing the data in such a memory does not require any additional time, which is an advantage over data retention with the Persistence Manager. If the controller does not provide hardware support, then the data is usually stored in a file. Then the data will be retained if you shut down the controller correctly. In the event of a power failure or a pulled plug, however, data will be lost.

Behavior

Value retained for

  • Uncontrolled exit
  • Warm start by calling the Reset warm command
  • Cold start by calling the Reset cold command
  • Repeated download of the application

Reinitialization for

  • Call of the Reset origin command

Therefore, persistent variables are reinitialized only if you reset the controller to the factory settings (for example, when you click Online ‣ Reset origin ).

If, on the other hand, you download the application again, the persisted data is retained if possible. That depends on how profound the changes that led to the download were. Changing the application name always leads to a full reinitialization. Changes to the implementations never lead to a reinitialization: the data persistence is completely preserved. Changes to the declarations lead to an initialization of the new variables only if the existing variables are persistent, when you change the declarations so that the persistent variable list remains consistent. This is the case when you add a new variable or delete an existing one. Inconsistencies can occur if you edit and change the identifiers or data types of previously declared persistent variables.

Mechanism for downloading

Editing the variable list in the persistence editor causes the variable list to be edited automatically before it is saved, not to be saved as it is shown in the editor.

During post-processing, a variable that you have removed is replaced by a placeholder variable with the same memory requirement. As a result, the subsequent variables retain their addresses in the process image. Moreover, a variable you add is moved to the end of the list. Post-processing can neutralize changes that would lead to a loss of persistence. But you create gaps that use additional memory.

When downloading, the CRC value of the variable list and the length of the list (number of variables) are stored on the controller. When downloading again, the new test value is compared with the test value currently on the controller. Then the variable list is compared successively up to the specified length. If you have edited a declaration (for example, the name or data type), then the variable is reinitialized. Otherwise its value is retained. When the download is repeated, CODESYS checks whether the variable list declared in the persistence editor is still consistent with the variable list already on the controller.

The mechanism works well when the variables themselves are not modified significantly. Too extensive changes of the identifiers and the data types continue to lead to a reinitialization and the loss of persistence. If you anticipate frequent changes due to your application requirements, then this kind of a list is not recommended. Moreover, in an online change after a data type change, a persistent variable is less robust than a variable with a normal lifespan.

It is good practice to clear any gaps in the variable list after a while (command Reorder list and clear gaps). After cleaning, however, the list no longer matches the list on the controller and you have triggered an initialization of all persistent variables. The persistence of all variables is lost.

Note

For versions before V3.5 SP1, changes in the persistence editor always lead to reinitialization.

Recovering data with the recipe manager

To clean up the global persistent variable list without losing persistence, you can save the data in a recipe using the Recipe Manager. This creates a list for all variables of the persistent variable list in the recipe manager, and at the same time its current values are stored by the controller as a recipe. Then execute the command Reorder list and clear gaps and perform a download again. Now when you execute the command Restore values from recipe, the values saved in the recipe are restored.

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. For complex data types, a change occurs when a new component is added, or when you change the type of a variable from INT to UINT in the depth of a used structure used, for example.

Basically, complex user-defined data types are not suitable for administration in a persistent variable list, because even small changes cause the variable to be initialized with all components.

Double allocation of memory in the case of instance paths

You can persist global variables or variables declared locally in a function block or program. To do this, add the keyword PERSISTENT to the declaration. In addition, you insert the instance path to this variable in the persistent global variable list. To do this, execute the Add all instance paths command in the persistence editor.

Persistence is guaranteed by the following mechanism:

  • The cyclic tasks in which the variable is accessed are determined.
  • At the end of the first cyclic task (in each cycle), the variable is copied to the persistent global variable list.
  • After restarting the controller, the value of the persistent variable is copied to the ordinary variable.

The disadvantage of this mechanism is that memory is allocated both at the place of declaration and at the place of the instance path. This persistent variable has a double memory allocation. Moreover, the data is copied to both places in each cycle. This can be time consuming, especially when large structured values are involved.

Memory location in the case of persistent function block instances

A function block instance is always stored completely in memory. This is necessary so that the same code can work on different instances. If only one variable in a function block is marked with PERSISTENT, then the function block instance is stored completely with all variables in remanent memory, although only the one variable is treated as persistent. However, non-volatile memory is not available to the same extent as main memory.

A function block with a pointer to an instance in SRAM as a variable is not stored in the protected memory.

Importing from CoDeSys V2.3 projects

When you open a CoDeSys V2.3 project to import it into CODESYS V3, the declarations of persistent variables are not preserved. You have to revise the declarations and create then again in a separate persistent global variable list.

See also