Opérateur : __NEW
L'opérateur est une extension de la norme CEI 61131-3.
le __NEW L'opérateur réserve de la mémoire dynamique pour instancier des blocs fonctionnels, des types de données définis par l'utilisateur ou des tableaux de types standard. L'opérateur renvoie un pointeur typé correspondant.
Condition : Dans la boîte de dialogue des propriétés de l'application mère, sur le Options de création d'applications onglet, l'onglet Utiliser l'allocation de mémoire dynamique option est sélectionnée.
Syntaxe
<pointer name> := __NEW( <type> ( , <size> )? ); __DELETE( <pointer name> ); <type> : <function block> | <data unit type> | <standard data type>
L'opérateur génère une instance du type <type> et renvoie un pointeur vers cette instance. Ensuite, l'initialisation de l'instance est appelée. Si <type> est un type de données standard scalaire, puis l'opérande facultatif <size> est également évalué. Ensuite, l'opérateur génère un tableau de type <standard data type> et la taille <size>. Si la tentative d'allocation de mémoire échoue, alors __NEW renvoie la valeur 0.
Utilisez l'opérateur dans l'affectation ":=" ; sinon, un message d'erreur s'affiche.
Un bloc fonctionnel ou un type de données défini par l'utilisateur dont l'instance est créée dynamiquement avec __NEW utilise une zone mémoire fixe. Ici, il est nécessaire que vous marquiez les objets avec le pragma {attribute 'enable_dynamic_creation'}. Il n'est pas nécessaire pour les blocs fonctionnels faisant partie d'une bibliothèque.
Astuce
Si vous modifiez la disposition des données du bloc fonctionnel en mode en ligne, vous ne pouvez pas exécuter une connexion avec une modification en ligne par la suite. En effet, la zone mémoire de l'instance du bloc fonction a été invalidée. Vous modifiez la disposition des données lorsque vous ajoutez de nouvelles variables au bloc fonction, supprimez des variables existantes ou modifiez les types de données des variables.
Déployer (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_IFBloc fonction
{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_IFType de données défini par l'utilisateur (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_IFTableau (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
Nous déconseillons l'exécution simultanée de deux tâches qui appellent toutes deux le __NEW opérateur. Vous utilisez soit un sémaphore (SysSemEnter) ou une technique comparable pour empêcher un appel simultané de __NEW. Cependant, cela se traduit par une gigue plus élevée lorsque __NEW est largement appliqué.
Nous vous recommandons d'appeler __NEW opérateurs dans une seule tâche.