Skip to main content

Operatore: __XADD

L'operatore multicore è un'estensione della norma IEC 61131-3.

L'operatore può essere utilizzato per implementare un contatore atomico. Se una variabile intera viene incrementata mediante addizione ordinaria, ad esempio iTest := iTest + 1;, quindi questa operazione non viene eseguita atomicamente. Un altro accesso alla variabile potrebbe avvenire tra la lettura e la scrittura della variabile.

Se il contatore viene incrementato in più attività, il risultato del contatore può essere inferiore al numero di cicli di conteggio. Quindi, se due attività eseguono il codice sopra una volta e la variabile aveva precedentemente il valore 0, la variabile può quindi avere il valore 1. Ciò è particolarmente problematico se gli array vengono elaborati in più attività ed è richiesto un indice univoco per l'array in ogni ciclo di elaborazione.

Quando il __XADD viene chiamato, ottiene un puntatore a un tipo DINT variabile come primo ammonimento e un tipo DINT valore come seconda somma. __XADD restituisce il vecchio valore della prima somma e nello stesso passaggio aggiunge la seconda somma alla prima somma.

Ad esempio, la chiamata di funzione può essere simile a questa: diOld := __XADD(ADR(diVar), deAdd);

Esempio 156. Esempio

L'esempio seguente mostra un utilizzo tipico. Un array dovrebbe essere popolato da due attività. Nel processo, tutte le posizioni nell'array devono essere utilizzate e nessuna posizione deve essere sovrascritta.

Con questa funzione, più attività possono popolare un array booleano.

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