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.

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.


  

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.


Overview table showing the behavior of PERSISTENT variables


After online command

VAR PERSISTENT

Reset cold

Values are retained

Reset origin

Values are reinitialized

Download

Values are retained

Online Change

Values are retained

How to reboot remote PLC

//header
PROGRAM MAIN
VAR
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;
END_VAR
VAR PERSISTENT
longCounter : UDINT;
END_VAR


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