Skip to main content

Definition of Persistent Variables

Single variables as well as structure instances and function block instances can be marked as "persistent" by the use of attributes. When an instance is marked, all members of VAR, VAR_INPUT, and VAR_OUTPUT will be stored persistently. In case that variables in a VAR PERSISTENT section are marked as "persistent", a warning will be created.

Additionally there are attributes for defining a default storage group, as well as for excluding particular variables from the persistent storage of structures or function block instances.

If the definition of persistent variables has been modified (adding, removing, renaming, changing data type) no new composer code generation (command Generate) must be executed. These changes will be updated in the Persistent Manager instances automatically during compilation.

For information about the possible implicit conversions in case of a modified data type definition please, see: Parameter

Supported data types

Instances with the following data types cannot be stored persistently:

  • BIT

  • Pointer

  • Interfaces

  • Constants

  • Arrays of non-persistent data types

All other data types are supported. This includes enumerations, subrange data types, arrays of arrays and multidimensional arrays:

ARRAY[0..9] OF ARRAY[5..6, 7..8, 9..10] OF INT

Data Type: UNION

To save the instance of an union persistently, one of its fields must be marked as "representative". There are three possible ways:

  • Exactly one field in the declaration of the union is marked with the attribute ac_persist_union_representant (without attribute value). This field then "represents" the union. Its value will be saved and loaded representatively for the complete union.

  • Exact one field in the declaration of the union is marked with the attribute ac_persist – this defines the representative at the same time.

  • The instance of the union is marked with the attribute ac_persist_union_set_representant including the attribute value. The attribute value describes the name of the union field which shall be used as representative. This attribute overwrites an existing ac_persist_union_representant attribute in the declaration of the union. Arrays of unions can also be marked and refer to the elements of the array.

Example 2. Examples

'ac_persist_union_representant'

TYPE UnionWithRep :
UNION
        di : DINT ;
        {attribute 'ac_persist_union_representant'}
        dw : DWORD ;
END_UNION
END_TYPE

'ac_persist'

TYPE UnionWithPersist :
UNION
        di : DINT ;
        {attribute 'ac_persist' := 'TestUnion'}
        dw : DWORD ;
END_UNION
END_TYPE

'ac_persist_union_set_representant‘

FUNCTION_BLOCK FBTestUnion
VAR
        {attribute 'ac_persist_union_set_representant' := 'dw'}
        u2 : UnionWithoutRep ;
END_VAR

Array of union

VAR
        {attribute 'ac_persist_union_set_representant' := 'dw'}
        aElems ARRAY[0..7] OF SomeUnion ;

        {attribute 'ac_persist_union_set_representant' := 'dw'}
        aaElems ARRAY[0..7] OF ARRAY[0..1] OF SomeUnion ;
END_VAR


. For a representative to be valid, it has to fulfill the following rules:
  • The representative must have the same size as the whole union. Otherwise the complete data would not be saved. The representative also must not have any padding areas (empty data areas created by the compiler to align the data in the storage).

  • The decomposition of the representative in primitive data types must not contain instances of type REAL or LREAL or instance of type STRING or WSTRING.

  • Furthermore the representative must consist of supported types (see above). For example the representative can be of type Structure – however, the structure itself must not contain Pointer.

Attribute: 'ac_persist'

The attribute ‘ac_persist‘ can be used for

  • Variables

  • Instances of structures

  • Instances of function blocks

  • Members of structures

  • Members of function blocks

{attribute 'ac_persist' [ := '<PERSISTENCE_GROUP>']}

PERSISTENCE_GROUP is the name of the persistence group to which the declaration should be assigned. It must be a valid IEC identifier. If no persistence group is named here, the assignment will be done according to attribute 'ac_persist_set_default_group', which in this case must be defined.

If a structure instance or a function block instance is marked as "persistent" and at least one member in the declaration is also marked as "persistent" an error message will be created.

Example 3. Example for a persistent instance

The variable t is assigned to the persistence group PROCESS. All members will be stored persistently.

PROGRAM PLC_PRG
VAR
        {attribute 'ac_persist' := 'PROCESS'}
        t : TON;
END_VAR


Example 4. Example for a persistent members of a function block

The member iNumIOs is assigned to the persistence group CONFIG. This member will be stored persistently for all instances of the function block (if not explicitly suppressed by the attribute 'ac_persist_exclude').

FUNCTION_BLOCK FB
VAR
        {attribute 'ac_persist' := 'CONFIG'}
        iNumIOs : INT := 0;
END_VAR


Attribute: 'ac_persist_set_default_group'

If the group name is missing in the attribute 'ac_persist', a default group must be defined in a function block instance or structure instance containing the respective variable directly or indirectly. This is possible with the attribute 'ac_persist_set_default_group'. The attribute also can be set for a member of the function block. The innermost found definition of 'ac_persist_set_default_group' will be used as default group for the variable.

It is not allowed to use 'ac_persist_set_default_group' together with 'ac_persist' or 'ac_persist_exclude'. In this case an error message will be created during code generation.

Example 5. Example for a default group
FUNCTION_BLOCK FB_Util
VAR
        {attribute 'ac_persist'} // keine Gruppe
        i : INT := 0;
END_VAR
PROGRAM PLC_PRG
VAR
        {attribute 'ac_persist_set_default_group' := 'PROCESS'}
        fbu1 : FB_Util;

        {attribute 'ac_persist_set_default_group'´ := 'CONFIG'}
        fbu2 : FB_Util;
END_VAR


Attribute: 'ac_persist_exclude'

The attribute 'ac_persist_exclude' is used to exclude a variable from the persistent storage, no matter if members in the structure or function block declaration are defined as "persistent". If there exist no persistent members in the declaration an error will be created during code generation.

Example 6. Example for exclusion of variables
PROGRAM PLC_PRG
VAR
        {attribute 'ac_persist_exclude'}
        fb1 : FB;
END_VAR