Skip to main content
Suche

Operator: __XADD

Der Multicore-Operator ist eine Erweiterung der Norm IEC 61131-3.

Der Operator kann zur Realisierung eines atomaren Zählers verwendet werden. Wenn eine Integer-Variable mit einer normalen Addition, zum Beispiel iTest := iTest + 1; hochgezählt wird, dann wird diese Operation nicht atomar ausgeführt. Zwischen dem Lesen und dem Schreiben der Variable könnte ein weiterer Zugriff auf die Variable erfolgen.

Wenn der Zähler in mehreren Tasks hochgezählt wird, kann das Ergebnis der Zählung kleiner sein als die Anzahl der Zählvorgänge. Wenn also zwei Tasks den obigen Code einmal ausführen und die Variable zuvor den Wert 0 hatte, dann kann die Variable anschließend den Wert 1 haben. Das ist insbesondere dann problematisch, wenn Arrays in mehreren Tasks bearbeitet werden und in jeder Bearbeitung ein eindeutiger Index für das Array benötigt wird.

Die Operator __XADD erhält beim Aufruf als ersten Summanden einen Pointer auf eine Variable vom Typ DINT und als zweiten Summanden einen Wert vom Typ DINT . __XADD liefert den alten Wert des ersten Summanden zurück und addiert im selben Schritt den zweiten Summanden auf den ersten Summanden.

Beispielsweise kann der Aufruf der Funktion wie folgt aussehen: diOld := __XADD(ADR(diVar), deAdd);

Beispiel 156. Beispiel

Das folgende Beispiel zeigt eine typische Verwendung. Ein Array soll aus zwei Tasks gefüllt werden, dabei sollen alle Positionen im Array verwendet werden und keine Position überschrieben werden.

Mit dieser Funktion können mehrere Tasks ein boolsches Array füllen.

FUNCTION WriteToNextArrayPosition : BOOL
VAR_EXTERNAL
        g_diIndex : DINT;  // Index and array are globally defined and used by multiple tasks
        g_boolArray : ARRAY [0..1000] OF BOOL;
END_VAR
VAR_INPUT
        bToWrite : BOOL;
END_VAR
VAR
        diIndex : DWORD;
END_VAR

diIndex := __XADD(ADR(g_diIndex), 1);       // Returns a unique index
WriteToNextArrayPosition := FALSE;
IF (diIndex >= 0 AND diIndex <= 1000) THEN
        g_boolArray[diIndex] := bToWrite;         //Writes to unique index
        WriteToNextArrayPosition := TRUE;         // TRUE: Array was not full yet
END_IF