Operator ‘__NEW’ΒΆ

The operator is an extension of the IEC 61131-3 standard.

The __NEW operator reserves dynamic memory to instantiate function blocks, user-defined data types, or arrays of standard types. The operator returns a matching typed pointer.

Requirement: In the properties dialog of the parent application, on the Application Build Options tab, the Use dynamic memory allocation option is selected.

Syntax

<pointer name> := __NEW( <type> ( , <size> )? );
__DELETE( <pointer name> );

<type> : <function block> | <data unit type> | <standard data type>

The operator generates an instance of the type <type> and returns a pointer to this instance. Then the initialization of the instance is called. If <type> is a scalar standard data type, then the optional operand <size> is also evaluated. Then the operator generates an array of type <standard data type> and size <size>. If the attempt to allocate memory fails, then __NEW returns the value 0.

Use the operator within the assignment “:=”. Otherwise an error message is displayed.

A function block or a user-defined data type whose instance is created dynamically with __NEW uses a fixed memory area. Here it is required that you mark the objects with the pragma {attribute 'enable_dynamic_creation'}. It is not required for function blocks that are part of a library.

Note

If you change the data layout of the function block in online mode, then you cannot execute a login with an online change afterwards. This is because the memory area of the function block instance has been invalidated. You change the data layout when you add new variables to the function block, delete existing variables, or change the data types of variables.

Example

Array (DWORD):

PROGRAM PLC_PRG
VAR
        pdwScalar : POINTER TO DWORD; //Typed pointer
        xInit : BOOL := TRUE;
        xDelete : BOOL;
END_VAR

IF (xInit) THEN
        pdwScalar := __NEW(DWORD, 16); // Allocates memory (16 dwords) and assigns them to pointer pdwScalar
END_IF
IF (xDelete) THEN
        __DELETE(pdwScalar); // Frees memory of pointer
END_IF

Function block:

{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;      // Typed pointer
        xInit : BOOL := TRUE;
        xDelete : BOOL;
        iResult : INT;
END_VAR

IF (xInit) THEN
        pComputeGamma := __NEW(FBComputeGamma); // Allocates memory
        xInit := FALSE;
END_IF
pComputeGamma^.iAlpha := (pComputeGamma^.iAlpha + 1)MOD 100; // Sets first input of pComputeGamma
pComputeGamma^.iBeta := 10; // Sets second input of pComputeGamma
pComputeGamma^(); // Calls the FB pComputeGamma is pointing to
iResult := pComputeGamma^.iGamma; // Reads output of pComputeGamma
IF (xDelete) THEN
    __DELETE(pComputeGamma); // Frees memory
END_IF

User-defined data type (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; // Typed pointer
        xInit : BOOL := TRUE;
        xDelete : BOOL;
END_VAR

IF (xInit) THEN
    pABCData := __NEW(ABCDATA); // Allocates memory
    xInit := FALSE;
END_IF
IF (xDelete) THEN
    __DELETE(pABCData); // Frees memory
END_IF

Array (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); // Allocates 16 bytes for pbDataAlpha
        pbDataBeta := __NEW(BYTE);  // Allocates memory for pbDataBeta
        xInit := FALSE;

        FOR usiCnt := 0 TO 15 DO
                pbDataAlpha[usiCnt] := usiCnt; // Writes to new array
        END_FOR
        pbDataBeta^:= 16#FF; // Writes to new data
END_IF

bTestC := pbDataAlpha[12];  // Reads new array by index access

IF (xDelete) THEN // Frees memory
        __DELETE(pbDataAlpha);
        __DELETE(pbDataBeta);
END_IF

Hint

We do not recommend the simultaneous execution of two tasks that both call the __NEW operator. You use either a semaphore (SysSemEnter) or a comparable technique to prevent a concurrent call of __NEW. However, this results in a higher jitter when __NEW is applied extensively.

We recommend that you call __NEW operators in one task only.

See also