POU: CheckBounds
The task of this monitoring function is to handle bound violations appropriately. Examples of reactions to violations include setting error flags and changing the value of the array index. The check is performed only for one variable array index. An incorrect constant array index causes a compiler error. CODESYS calls the function implicitly when values are assigned to an ARRAY variable.
For more information, see: Using POUs for Implicit Checks, Using POUs for Implicit Checks
After inserting the function, you receive automatically generated code in the declaration and implementation parts. See below.
Caution
To get the feature for monitoring functions, do not edit the declaration part. However, you are permitted to add local variables.
Declaration part
// Automatisch erzeugter Code : NICHT EDITIEREN
FUNCTION CheckBounds : DINT
VAR_INPUT
index, lower, upper: DINT;
END_VARImplementation
// 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
*)When the CheckBounds function is called, it receives the following input parameters:
index: Index of the array elementlower: Lower limit of the array rangeupper: Upper limit of the array range
The return value is the index of the array element, as long as it is within a valid range. If not, then the CODESYS returns either the upper or lower limit, depending on which threshold was violated.
In the sample program below, the index falls short of the defined lower limit of the a array.
PROGRAM PLC_PRG
VAR
a: ARRAY[0..7] OF BOOL;
b: INT:=10;
END_VAR
a[b]:=TRUE;In this example, the CheckBounds function causes a to change the upper limit of the array range index to 10. The value TRUE is assigned then to the element a[7]. In this way, the function corrects array access outside of the valid array range.
Add the following libraries in the Library Manager of the application:
CmpApp.libraryandSysExcept.libraryas placeholder librariesSysTypes2_Itfs.librarywith Newest version always
Add a CheckBounds object below the application and modify the specified code as shown below.
Declaration part
FUNCTION CheckBounds : DINT
VAR_INPUT
index, lower, upper: DINT;
END_VAR
VAR
_pApp : POINTER TO CmpApp.APPLICATION;
_Result : ISystypes2.RTS_IEC_RESULT;
END_VARImplementation part
// 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_IFProgram a MAIN_PRG object below the application with the contents shown below.
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;When you load and start this application, an "exception" will be thrown when array bounds are violated. Processing stops in CheckBounds so that the type of error can be detected.