I have a piece of code that is used for a linear congruential psuedo-random number generator, however one of the arithmetic operations deliberately overflows. I know that this will happen, it's entirely expected behaviour, and I don't wish to have additional code that will alter this behaviour (since this existing code has already been characterised, and I don't wish to revisit this).
How would I go about disabling the diagnostic reporting of this particular arithmetic overflow however?
I was expecting that there would be an EF that could be called prior to the operation, passing in a mask of arithmetic errors, and then I could call the same EF afterwards to restore the previous mask.
Has anyone done something similar?
It becomes quite an issue that the fault light comes on, and requires someone to access the controller and acknowledge this 'fault'.
If you look at Help you'll see that %S18 directly addresses our overflow error. However, if you read towards the bottom you'll see the following:
"When the %S18 bit switches to 1, the application stops in error state if the %S78 bit has been set to 1".
%S78 is the "halt if error" occurs. You could try writing a 0 to %S78 so that if the error occurs (i.e. overflow) at %S18 then it won't make any difference because the conditional bit (%S78) is not set to 1.
%S78 doesn't stop the 'error' from being entered in the Diagnostics Logs, and flashing the fault light.
It just changes whether that results in the process HALTing also.
I do NOT have %S78 set, so the HALT isn't my problem. The diagnostic entry, and fault light behaviour is.
Yes you are correct. Perhaps I misunderstood.
I do not know of any method to prevent such an error occurring.
All the best.
There is no way to prevent the overflow error, but you can just reset the overflow bit after the execution of your function. Or prevent the execution of the function if it will lead to an overflow. The system diagnostic can be disabled if you don’t want to log this kind of errors.
So if I was doing this:
PrevSW125 := %SW125; PrevS18 := %S18; cong := 69069*cong+1234567; %SW125 := PrevSW125; %S18 := PrevS18;
What is expected to be 'different'.. it appears to still generate the system diagnostic log entry, and I suspect that it will still flash the fault light.
I really don't want to just turn off the system diagnostics, since it's incredibly useful for other situations, like genuine code errors (e.g. index array out of bounds, PIDIFF instructions with inf/sup set to the same values etc).
Unfortunately the overflow is a part of the operation. A MODulus could be performed.. but it's already using a UDINT, so there's no bigger elementary type that I could use to fit the operation and then MOD it back down (right?)
Converting to a REAL for the dynamic range will ruin the entire psuedo-random behaviour of it (NOTE: I'm not using this for cryptography, so the trivial prediction of the sequence is not an issue... but the 'random' distribution of results is necessary)