Range/LRange Checks (POUs CheckRangeSigned, CheckRangeUnsigned, CheckLRangeSigned, CheckLRangeUnsigned)
Functions for monitoring the range bounds of a subrange type
- CheckRangeSigned checks subrange types of the type SINT, INT, DINT.
- CheckRangeUnsigned checks subrange types of the type BYTE, WORD, DWORD, USINT, UINT, UDINT.
- CheckLRangeSigned checks subrange types of the type LINT.
- CheckLRangeUnsigned checks subrange types of the type LWORD, ULINT.
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.
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:
- value: Value to be assigned to the variables of the subrange type.
- lower: Lower range bound
- upper: Upper range bound
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.
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. |
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}