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.libraryundSysExcept.libraryals Platzhalterbibliotheken. -
SysTypes2_Itfs.librarymit „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.