Funktionen zur Überprüfung der Feldgrenzen: CheckBounds
Aufgabe dieser Überwachungsfunktion ist eine angemessene Behandlung von Verletzungen
von Feldgrenzen. Eine Reaktion auf eine Verletzung kann beispielsweise das Setzen
eines Error-Flags oder das Verändern des Arrayindex sein. Die Prüfung erfolgt nur
bei einem variablen Feldindex. Ein fehlerhafter konstanter Arrayindex führt zu einem
Compilerfehler. CODESYS ruft die Funktion implizit auf sobald einer Variablen vom Typ ARRAY
Werte zugewiesen werden.
Nach dem Einfügen der Funktion erhalten Sie automatisch erzeugten Code in Deklarationsteil und Implementierungsteil. Siehe unten.




VORSICHT

Um die Funktionalität der Überwachungsfunktionen zu erhalten, dürfen Sie den Deklarationsteil nicht verändern. Als einzige Ausnahme dürfen Sie lokale Variablen hinzufügen.
Deklarationsteil
// Automatisch erzeugter Code : NICHT EDITIEREN FUNCTION CheckBounds : DINT VAR_INPUT index, lower, upper: DINT; END_VAR
Implementierung
// Automatisch erzeugter Code: Es handelt sich hierbei um einen Implementierungsvorschlag. IF index < lower THEN CheckBounds := lower; ELSIF index > upper THEN CheckBounds := upper; ELSE CheckBounds := index; END_IF (* It is also possible to set a breakpoint, log messages or e.g. to halt on an exception: Add CmpApp.library, SysExcept.library and SysTypes2_Itf as newest. Declaration: VAR _pApp : POINTER TO CmpApp.APPLICATION; _result : SysTypes.RTS_IEC_RESULT; END_VAR Implementation: _pApp := AppGetCurrent(pResult:=_result); IF index < lower THEN CheckBounds := lower; IF _pApp <> 0 THEN AppGenerateException(pApp:=_pApp, ulException:=RtsExceptions.RTSEXCPT_ARRAYBOUNDS); END_IF ELSIF index > upper THEN CheckBounds := upper; IF _pApp <> 0 THEN AppGenerateException(pApp:=_pApp, ulException:=RtsExceptions.RTSEXCPT_ARRAYBOUNDS); END_IF ELSE CheckBounds := index; END_IF *)
Beim Aufruf erhält die Funktion „CheckBounds“ folgende Eingangsparameter:
-
index
: Index des Arrayelements -
lower
: Untergrenze des Arraybereichs -
upper
: Obergrenze des Arraybereichs
Rückgabewert ist der Index des Arrayelements, sofern sich dieser im gültigen Bereich befindet. Ansonsten gibt CODESYS je nach Verletzung des Grenzbereichs die Ober- oder Untergrenze zurück.
Beispiel: Korrektur des Zugriffs auf ein Array außerhalb der definierten Arraygrenzen
Im unten stehenden Beispielprogramm unterschreitet der Index die definierte Untergrenze
des Arrays a
.
PROGRAM PLC_PRG VAR a: ARRAY[0..7] OF BOOL; b: INT:=10; END_VAR a[b]:=TRUE;
Die Funktion CheckBounds
bewirkt in diesem Beispiel, dass der Index 10
in die Obergrenze des Arraybereichs von a
abgeändert wird. Damit wird der Wert TRUE
dem Element a[7]
zugewiesen. Auf diese Weise korrigiert die Funktion Arrayzugriffe außerhalb des gültigen
Arraybereichs.
Beispiel: Ausgabe einer Ausnahme bei Verletzung von Arraygrenzen
Fügen Sie im Bibliotheksverwalter der Applikation folgende Bibliotheken ein:
-
CmpApp.library
undSysExcept.library
als Platzhalterbibliotheken. -
SysTypes2_Itfs.library
mit „Immer neueste Version“
Fügen Sie ein Objekt „CheckBounds“ unter der Applikation ein und ändern Sie den vorgegebenen Code wie folgt:
Deklarationsteil
FUNCTION CheckBounds : DINT VAR_INPUT index, lower, upper: DINT; END_VAR VAR _pApp : POINTER TO CmpApp.APPLICATION; _Result : ISystypes2.RTS_IEC_RESULT; END_VAR
Implementierungsteil
// Automatisch erzeugter Code: Es handelt sich hierbei um einen Implementierungsvorschlag. _pApp := AppGetCurrent(pResult := _Result); IF index < lower THEN CheckBounds := lower; IF _pApp <> 0 THEN AppGenerateException(pApp := _pApp, ulException := RtsExceptions.RTSEXCPT_ARRAYBOUNDS); END_IF ELSIF index > upper THEN CheckBounds := upper; IF _pApp <> 0 THEN AppGenerateException(pApp:=_pApp, ulException:=RtsExceptions.RTSEXCPT_ARRAYBOUNDS); END_IF ELSE CheckBounds := index; END_IF
Programmieren Sie ein Objekt „ MAIN_PRG“ mit dem unten gezeigten Inhalt unter der Applikation.
PROGRAM MAIN_PRG VAR xInit : BOOL; arData : ARRAY[0..7] OF BYTE; i : INT; dwAdr : DWORD; END_VAR IF NOT xInit THEN // Erforderlich für CheckBounds xInit := TRUE; END_IF // Setze i auf einen Wert > 7 oder < 0 // Generiert eine Exception in CheckBounds, Benutzerdefiniert arData[i] := 11;
Wenn Sie diese Applikation laden und starten, wird bei Verletzung der Arraygrenzen eine "Exception" generiert. Die Abarbeitung stoppt in „CheckBounds“, so dass die Art des Fehlers erkenntlich ist.