drivers: systick: fix calculation of absolute cycles count in ISR

The commit fixes the update of the absolute counter of HW cycles
in the SysTick ISR for TICKLESS mode.

Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
This commit is contained in:
Ioannis Glaropoulos 2019-04-16 15:08:56 +02:00 committed by David Leach
commit b3574bdad7

View file

@ -120,14 +120,34 @@ void z_clock_isr(void *arg)
ARG_UNUSED(arg); ARG_UNUSED(arg);
u32_t dticks; u32_t dticks;
cycle_count += last_load; /* Update overflow_cyc and clear COUNTFLAG by invoking elapsed() */
dticks = (cycle_count - announced_cycles) / CYC_PER_TICK; elapsed();
announced_cycles += dticks * CYC_PER_TICK;
overflow_cyc = SysTick->CTRL; /* Reset overflow flag */ /* Increment the amount of HW cycles elapsed (complete counter
overflow_cyc = 0U; * cycles) and announce the progress to the kernel.
*/
cycle_count += overflow_cyc;
overflow_cyc = 0;
z_clock_announce(TICKLESS ? dticks : 1); if (TICKLESS) {
/* In TICKLESS mode, the SysTick.LOAD is re-programmed
* in z_clock_set_timeout(), followed by resetting of
* the counter (VAL = 0).
*
* If a timer wrap occurs right when we re-program LOAD,
* the ISR is triggered immediately after z_clock_set_timeout()
* returns; in that case we shall not increment the cycle_count
* because the value has been updated before LOAD re-program.
*
* We can assess if this is the case by inspecting COUNTFLAG.
*/
dticks = (cycle_count - announced_cycles) / CYC_PER_TICK;
announced_cycles += dticks * CYC_PER_TICK;
z_clock_announce(dticks);
} else {
z_clock_announce(1);
}
z_arm_exc_exit(); z_arm_exc_exit();
} }