.

运算符‘_XADD’

.
.

该多核运算符是IEC 61131-3标准的扩展。

该运算符可用于实现原子计数器。如果通过普通加法来增加整数变量,例如iTest := iTest + 1;,则此操作不会自动执行。对变量的另一种访问可能发生在读写变量之间。

如果计数器在多个任务中递增,则计数器结果可能小于计数周期数。因此,如果两个任务一次执行上述代码,并且变量先前的值为0,则变量可以为1。如果要在多个任务中处理数组,并且在每个处理周期中数组都需要唯一索引,则这尤其成问题。

调用__XADD操作符时,它会获得一个指向DINT变量的指针作为第一个被加数,并获得一个DINT类型的值作为第二个被加数。__XADD返回第一个被加数的旧值,并在同一步骤中将第二个被加数添加到第一个被加数。

例如,这个函数调用如下所示:diOld := __XADD(ADR(diVar), deAdd);

.

.例如

以下示例显示了典型用法。一个数组应该由两个任务组成。在这个过程中,应该使用数组中的所有位置,不应该覆盖任何位置。

使用此功能,多个任务可以填充布尔数组。

FUNCTION WriteToNextArrayPosition : BOOL
VAR_EXTERNAL
    g_diIndex : DINT;  // 索引和数组是全局定义的,并由多个任务使用
    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);        // 返回唯一索引
WriteToNextArrayPosition := FALSE;
IF (diIndex >= 0 AND diIndex <= 1000) THEN  
    g_boolArray[diIndex] := bToWrite;         //写入唯一索引
    WriteToNextArrayPosition := TRUE;         // TRUE: 数组没有被填满
END_IF 
 

.另请参考