mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-24 04:32:52 +01:00
Merge #277
277: TimerQueue.dequeue: don't set SYST reload to 0 r=korken89 a=mpasternacki ARM Architecture Reference Manual says: "Setting SYST_RVR to zero has the effect of disabling the SysTick counter independently of the counter enable bit." If Monotonic's ratio is less than one, the timeout calculations can compute zero if next task is scheduled after current instant, but before next timer tick. This results in disabling SYST and freezing the timer queue. The division by ratio's denominator rounds downward and the dequeue condition is `if instant < now`. If ratio is small enough, this results in unnecessary interrupts: Let's say `instant - now` is 99 and ratio is 1/25. Then, `dur` will equal 3 and the next tick will happen at `now + 75`. In the next interrupt, `instant > now` and additional tick needs to be scheduled (which doesn't happen, because now `instant - now` is less than 25, so reload will be set to 0 and timer queue will stop). Adding one to computed duration will prevent both freezing and additional interrupts. When ratio is 1 or close, timer queue code overhead will prevent this from happening. I am working with a chip where CPU is clocked at 600MHz and SysTick is 100kHz and the freeze happens quite often. Co-authored-by: Maciej Pasternacki <maciej@3ofcoins.net>
This commit is contained in:
commit
82efffd706
1 changed files with 7 additions and 0 deletions
|
@ -68,6 +68,13 @@ where
|
||||||
.map(|x| x / ratio.denominator)
|
.map(|x| x / ratio.denominator)
|
||||||
}) {
|
}) {
|
||||||
None => MAX,
|
None => MAX,
|
||||||
|
|
||||||
|
// ARM Architecture Reference Manual says:
|
||||||
|
// "Setting SYST_RVR to zero has the effect of
|
||||||
|
// disabling the SysTick counter independently
|
||||||
|
// of the counter enable bit."
|
||||||
|
Some(0) => 1,
|
||||||
|
|
||||||
Some(x) => cmp::min(MAX, x),
|
Some(x) => cmp::min(MAX, x),
|
||||||
};
|
};
|
||||||
mem::transmute::<_, SYST>(()).set_reload(dur);
|
mem::transmute::<_, SYST>(()).set_reload(dur);
|
||||||
|
|
Loading…
Reference in a new issue