Skip to content

Commit b3574bd

Browse files
ioannisgdleach02
authored andcommitted
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 <[email protected]>
1 parent f16a403 commit b3574bd

File tree

1 file changed

+27
-7
lines changed

1 file changed

+27
-7
lines changed

drivers/timer/cortex_m_systick.c

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,34 @@ void z_clock_isr(void *arg)
120120
ARG_UNUSED(arg);
121121
u32_t dticks;
122122

123-
cycle_count += last_load;
124-
dticks = (cycle_count - announced_cycles) / CYC_PER_TICK;
125-
announced_cycles += dticks * CYC_PER_TICK;
123+
/* Update overflow_cyc and clear COUNTFLAG by invoking elapsed() */
124+
elapsed();
126125

127-
overflow_cyc = SysTick->CTRL; /* Reset overflow flag */
128-
overflow_cyc = 0U;
129-
130-
z_clock_announce(TICKLESS ? dticks : 1);
126+
/* Increment the amount of HW cycles elapsed (complete counter
127+
* cycles) and announce the progress to the kernel.
128+
*/
129+
cycle_count += overflow_cyc;
130+
overflow_cyc = 0;
131+
132+
if (TICKLESS) {
133+
/* In TICKLESS mode, the SysTick.LOAD is re-programmed
134+
* in z_clock_set_timeout(), followed by resetting of
135+
* the counter (VAL = 0).
136+
*
137+
* If a timer wrap occurs right when we re-program LOAD,
138+
* the ISR is triggered immediately after z_clock_set_timeout()
139+
* returns; in that case we shall not increment the cycle_count
140+
* because the value has been updated before LOAD re-program.
141+
*
142+
* We can assess if this is the case by inspecting COUNTFLAG.
143+
*/
144+
145+
dticks = (cycle_count - announced_cycles) / CYC_PER_TICK;
146+
announced_cycles += dticks * CYC_PER_TICK;
147+
z_clock_announce(dticks);
148+
} else {
149+
z_clock_announce(1);
150+
}
131151
z_arm_exc_exit();
132152
}
133153

0 commit comments

Comments
 (0)