该运算符是IEC 61131-3标准的扩展。
__NEW运算符保留动态内存以实例化功能块,用户定义的数据类型或标准类型的数组。运算符返回匹配的类型化指针。
要求:在应用程序的属性对话框中,在应用程序生成信息选项中,选择使用动态分配内存选项。
该运算符生成一个<type>类型的实例,并返回指向该实例的指针。然后调用实例的初始化。如果<type>是标量标准数据类型,则还将评估可选操作数<size>。然后,这个操作符生成一个类型为<standard data type>的数据类型和<size>大小的数组。如果分配内存的尝试失败,则__NEW返回值0。
在分配中使用“:=”运算符。否则,将显示错误消息。
使用__NEW动态创建实例的功能块或用户定义的数据类型使用固定的存储区。在这里,要求你用{attribute 'enable_dynamic_creation'}来标记对象。对于属于库的功能块,则不需要此功能。
如果在在线模式下更改功能块的数据布局,则之后无法通过在线更改执行登录。这是因为功能块实例的存储区已无效。在将新变量添加到功能块,删除现有变量或更改变量的数据类型时,可以更改数据布局。 |
.例如
.数组(DWORD):
PROGRAM PLC_PRG
VAR
pdwScalar : POINTER TO DWORD; //输入指针变量
xInit : BOOL := TRUE;
xDelete : BOOL;
END_VAR
IF (xInit) THEN
pdwScalar := __NEW(DWORD, 16); // 分配内存(16个双字)并将其分配给指针pdwScalar
END_IF
IF (xDelete) THEN
__DELETE(pdwScalar); // 释放指针的内存
END_IF
. 功能块:
{attribute 'enable_dynamic_creation'}
FUNCTION_BLOCK FBComputeGamma
VAR_INPUT
iAlpha : INT;
iBeta : INT;
END_VAR
VAR_OUTPUT
iGamma : INT;
END_VAR
VAR
END_VAR
iGamma := iAlpha + iBeta;
PROGRAM PLC_PRG
VAR
pComputeGamma : POINTER TO FBComputeGamma; // 输入指针变量
xInit : BOOL := TRUE;
xDelete : BOOL;
iResult : INT;
END_VAR
IF (xInit) THEN
pComputeGamma := __NEW(FBComputeGamma); // 分配内存
xInit := FALSE;
END_IF
pComputeGamma^.iAlpha := (pComputeGamma^.iAlpha + 1)MOD 100; // 设置pComputeGamma的第一个输入
pComputeGamma^.iBeta := 10; // 设置pComputeGamma的第二个输入
pComputeGamma^(); // 调用FB pComputeGamma指针
iResult := pComputeGamma^.iGamma; // 读取pComputeGamma的输出
IF (xDelete) THEN
__DELETE(pComputeGamma); // 释放内存
END_IF
.用户定义的数据类型(DUT):
{attribute 'enable_dynamic_creation'}
TYPE ABCDATA :
STRUCT
iA, iB, iC, iD : INT;
END_STRUCT
END_TYPE
PROGRAM PLC_PRG
VAR
pABCData : POINTER TO ABCDATA; // 输入指针变量
xInit : BOOL := TRUE;
xDelete : BOOL;
END_VAR
IF (xInit) THEN
pABCData := __NEW(ABCDATA); // 分配内存
xInit := FALSE;
END_IF
IF (xDelete) THEN
__DELETE(pABCData); // 释放内存
END_IF
. 数组(BYTE):
PROGRAM PLC_PRG
VAR
pbDataAlpha : POINTER TO BYTE;
pbDataBeta : POINTER TO BYTE;
xInit : BOOL := TRUE;
xDelete : BOOL;
usiCnt : USINT;
bTestC: BYTE;
END_VAR
IF (xInit) THEN
pbDataAlpha := __NEW(BYTE, 16); // 为pbDataAlpha分配16个字节
pbDataBeta := __NEW(BYTE); // 为pbDataBeta分配内存
xInit := FALSE;
FOR usiCnt := 0 TO 15 DO
pbDataAlpha[usiCnt] := usiCnt; // 写入新数组
END_FOR
pbDataBeta^:= 16#FF; // 写入新的数据
END_IF
bTestC := pbDataAlpha[12]; // 通过索引访问读取新数组
IF (xDelete) THEN // 释放内存
__DELETE(pbDataAlpha);
__DELETE(pbDataBeta);
END_IF
我们不建议同时执行两个都调用__NEW操作符的任务。你可以使用信号量(SysSemEnter)或类似技术来防止并发调用 __NEW。但是,广泛使用__NEW 时,这会导致较高的抖动。 我们建议你仅在一项任务中调用__NEW 运算符。 |