Operatore: __NEW
L'operatore è un'estensione della norma IEC 61131-3.
Il __NEW l'operatore riserva la memoria dinamica per creare un'istanza di blocchi funzione, tipi di dati definiti dall'utente o matrici di tipi standard. L'operatore restituisce un puntatore digitato corrispondente.
Requisito: nella finestra di dialogo delle proprietà dell'applicazione padre, su Opzioni di creazione dell'applicazione scheda, il Utilizzare l'allocazione dinamica della memoria l'opzione è selezionata.
Sintassi
<pointer name> := __NEW( <type> ( , <size> )? ); __DELETE( <pointer name> ); <type> : <function block> | <data unit type> | <standard data type>
L'operatore genera un'istanza del tipo <type> e restituisce un puntatore a questa istanza. Quindi viene chiamata l'inizializzazione dell'istanza. Se <type> è un tipo di dati scalare standard, quindi l'operando facoltativo <size> viene anche valutato. Quindi l'operatore genera un array di tipo <standard data type> e dimensioni <size>. Se il tentativo di allocare memoria fallisce, allora __NEW restituisce il valore 0.
Utilizzare l'operatore all'interno dell'assegnazione ":="; in caso contrario viene visualizzato un messaggio di errore.
Un blocco funzione o un tipo di dati definito dall'utente la cui istanza viene creata dinamicamente con __NEW utilizza un'area di memoria fissa. Qui è necessario contrassegnare gli oggetti con il pragma {attribute 'enable_dynamic_creation'}. Non è richiesto per i blocchi funzione che fanno parte di una libreria.
Suggerimento
Se si modifica il layout dei dati del blocco funzione in modalità online, non è possibile eseguire successivamente un login con una modifica online. Ciò è dovuto al fatto che l'area di memoria dell'istanza del blocco funzione è stata invalidata. Si modifica il layout dei dati quando si aggiungono nuove variabili al blocco funzione, si eliminano le variabili esistenti o si modificano i tipi di dati delle variabili.
Vettore (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_IFBlocco funzione
{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_IFTipo di dati definito dall'utente (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_IFMatrice (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_IFImportante
Si sconsiglia l'esecuzione simultanea di due attività che entrambe chiamano il __NEW operatore. Usi o un semaforo (SysSemEnter) o una tecnica comparabile per impedire una chiamata simultanea di __NEW. Tuttavia, ciò si traduce in un jitter più elevato quando __NEW è ampiamente applicato.
Ti consigliamo di chiamare __NEW operatori in un solo compito.