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.
Tip
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.
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_IFFunction 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_IFUser-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_IFArray (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_IFImportant
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.