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_IF
Bloc 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_IF
Type 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_IF
Tableau (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
Important
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.