Range/LRange Checks (POUs CheckRangeSigned, CheckRangeUnsigned, CheckLRangeSigned, CheckLRangeUnsigned)

Functions for monitoring the range bounds of a subrange type

The purpose of these monitoring functions is to deal with range bound violations as appropriate. A response to a violation may be setting of an error flag or changing a value, for example. The functions are called implicitly when a variable is assigned a value of the subrange type.

Range/LRange Checks (POUs CheckRangeSigned, CheckRangeUnsigned, CheckLRangeSigned, CheckLRangeUnsigned) 1:

Do not change the declaration part

To maintain the functionality of the monitoring functions, the declaration part must not be modified. The only exception is to add local variables.

When the function is called, the following input parameters are transferred to it:

The return value is the assigned value itself, provided it is in the valid range. Otherwise the upper or lower bound is returned, depending on the violation of the lower bound.

The assignment i := 10*y is now implicitly replaced by i := CheckRangeSigned(10*y, -4095, 4095);

If y has the value "1000", for example, the variable i is not assigned the value "10*1000=10000", as specified in the original code, but the value of the upper range bound, i.e. "4095".

The same applies to the functions CheckRangeUnsigned, CheckLRangeSigned and CheckLRangeUnsigned.

Range/LRange Checks (POUs CheckRangeSigned, CheckRangeUnsigned, CheckLRangeSigned, CheckLRangeUnsigned) 2:

If no function for range monitoring is available, no subrange validation is performed during runtime with corresponding variables! In this case you can assign a variable of subrange type DINT/UDINT any value between -2147483648 and +2147483648 or between 0 and 4294967295. A variable of subrange type LINT/ULINT can then be assigned any value between -- 9223372036854775808 and +9223372036854775807 or between 0 and 18446744073709551615.

Range/LRange Checks (POUs CheckRangeSigned, CheckRangeUnsigned, CheckLRangeSigned, CheckLRangeUnsigned) 3:

Infinite loops

When you integrate field monitoring functions, infinite loops can occur. This is the case, for example, if the counter variable of a FOR loop is of the subrange type and the loop range leaves the defined subrange.

Example for an infinite loop:

VAR
    nVar : DINT(0..10000);
    ...
END_VAR
FOR nVar := 0 TO 10000 DO
    ...
END_FOR

The program never leaves the FOR loop, since the monitoring function CheckRangeSigned prevents that nVar is set to a value greater than 10000.

Standard implementation of the function CheckRangeSigned

If a DINT variable of a signed subrange type is assigned a value, this necessitates an automatic call of the function CheckRangeSigned. The function, which limits the assignment to the subrange specified in the variable declaration, is implemented in ST as follows by default:

Declaration part:

// Implicitly generated code : DO NOT EDIT
FUNCTION CheckRangeSigned : DINT
VAR_INPUT
    value, lower, upper : DINT;
END_VAR

Implementation:

// Implicitly generated code : Only an Implementation suggestion
{noflow}
IF (value < lower) THEN
    CheckRangeSigned := lower;
ELSEIF(value > upper) THEN
    CheckRangeSigned := upper;
ELSE
    CheckRangeSigned := value;
END_IF
{flow}