Skip to main content

Operadores: __XADD

El operador multinúcleo es una extensión del estándar IEC 61131-3.

El operador se puede utilizar para implementar un contador atómico. Si una variable entera con una suma normal, por ejemplo iTest := iTest + 1; se incrementa, entonces esta operación no se realiza atómicamente. Otro acceso a la variable podría tener lugar entre la lectura y la escritura de la variable.

Si el contador se incrementa en varias tareas, el resultado del conteo puede ser menor que el número de conteos. Entonces, si dos tareas ejecutan el código anterior una vez y la variable previamente el valor 0 tenía, entonces la variable puede tener posteriormente el valor 1 tener. Esto es particularmente problemático cuando las matrices se procesan en varias tareas y se requiere un índice único para la matriz para cada procesamiento.

los operadores __XADD recibe un puntero a una variable del tipo como el primer sumando cuando se llama DINT y como segundo sumando un valor del tipo DINT . __XADD devuelve el valor antiguo del primer sumando y suma el segundo sumando al primer sumando en el mismo paso.

Por ejemplo, la llamada a la función puede verse así: diOld := __XADD(ADR(diVar), deAdd);

ejemplo 156. ejemplo

El siguiente ejemplo muestra un uso típico. Se debe llenar una matriz a partir de dos tareas, se deben usar todas las posiciones de la matriz y no se debe sobrescribir ninguna posición.

Con esta función, varias tareas pueden llenar una matriz booleana.

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