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_IF
Blocco 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_IF
Tipo 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_IF
Matrice (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
Importante
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.