.

运算符‘__NEW’

.
.

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

__NEW运算符保留动态内存以实例化功能块,用户定义的数据类型或标准类型的数组。运算符返回匹配的类型化指针。

要求:在应用程序的属性对话框中,在应用程序生成信息选项中,选择使用动态分配内存选项。

.语法


<指针名称> := __NEW( <类型> ( , <大小> )? );
__DELETE( <指针名称> );

<类型> : <功能块> | <数据单位类型> | <标准数据类型>
 

该运算符生成一个<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 运算符。