Skip to main content

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.

Esempio 150. Esempio

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.