Function Block to Write Persistent Variables

  • arj3090

    arj3090 - 2019-07-25

    Is the a function block that forces the values of the persistent variables to be written to the disk? I am using a Raspberry Pi which does not have a UPS. My list of persistent variables is small and change infrequently, so I can monitor the values for any changes and write the values when a change occurs.

  • yannickasselin1

    yannickasselin1 - 2019-07-25

    Good question. I know there is one in TwinCAT but I am not aware of any function block to do it in Codesys. I would be interrested to know.

  • arj3090

    arj3090 - 2019-07-26

    I am guessing the requested FB does not exist, so I started creating a function block to mimc the persistent variable functionality. It requires the SysFile library. It seems kind of clunky, but works. If anyone has any improvements or better options, I am open for them. This is what I have so far

       Write : BOOL;               //Edge triggered
       Read : BOOL;               //Edge triggered
       MemLocation : POINTER TO BYTE;   // e.g ADR(%MB0)
       ByteLength : DWORD;            // byte count to monitor and store
       MinTimeBetweenWrites : TIME;   // Used to limit writing
       WriteCount : DINT;            //Count showing number of times write was triggered
       LastWrite : BOOL;
       LastRead : BOOL;
       FileHandle : RTS_IEC_HANDLE;
       OpenResult: RTS_IEC_RESULT;
       WriteResult,ReadResult: RTS_IEC_RESULT;
       pCompare : POINTER TO BYTE;
       LastByteLength : DWORD;
       DifferenceFound : BOOL;
       index : DWORD;
       pWorking, pWorking2 : POINTER TO BYTE;
       FirstPass : BOOL;
       TimeBetweenWrites : TON;
    (* This function block is to provide an alternative to persitent variable values *)
    (* on systems that do not have a UPS or NOVRAM                                   *)
    (* CAUTION must be used because excessive writing can damage flash memory        *)
    (* MemLocation is specified like ADR(%MB0)  or ADR(V1)                                      *)
    (* Variable values to be saved are mapped to the block starting as specified     *)
    (* by MemLocation                                                                *)
    (* A method that works, but not guaranteed is to create a GVL only for the      *)
    (* variables to be persisted. Use ADR(firstvar) and calculate the byte length of *)
    (* all the variables in the list to use in ByteLength                            *)
    (* EDIT : The method above will not work as variables are added unless a Clean All*)
    (* is done to reorganize the variable memory assignments                         *)
    (* The memory block values are monitored for changes which will trigger the write*)
    (* The writing can be limited by using the MinTimeBetweenWrites                  *)
    (* Read input can be set to TRUE to load values on first scan                    *)
    (* Read the file and store in memory - rising edge triggered                  *)
    IF Read AND Read<>LastRead THEN
       IF OpenResult=0 THEN
    (* Create a memory area for comparing a change in values                      *)
    IF LastByteLength<>ByteLength THEN
       IF LastByteLength>0 THEN
       pCompare := __NEW(BYTE,ByteLength);
    (* Check for a change in values                                               *)
    // Do not set PT here so that first check occurs without delsy
    IF TimeBetweenWrites.Q THEN
       WHILE (index<ByteLength) DO
          IF (pWorking^ <> pWorking2^) THEN
             // Copy all values to working memory area for checking value chsnge
       IF DifferenceFound THEN
    (* Write Values to the file                                                   *)
    IF (Write AND Write<>LastWrite) OR (DifferenceFound AND FirstPass) THEN
       IF OpenResult=0 THEN
  • arj3090

    arj3090 - 2019-07-26

    Here is a sample of its use:

    IMG: SaveMemoryBlock.png

  • arj3090

    arj3090 - 2019-07-26

    With some more digging I did discover the function blocks to read and write retain variables do exist:



Log in to post a comment.