Multiple tasks
Topics:
Details on protection from concurrent access are described in the chapter Multi-task data access synchronization in the PLC.
Avoid concurrent accesses to memory areas
You should avoid concurrent accesses to memory areas. For example, concurrent access to memory areas occurs when variables are read and/or written by more than one task with at least one write access.
Notice | |
Inconsistent variable values For example, if a global variable is accessed from multiple task contexts and at least one access is also write access, the variable value is very likely to become inconsistent. An inconsistent variable value usually has serious consequences on the program flow and can also cause a stop of the PLC. |
Static Analysis:
Verify using the following Static Analysis rules:
The rule SA0006 is also included in the license-free variant Static Analysis Light.
Negative sample:
GVL_Sample:
VAR_GLOBAL
nTestOutput AT%Q* : WORD; // Test output to be allocated
nGlobalCounter : UDINT;
nLastErrorID : UDINT;
END_VAR
Program Sample_neg_task_M, executed in task M:
PROGRAM Sample_neg_task_M
VAR
nLocalTaskM : WORD;
fbLocalTaskM : FB_Test;
END_VAR
GVL_Sample.nTestOutput := nLocalTaskM; // NON COMPLIANT: Task N reads variable being written by Task M whereas the accesses are not synchronized.
GVL_Sample.nGlobalCounter := GVL_Sample.nGlobalCounter + 1; // NON COMPLIANT: Task M & Task N write to GVL_Sample.nGlobalCounter
GVL_Sample.nLastErrorID := fbLocalTaskM.nErrorID; // NON COMPLIANT: Task M & Task N write to GVL_Sample.nLastErrorID
Program Sample_neg_task_N, executed in task N:
PROGRAM Sample_neg_task_N
VAR
nLocalTaskN : DWORD;
fbLocalTaskN : FB_Test;
END_VAR
nLocalTaskN := GVL_Sample.nTestOutput; // NON COMPLIANT: Task N reads variable being written by Task M whereas the accesses are not synchronized.
GVL_Sample.nGlobalCounter := 0; // NON COMPLIANT: Task M & Task N write to GVL_Sample.nGlobalCounter
GVL_Sample.nLastErrorID := fbLocalTaskN.nErrorID; // NON COMPLIANT: Task M & Task N write to GVL_Sample.nLastErrorID
Positive sample:
GVL_Sample:
VAR_GLOBAL
nTestOutput AT%Q* : WORD; // Test output to be allocated
nGlobalCounter : UDINT;
nLastErrorID_TaskM : UDINT; // only used in Task M
nLastErrorID_TaskN : UDINT; // only used in Task N
END_VAR
Program Sample_pos_task_M, executed in task M:
PROGRAM Sample_pos_task_M
VAR
nLocalTaskM : WORD;
fbLocalTaskM : FB_Test;
END_VAR
GVL_Sample.nLastErrorID_TaskM := fbLocalTaskN.nErrorID; // writes data that is declared for task M and only used in task M
IF (* special condition to synchronize access - see InfoSys chapter 'multitask data access' *) THEN
GVL_Sample.nTestOutput := nLocalTaskM;
GVL_Sample.nGlobalCounter := GVL_Sample.nGlobalCounter + 1;
END_IF
Program Sample_pos_task_N, executed in task N:
PROGRAM Sample_pos_task_N
VAR
nLocalTaskN : DWORD;
fbLocalTaskN : FB_Test;
END_VAR
GVL_Sample.nLastErrorID_TaskN := fbLocalTaskN.nErrorID; // writes data that is declared for task N and only used in task N
IF (* special condition to synchronize access – see InfoSys chapter 'multitask data access' *) THEN
nLocalTaskN := GVL_Sample.nTestOutput;
GVL_Sample.nGlobalCounter := 0;
END_IF
Avoid concurrent accesses to function blocks
You should avoid concurrent accesses to function blocks.
Access from several task contexts to one function block is not allowed. This concerns both the call of the body and of methods or properties. The internal process is very likely to result in inconsistent variable values. The effects are again serious consequences on the program sequence or an immediate stop of the PLC.
In a few exceptions, the definition of a function block allows access from several task contexts. If a function block is designed and developed for this use case, this is explicitly documented. In all other cases, global instantiation and use from several task contexts is not allowed.
Use global variables wisely
To prevent concurrent access and to support data encapsulation, avoid global instantiations if possible.
Likewise, you should avoid using existing global variables within function blocks if possible. You assign necessary data via input parameters.