SA0103: Gleichzeitiger Zugriff auf nicht-atomare Daten

Funktion

Ermittelt nicht-atomare Variablen (zum Beispiel mit Datentyp STRING, WSTRING, ARRAY, STRUCT, FB-Instanzen, 64-Bit Datentypen), die in mehr als einer Task verwendet werden.

Begründung

Wenn keine Synchronisation beim Zugriff erfolgt, dann kann es bei gleichzeitigem Lesen in einer Task und Schreiben in einer anderen Task dazu kommen, dass inkonsistente Werte gelesen werden.

Ausnahme

In folgenden Fällen greift diese Regel nicht:

  • Wenn das Zielsystem eine FPU (Floating Point Unit) besitzt, wird der Zugriff mehrerer Tasks auf LREAL-Variablen nicht ermittelt und gemeldet.
  • Wenn das Zielsystem ein 64-Bit Prozessor ist bzw. "TwinCAT RT (x64)" als Solution-Plattform ausgewählt ist, greift die Regel nicht für 64-Bit Datentypen.

Wichtigkeit

Mittel

SA0103: Gleichzeitiger Zugriff auf nicht-atomare Daten 1:

Sehen Sie auch die Regel SA0006: Schreibzugriff aus mehreren Tasks.

Beispiele:

Struktur ST_Sample:

TYPE ST_Sample :
STRUCT
    bMember : BOOL;
    nTest   : INT;
END_STRUCT
END_TYPE

Funktionsbaustein FB_Sample:

FUNCTION_BLOCK FB_Sample
VAR_INPUT
    fInput  : LREAL;
END_VAR

GVL:

{attribute 'qualified_only'}
VAR_GLOBAL
    fTest   : LREAL;              // => no error SA0103: Since the target system has a FPU, SA0103 does not apply.
    nTest   : LINT;               // => error reporting depends on the solution platform:
                                     // - SA0103 error if solution platform is set to "TwinCAT RT(x86)"
                                     // - no error SA0103 if solution platform is set to "TwinCAT (x64)"
    sTest   : STRING;             // => SA0103
    wsTest  : WSTRING;            // => SA0103
    aTest   : ARRAY[0..2] OF INT; // => SA0103
    aTest2  : ARRAY[0..2] OF INT; // => SA0103
    fbTest  : FB_Sample;          // => SA0103
    stTest  : ST_Sample;          // => SA0103
END_VAR

Programm MAIN1, aufgerufen von der Task PlcTask1:

PROGRAM MAIN1
VAR
END_VAR
GVL.fTest         := 5.0;
GVL.nTest         := 123;
GVL.sTest         := 'sample text';
GVL.wsTest        := "sample text";
GVL.aTest         := GVL.aTest2;
GVL.fbTest.fInput := 3;
GVL.stTest.nTest  := GVL.stTest.nTest + 1;

Programm MAIN2, aufgerufen von der Task PlcTask2:

PROGRAM MAIN2
VAR
    fLocal  : LREAL;
    nLocal  : LINT;
    sLocal  : STRING;
    wsLocal : WSTRING;
    aLocal  : ARRAY[0..2] OF INT;
    aLocal2 : ARRAY[0..2] OF INT;
    fLocal2 : LREAL;
    nLocal2  : INT;
END_VAR
fLocal  := GVL.fTest + 1.5;
nLocal  := GVL.nTest + 10;
sLocal  := GVL.sTest;
wsLocal := GVL.wsTest;
aLocal  := GVL.aTest;
aLocal2 := GVL.aTest2;
fLocal2 := GVL.fbTest.fInput;
nLocal2 := GVL.stTest.nTest;