Skip to main content

POU: CheckBounds

Die 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. Die Funktion wird implizit aufgerufen, sobald der ARRAY-Variablen Werte zugewiesen werden.

Für weitere Informationen siehe: Bausteine für implizite Prüfungen verwenden und Bausteine für implizite Prüfungen verwenden

Nach dem Einfügen der Funktion erhalten Sie automatisch erzeugten Code in Deklarationsteil und Implementierungsteil. Siehe unten.

Achtung

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

Deklaration:

Sie können auch einen Haltepunkt setzen, Meldungen protokollieren oder beispielsweise bei einer Exception anhalten. Fügen Sie CmpApp.Library, SysExcept.Library und SysTypes2_Itf hinzu.

(* 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.*)
VAR
    _pApp : POINTER TO CmpApp.APPLICATION;
    _result   : SysTypes.RTS_IEC_RESULT;
END_VAR

Implementierung:

_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: Arrayzugriff außerhalb der Arraygrenzen

Beispiel 541. 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

Implementierung

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: Verletzung von Arraygrenzen

Beispiel 542. 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:

// Automatically generated code: This is an implementation suggestion.
_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
    // Required for CheckBounds
    xInit  := TRUE;
END_IF

// Set i to a value > 7 or < 0
// Generates an exception in CheckBounds, user-defined
arData[i] := 11;

Wenn Sie diese Applikation laden und starten, wird bei Verletzung der Arraygrenzen eine Exception generiert. Die Abarbeitung stoppt in CheckBounds, sodass die Art des Fehlers erkenntlich ist.