xTimerStartFromISR() and xTimerResetFromISR() with tickless idle

When used with tickless idle, xTimerStartFromISR() and xTimerResetFromISR() might not behave as expected. For reference, these functions capture the current tick count (in the ISR) for use as the start time of the timer. If the ISR happens to interrupt a tickless idle period, the captured tick count isn’t current. It hasn’t yet been corrected by the tickless logic. The correction occurs immediately after the ISR. As a result, the timer is unexpectedly started from a time in the past, possibly in the distant past.

Example: GPIO ISR calls xTimerStartFromISR() for a 25ms timer

Time (ms)        10   15   20   25   30   35   40   45   50   55   60   65   70   75
Expected Tickless Period   |.................................................|
GPIO Interrupt                                           *
Expected Timer Period 25ms                               |------------------------|

However, the actual behavior (unexpected) is that the timer expires immediately (at Time = 50ms) because the timer logic thinks the start time was Time = 20ms.

If I am understanding this issue correctly, I’m happy to contribute in whatever way is most helpful. I can submit a PR or log an issue for discussion etc. Meantime a simple workaround is to notify a task or pend a function call to start the timer.

1 Like

What you are saying makes sense. I’m not shore what to do about it though, other than to document the workaround you suggest.

Was thinking about implementing the workaround right in timers.c.

xTimerStartFromISR() could queue tmrCOMMAND_START_FROM_ISR or tmrCOMMAND_START_FROM_TICKLESS as necessary. The timer task would handle the _FROM_TICKLESS case by setting the start time to the current tick count and then fall through to the existing _FROM_ISR case. Big picture, the concept of tickless idle would bleed out of tasks.c/.h and into the timers implementation, but maybe that’s OK. Also, a new version of xTaskGetTickCountFromISR() would tell the caller if a tickless idle period is currently active.

I actually like your documentation solution too :sunglasses:. So I’m satisfied either way.