POU ‘CheckBounds’

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 und SysExcept.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.

Siehe auch