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 existingac_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.
'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
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
orLREAL
or instance of typeSTRING
orWSTRING
.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.
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
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.
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.
PROGRAM PLC_PRG VAR {attribute 'ac_persist_exclude'} fb1 : FB; END_VAR