FB_BA_DynamicArray

Der Funktionsbaustein erzeugt und löscht Speicherbereiche dynamisch, damit zur Laufzeit Einträge hinzugefügt und entfernt werden können.
Sobald die maximale Kapazität des Arrays erreicht ist, wird der interne Speicherbereich automatisch erweitert. Ist die Kapazität mehr als ausreichend, wird der interne Speicherbereich verkleinert.
![]() | Der intern verwendete Speicher wird aus dem Routerspeicherpool alloziert und zur Laufzeit via _NEW erzeugt und via _DELETE freigegeben. |
![]() | Der Datentyp der Einträge spielt für das dynamische Array keine Rolle! |
Es empfiehlt sich das dynamische Array vor allem dann einzusetzen, wenn die zu erwartende Speicherausnutzung relativ gut abgeschätzt werden kann. Routerspeicher steht (vor allem bei kleinen Steuerungen) nur begrenzt zur Verfügung und ist so effizient wie möglich zu verwenden! Gegebenenfalls muss die im Zielsystem verfügbare Menge an Routerspeicher zusätzlich angepasst werden.
VAR_OUTPUT
bReady : BOOL;
discount : DINT;
bReady: Zustand des allozierten Speichers. (TRUE wenn mindestens ein Eintrag im Array enthalten und somit bereits Speicher erzeugt ist)
diCount: Aktuelle Anzahl an enthaltenen Einträgen.
VAR
Interne Variablen, die bei der Deklaration initialisiert werden müssen.
uiEntrySize : UINT;
uiMinExpCount: : UINT;
uiEntrySize: Zu erwartende Größe von Einträgen. Wird verwendet um internen Speicher zu allozieren und Speicherbereiche von aufgenommenen Einträgen zu verwalten.
uiMinExpCount: Zu erweiternde Größe des internen Speichers (angegeben in [Anzahl an Einträgen]) bei Erreichen der maximalen Kapazität.
Weiterführende Informationen, siehe Beispiele für Initialisierung bei Variablen-Deklaration.
Anwendung
Es sind zwei typische Anwendungsfälle vorstellbar:
Fall 1) Array enthält Datensätze
In diesem Fall enthält das Array Datensätze (generische Typen wie z.B. BOOL, INT, STRING oder auch Strukturen), indem interner Speicher entsprechend der Größe des angewendeten Typs reserviert wird.
Fall 2) Array enthält Pointer
In diesem Fall enthält das Array Pointer auf extern deklarierte Daten und es wird nur Speicher entsprechend der Größe von Speicheradressen reserviert.
![]() | Instanzen des dynamischen Arrays werden nicht zyklisch aufgerufen. Es ist ausreichend die hier beschriebenen Verwaltungsfunktionen und Eigenschaften anzuwenden. |
Beispiele
Beispiel 1:
In einem Array werden Datensäte des Datentyps ST_DATA gespeichert.
Ein Zugriff auf die entsprechenden Datensätze geschieht mittels Pointer auf den internen Speicher des Arrays oder mittels einer Kopie eines Datensatzes.
VAR
fbArray : FB_DynamicArray := (uiEntrySize:=SIZEOF(ST_Data), uiMinExpCount:=5);
stMyDataTmp : ST_Data;
ptrMyDataTmp : POINTER TO ST_Data;
diIndexTmp : DINT;
END_VAR
// 1) Save data in array and remove them with the help of index position:
IF (fbArray.AddEntry(ADR(stMyDataTmp), diResultIndex=>diIndexTmp)) THEN
fbArray.RemoveEntry(diIndexTmp);
END_IF
// 2) List all data sets consecutively:
FOR diIndexTmp = 0 TO fbArray.LastIndex DO
IF (fbArray.GetEntryEx(diIndexTmp, pMemoryPtr=>ptrMyDataTemp)) THEN
ptrMyDataTmp^.diValue := (diIndexTmp+1);
END_IF
END_FOR
// 3) Get a copy of the first data set:
If (fbArray.GetEntry(0, ADR(stMyDataTmp))) THEN
// Edit and update data set:
stMyDataTmp.diValue := 99;
fbArray.SetEntry(0, ADR(stMyDataTmp));
END_IF
Beispiel 2:
In einem Array werden die Adressen von extern deklarierten Instanzen des Funktionsbausteins FB_Object gespeichert.
VAR
fbArray : FB_DynamicArray := (uiEntrySize:=SIZEOF(POINTER TO FB_Object), uiMinExpCount:=5);
fbMyObject1 : FB_Object;
fbMyObject2 : FB_Object;
fbObjectTmp : POINTER TO FB_Object;
diIndexTmp : DINT;
END_VAR
// 1) Add object to array and remove it with the help of index position:
If (fbArray.AddEntryPtr(ADR(fbMyObject1), diResultIndex=>diIndexTmp)) THEN
fbArray.RemoveEntry(diIndexTmp);
END_IF
// 2) Add object to array and remove subsequently with the use of the pointer:
fbArray.AddEntryPtr(ADR(fbMyObject1));
fbArray.RemoveEntryExPtr(ADR(fbMyObject1));
// 3) Determine the index position of an object within an array:
IF (fbArray.FindEntryPtr(ADR(fbMyObject1), diResultIndex=>diIndexTemp)) THEN
// Replace entry on position "fbMyObject1" with "fbMyObject2":
fbArray.SetEntryPtr(diIndexTmp, ADR(fbMyObject2));
ELSE
// Error handling
…
END_IF
// 4) Determine first object:
IF (fbArray.GetEntry(0,ADR(fbObjTemp))) THEN
// …
END_IF
// 5) Remove content of the array if it has more than 10 entries:
IF(fbArray.diCount > 10) THEN
fb_Array.Reset();
END_IF
Fehlermeldungen
Folgende Fehlermeldungen können zur Laufzeit im TwinCAT Ausgabefenster ausgegeben werden:
[EDB4] Entry-size of array not defined!
Die zu erwartende Größe von Einträgen wurde bei der Deklaration des Arrays nicht initialisiert.
[EDB7] Expansion-count of entries not defined!
Die zu erweiternde Größe des internen Speichers wurde bei der Deklaration des Arrays nicht initialisiert.
Methods of FB_BA_DynamicArray
Name | Definitionsort | Beschreibung |
---|---|---|
Lokal | Erstellt einen neuen Datensatz am Ende des Arrays und kopiert den Inhalt des angegebenen Eintrags in den internen Speicher | |
Lokal | Ermittelt die Position des angegebenen Eintrags im Array, indem dessen Inhalt mit den Datensätzen des Arrays vergleichen wird. | |
Lokal | Kopiert den Inhalt des Datensatzes an einer bestimmten Position auf den angegebenen Speicherbereich. | |
Lokal | Ermittelt einen Pointer auf den internen Speicher des angeforderten Datensatzes. | |
Lokal | Entfernt den Datensatz an der angegebenen Index-Position aus dem Array. | |
Lokal | Ermittelt die Position des angegebenen Eintrags und löscht diesen aus dem Array. | |
Lokal | Setzt den kompletten Inhalt des Arrays zurück. | |
Lokal | Ersetzt den existierenden Datensatz durch einen neuen, indem der interne Speicherbereich des existierenden Datensatzes mit dem Wert des neuen Eintrags überschrieben wird. | |
Lokal | Erstellt einen neuen Eintrag am Ende des Arrays und kopiert dessen Speicheradresse (d.h. die Adresse auf die der Pointer pEntry zeigt) in den internen Speicher. | |
Lokal | Ermittelt die Position eines Eintrags im Array, indem dessen Adresse mit den im Array gespeicherten Adressen verglichen wird. | |
Lokal | Gibt einen Pointer auf die Speicheradresse des angeforderten Eintrags aus. | |
Lokal | Ermittelt die Position des angegebenen Eintrags und löscht diesen aus dem Array. | |
Lokal | Ersetzt einen existierenden Eintrag durch einen Neuen. |
Properties of FB_BA_DynamicArray
Name | Typ | Zugriff | Definitionsort | Initialwert | Beschreibung |
---|---|---|---|---|---|
CurCapacity | DINT | Get | Lokal | - | Aktuelle Kapazität des Arrays (Anzahl an Einträgen). Entspricht der maximalen Anzahl an Einträgen die vom internen Speicher aufgenommen werden kann. |
EntrySize | DINT | Get | Lokal | Zu erwartende Größe von Einträgen welche im Array gespeichert werden | |
LastIndex | DINT | Get | Lokal | - | Index-Position des letzten Eintrags. |
UsedMemory | DINT | Get | Lokal | - | Größe des verbrauchten internen Speichers [Byte]. |
Voraussetzungen
Entwicklungsumgebung | Erforderliche Bibliothek | Erforderliche Function |
---|---|---|
TwinCAT3.1 4022.16 | Tc3_BA_Common ab V1.0.4.3 | TF8040 | TwinCAT Building Automation ab V1.0.5.0 |