📜 ⬆️ ⬇️

On the issue of timers in RTOS (Conclusions)

image In brief, I will describe the content of the article :

There is a cyclic hardware counter, which, for example, counts seconds, and there is an interrupt due to its overflow. Extend the range of notation programmatically, incrementing the value of another cell in the interrupt. Thus, we are able to count the minutes. The essence of the problem is that in the general case it is impossible to simultaneously read the value of minutes and seconds, and during sequential reading an interruption and an increase in minutes may occur. Consequences: a journey back in time.

Example: 1 minute 20 seconds, read minutes. An interrupt occurs that lasts 50 seconds, the minutes are incremented -
2 minutes, 10 seconds, readings seconds.

We get time: 1:10 (1 min 10 sec), we could get this time only after traveling back in time, because we started measurements at 1:20, and got the result at 2:10. It should be noted that we will not be able to run forward with such a reading sequence (as the author claimed), because with reading we are behind the discharge of minutes, and this is always more than all seconds that fit in the corresponding discharge (lagging for a minute is minus a minute, and seconds only with a plus and no more than a minute).
')
If we read seconds, then minutes, then we can, on the contrary, give future time around one minute, and in the past, flights are canceled.

So, the criterion was described by the thought that the read time should be between the time the function was started and its end, which seemed logical, and on the basis of this all the arguments were constructed. At the same time, we courageously fought for the read seconds to match the minutes, which is not very easy, because in general we should assume that the meter counts very quickly, or the system is heavily loaded, therefore, during the execution of our function, many and many interruptions occur during which “minutes” change (we call it conditionally, for clarity). We cannot prohibit interrupts, since the minutes will no longer be counted (the minutes are programmatically incremented by minutes), and this is already a complete Armageddon.

How can you be sure that the known seconds correspond to the desired minute? Just hoping that we did everything very quickly and we were lucky, so there was no interruption between reading minutes, seconds, and then again minutes (test reading), or it was lightning-fast, and the minute did not expire. This is easily verified: a check reading of minutes should give the same value. The only thing is that in the worst case, we will endlessly try to get such a confluence of circumstances, and we will never get the result.

The output was coined in the original article like this: we only check once, and if the minute has changed, then we assume that it has just changed, which means there are still as many as 59 seconds to quickly read the minutes and seconds again, and voila - we in ladies. In practice, such a technique will work quite well, but in theory this is not a solution at all, because no 59 seconds are guaranteed for us (we can immediately get an interrupt for all 70), and we have again read the seconds and minutes general case, is broken by the same atrocity. But statistically, yes, we sharply reduced the probability of incorrect data using such heuristics.

In the author's comments sent to the true path, and it is very simple. We are too abstract from what is actually needed and we are trying to solve a certain spherical synchronization problem, which, in fact, does not require a solution.

Let me explain: we run the function to find out “what time it is”, if we are answered quickly, then we may be interested in seconds, if instantly we can use milliseconds for practical purposes, etc. If we are answered within an hour, then it does not matter at all how many milliseconds there are, “now” we cannot measure more precisely than an hour, but as was indicated above - time travel, however, is not permissible.

Therefore, a very simple algorithm suggests itself:

Read the minutes, read the seconds, check the read minutes, if everything is normal, then return the result. If the minutes have changed, then the current time is n minutes and 00 seconds or later, but not more than 59 seconds, and most likely it is a matter of seconds, because, like in the author’s heuristics, we should be in the neighborhood of one minute to another transition. Our task is to return this result as soon as possible (n minutes 00 seconds), any attempt at a new synchronization, reading or checking may end (and in the worst case - must end) with an interruption of work, and regardless of the methods of obtaining, we immediately move away from the current time and worsen any next value, no matter how accurate, with respect to the synchronization moment, it is not.

Thus, the return of 00 seconds will be even more accurate than the actual read value (we do not spend time reading seconds and further checks), because we want to get the time "now", not the time when we managed to synchronize. In fact, any time taken at random suits us, the main thing is that it was in the time interval of the function, and the function itself worked as little as possible. This is exactly the heuristic that allows you to make a very accurate assumption, and it exactly falls into the interval of the function.

Criticism: time can be used differently, if we try to measure the interval, having received “now” twice, then such an algorithm will give the smallest error, if we wait for an “alarm clock” - similarly. If we just want to start at some point right after which there will be, for example, an entry in the log file, which should correspond exactly to the real time recorded there, then it may make sense to synchronize before losing the pulse or come up with something more sophisticated , but as for me - this is a completely different task.

And, of course, we ruined the statistical distribution of seconds, making 00 more likely, so something like Randomize can have side effects.

Source: https://habr.com/ru/post/274805/


All Articles