FB_BA_DynamicArray

FB_BA_DynamicArray 1:

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.

FB_BA_DynamicArray 2:

Der intern verwendete Speicher wird aus dem Routerspeicherpool alloziert und zur Laufzeit via _NEW erzeugt und via _DELETE freigegeben.
Bei jeder Anpassung (d.h. Erweiterung oder Verkleinerung) des internen Speichers sind auch die Pointer auf den veralteten / angepassten Speicher ungültig!

FB_BA_DynamicArray 3:

Der Datentyp der Einträge spielt für das dynamische Array keine Rolle!
Der Anwender muss in jedem Fall dafür sorgen, dass beim Umgang mit enthaltenen Einträgen stets der Datentyp korrekt von der Applikation beachtet wird.
Des Weiteren müssen alle Daten, die in das Array hinzugefügt werden eine einheitlich definierte Größe haben!

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.

FB_BA_DynamicArray 4:

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

AddEntry

Lokal

Erstellt einen neuen Datensatz am Ende des Arrays und kopiert den Inhalt des angegebenen Eintrags in den internen Speicher

FindEntry

Lokal

Ermittelt die Position des angegebenen Eintrags im Array, indem dessen Inhalt mit den Datensätzen des Arrays vergleichen wird.

GetEntry

Lokal

Kopiert den Inhalt des Datensatzes an einer bestimmten Position auf den angegebenen Speicherbereich.

GetEntryEx

Lokal

Ermittelt einen Pointer auf den internen Speicher des angeforderten Datensatzes.

RemoveEntry

Lokal

Entfernt den Datensatz an der angegebenen Index-Position aus dem Array.

RemoveEntryEx

Lokal

Ermittelt die Position des angegebenen Eintrags und löscht diesen aus dem Array.

Reset

Lokal

Setzt den kompletten Inhalt des Arrays zurück.

SetEntry

Lokal

Ersetzt den existierenden Datensatz durch einen neuen, indem der interne Speicherbereich des existierenden Datensatzes mit dem Wert des neuen Eintrags überschrieben wird.

AddEntryPtr

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.

FindEntryPtr

Lokal

Ermittelt die Position eines Eintrags im Array, indem dessen Adresse mit den im Array gespeicherten Adressen verglichen wird.

GetEntryExPtr

Lokal

Gibt einen Pointer auf die Speicheradresse des angeforderten Eintrags aus.

RemoveEntryExPtr

Lokal

Ermittelt die Position des angegebenen Eintrags und löscht diesen aus dem Array.

SetEntryPtr

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

uiEntrySize

Zu erwartende Größe von Einträgen welche im Array gespeichert werden

LastIndex

DINT

Get

Lokal

-

Index-Position des letzten Eintrags.
Ist -1 wenn keine Einträge vorhanden sind

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