timer: cortex_m: Fix the discontinuous readings of the cycle counter.

On a stm32, When we use the k_busy_wait function to wait a
delay (500us) just after an idle tickless period the delay could be
lower than the requested one. Consecutive readings of the cycle counter
made with the function k_cycle_get_32 juste after tickeless period
provides erroneous values (value jump) after some time (100 us).

To fix this issue we needs:

- Add the update of clock_accumulated_count value in the
_timer_idle_exit function.

- Treat the case in the get_elapsed_count function when the reload value
of the timer is set to a remaining value to wait until end of tick (see
_timer_idle_exit) . In this case the time elapsed until the systick
timer restart was not yet added to clock_accumulated_count. To retrieve
a correct cycle count we must therefore consider the number of cycle
since current tick period start and not only the cycle number since the
timer restart.

Fixes #6164

Signed-off-by: Holman Greenhand <greenhandholman@gmail.com>
This commit is contained in:
Holman Greenhand 2018-02-12 18:46:32 +01:00 committed by Kumar Gala
commit 400dc79326

View file

@ -681,6 +681,8 @@ void _timer_idle_exit(void)
}
}
clock_accumulated_count += default_load_value * _sys_idle_elapsed_ticks;
idle_mode = IDLE_NOT_TICKLESS;
sysTickStart();
#endif
@ -753,7 +755,26 @@ return (u32_t) get_elapsed_count();
do {
cac = clock_accumulated_count;
#ifdef CONFIG_TICKLESS_IDLE
/* When we leave a tickless period the reload value of the timer
* can be set to a remaining value to wait until end of tick.
* (see _timer_idle_exit). The remaining value is always smaller
* than default_load_value. In this case the time elapsed until
* the timer restart was not yet added to
* clock_accumulated_count. To retrieve a correct cycle count
* we must therefore consider the number of cycle since current
* tick period start and not only the cycle number since
* the timer restart.
*/
if (SysTick->LOAD < default_load_value) {
count = default_load_value;
} else {
count = SysTick->LOAD;
}
count -= SysTick->VAL;
#else
count = SysTick->LOAD - SysTick->VAL;
#endif
} while (cac != clock_accumulated_count);
return cac + count;