You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The original implementation had two problems:
- It was not re-entrant: It cleared COUNTFLAG at startup and then used
that flag to detect if an overflow happened while reading the timer
values. If then another ISR would happen between the overflow (flag
set) and reading the flag, and that ISR would call micros(), the flag
would be cleared again and the original micros() call would return
the wrong value.
- It was sometimes wrong when called with interrupts disabled (e.g.
inside an ISR): When COUNTFLAG was set, the code would call
HAL_GetTick() again, assuming that it would return an updated value.
However, when interrupts are disabled, the systick overflow interrupt
cannot run and HAL_GetTick() just returns the same value again, and
micros() returns the wrong value.
This commit fixes both problems:
- Rather than relying on HAL_GetTick() to return an updated value, just
increment the value returned. This works with interrupts disabled,
and even requires interrupts to be disabled to make sure that the
pending bit is set (rather than running the systick ISR immediately)
and also guarantee that the original value is from *before* the
overflow (if any).
- Becauses all interrupts are now disabled, another ISR can no longer
interrupt this code and interfere with the result.
Rather than disabling interrupts entirely, it could have been enough to
just disable the systick irq. However, disabling the systick irq also
prevents its pending bit from being set, so this would just cause
overflows to be missed entirely (maybe it could be made to work by
detecting overflows based on the systick value and then manually
*setting* PENDSTSET to have them processed later, but that might be
fragile).
0 commit comments