Anatomy of Persistent Data in TwinCAT

Description of persistent data handling under TwinCAT 3

TwinCAT saves the persistent data for each runtime system in a file during each orderly shutdown, i.e. when switching from Run to Config or Stop mode.

Download the sample content:   The file name consists of the ADS port name of the runtime system with the file extension .bootdata, e.g.: Port_851.bootdata and is stored in the TwinCAT directory under TwinCAT\3.1\Boot\PLC.

When the system is restarted, i.e. when switching to run mode, this file is read and then saved as Port_xxx.bootdata-old.

If the file Port_xxx.bootdata-old already exists, it is overwritten.

The original file Port_xxx.bootdata then no longer exists. It is created again automatically when switching to Stop mode or by the function block FB_WritePersistentData from the TC2_Utilities library.

This behavior applies to each runtime system; each system has its own files with persistent data.

If the file is defective when the TwinCAT system is restarted, the system automatically accesses the backup file Port_xxx.bootdata-old. However, this behavior only applies if the Clear Invalid Persistent Data checkmark is unchecked in the runtime settings. If it is checked and the original file is defective, no data will be read.


Figure 1: Invalid persistent data option for runtime


The Port_xxx.bootdata-old backup file is also used when the controller is de-energized. In this case, too, the current persistent data is not stored in Port_xxx.bootdata. When the system is restarted, only the old data is available, unless a more up-to-date file was created by the FB_WritePersistentData function block before the system was switched off.

Figure 2: Boot data loading process

Remanent Variables - PERSISTENT, RETAIN

Remanent variables can retain their values beyond the usual program runtime. Remanent variables can be declared as RETAIN variables or even more strictly as PERSISTENT variables in the PLC project.

A prerequisite for the full functionality of RETAIN variables is a corresponding memory area on the controller (NovRam). Persistent variables are written only when TwinCAT shuts down. This will require usually a corresponding UPS. Exception: Persistent variables can also be written with the FB_WritePersistentData function block.

If the corresponding memory area does not exist, the values of RETAIN and PERSISTENT variables are lost during a power failure.

Persistent Variables:

You can declare persistent variables by adding the keyword PERSISTENT after the keyword for the variable type (VAR, VAR_GLOBAL, etc.) in the declaration part of programming objects. PERSISTENT variables retain their value after an uncontrolled termination, a Reset cold or a new download of the PLC project.

When the program restarts, the system continues to operate with the stored values. In this case TwinCAT reinitializes “normal” variables with their explicitly specified initial values or with the default initializations.

In other words, TwinCAT only reinitializes PERSISTENT variables during a Reset origin.

An application example for persistent variables is an operating hour counter, which is to continue counting after a power failure and when the PLC project is downloaded again.

Persistent example:

    nVarPers1 : DINT; (* 1. Persistent variable *)
    bVarPers2 : BOOL; (* 2. Persistent variable *)

RETAIN variables:

You can declare RETAIN variables by adding the keyword RETAIN after the keyword for the variable type (VAR, VAR_GLOBAL, etc.) in the declaration part of programming objects.

Variables declared as RETAIN are target system-dependent, but typically managed in a separate memory area that must be protected against power failure. The so-called Retain handler ensures that the RETAIN variables are written at the end of a PLC cycle and only in the corresponding area of the NovRam. The handling of the retain handler is described in chapter “Retain data” of the C/C++ documentation.RETAIN variables retain their value after an uncontrolled termination (power failure). When the program restarts, the system continues to operate with the stored values. In this case TwinCAT reinitializes “normal” variables with their explicitly specified initial values or with the default initializations.

TwinCAT reinitializes RETAIN variables at a reset origin.

One possible application is a part counter in a production plant, which should continue to count after a power failure.

Retain example:

    nRem1 : INT;

Figure 3: Comparison of variables in the context of program start

If we press on reset cold then all data will be reset to default except persistent and retain data. If we press on the reset origin then event persistent and retain data will be initialized to initial value.

Figure 4: Reset origin and reset cold option in visual studio editor

How to reboot remote PLC

reStartPLC : BOOL := TRUE;
trigBoolean : BOOL:= FALSE;
myTimer : TON;
myTrig : R_TRIG;
fnReboot : NT_Reboot;
fnTCReStart : TC_Restart;
sysERR              : BOOL;
sysERRID            : UDINT;
bOldData            : BOOL;
myTestTrig          : R_TRIG;
systemInfo          : PlcAppSystemInfo;
test1               : BOOL := TRUE;
test2               : BOOL := FALSE;
longCounter : UDINT;

//bOldData:= TwinCAT_SystemInfoVarList._AppInfo.OldBootData;
IF myTestTrig.Q  THEN
longCounter:= 87654;
test1:= FALSE;
test2 := bOldData;
bOldData:= TwinCAT_SystemInfoVarList._AppInfo.OldBootData;
myTimer(IN:= TRUE, PT:= T#600S);
IF myTimer.Q  THEN
trigBoolean := TRUE;
trigBoolean := FALSE;
IF myTrig.Q  THEN
longCounter := longCounter +1;
reStartPLC:= FALSE;
fnTCReStart(NETID:='',  RESTART:= trigBoolean,TMOUT:= T#5S);
sysERR:= fnTCReStart.ERR;
sysERRID:= fnTCReStart.ERRID;
reStartPLC:= TRUE;
fnReboot(NETID:='', DELAY := 1, START:= trigBoolean,TMOUT:= T#5S);
sysERR:= fnReboot.ERR;
sysERRID:= fnReboot.ERRID;
fnReboot(START:= FALSE);

See also

For details about how to save settings in persistent memory in PLC, you could take a look at


Download the sample from the link given above.

Next, let’s try to understand the task, scan time at

Ask questions related to Hemelix sample code and design at Google group