drivers: timer: SysTick: enforce proper min & max SysTick LOAD values
Similar to what we do in other timer drivers, the maximum ticks supplied in z_clock_set_timeout(..) needs to be MAX_TICKS at maximum, when K_FOREVER is supplied as argument to the function. In addition to that, the value we load onto the SysTick LOAD register shall be truncated to MAX_CYCLES. This is required to prevent loading a trash value to LOAD register, as only the lowest 24 bits may be safely written. Finally, we move the enforcement of the minimum delay to be programmed on LOAD (i.e. MIN_DELAY) at the end step of the calculation of the cycles-to-be-programmed. This prevents from misscalculating the delay, as any required adjustment is applied at the end, after the delay is rounded up to the next tick boundary. Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
This commit is contained in:
parent
3594f136d7
commit
ea2324dd2a
1 changed files with 11 additions and 6 deletions
|
@ -181,10 +181,8 @@ void z_clock_set_timeout(s32_t ticks, bool idle)
|
|||
#if defined(CONFIG_TICKLESS_KERNEL)
|
||||
u32_t delay;
|
||||
|
||||
ticks = MIN(MAX_TICKS, MAX(ticks - 1, 0));
|
||||
|
||||
/* Desired delay in the future */
|
||||
delay = (ticks == 0) ? MIN_DELAY : ticks * CYC_PER_TICK;
|
||||
ticks = (ticks == K_FOREVER) ? MAX_TICKS : ticks;
|
||||
ticks = MAX(MIN(ticks - 1, (s32_t)MAX_TICKS), 0);
|
||||
|
||||
k_spinlock_key_t key = k_spin_lock(&lock);
|
||||
|
||||
|
@ -204,13 +202,20 @@ void z_clock_set_timeout(s32_t ticks, bool idle)
|
|||
*/
|
||||
last_load = MIN_DELAY;
|
||||
} else {
|
||||
/* Desired delay in the future */
|
||||
delay = ticks * CYC_PER_TICK;
|
||||
|
||||
/* Round delay up to next tick boundary */
|
||||
delay += unannounced;
|
||||
delay =
|
||||
((delay + CYC_PER_TICK - 1) / CYC_PER_TICK) * CYC_PER_TICK;
|
||||
delay -= unannounced;
|
||||
delay = MAX(delay, MIN_DELAY);
|
||||
if (delay > MAX_CYCLES) {
|
||||
last_load = MAX_CYCLES;
|
||||
} else {
|
||||
last_load = delay;
|
||||
|
||||
}
|
||||
}
|
||||
SysTick->LOAD = last_load - 1;
|
||||
SysTick->VAL = 0; /* resets timer to last_load */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue