Mirror with some correction
Dependencies: mbed FastIO FastPWM USBDevice
mbed_Fixes/KLXX_us_ticker_fix.c@116:7a67265d7c19, 2021-10-01 (annotated)
- Committer:
- arnoz
- Date:
- Fri Oct 01 08:19:46 2021 +0000
- Revision:
- 116:7a67265d7c19
- Parent:
- 79:682ae3171a08
- Correct information regarding your last merge
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mjr | 79:682ae3171a08 | 1 | #include <stddef.h> |
mjr | 79:682ae3171a08 | 2 | #include "us_ticker_api.h" |
mjr | 79:682ae3171a08 | 3 | |
mjr | 79:682ae3171a08 | 4 | // Bug fix: if scheduling an event in the past, schedule it for |
mjr | 79:682ae3171a08 | 5 | // the very near future rather than invoking the handler directly. |
mjr | 79:682ae3171a08 | 6 | // For Tickers and other recurring events, invoking the handler |
mjr | 79:682ae3171a08 | 7 | // can cause significant recursion, since the handler might try |
mjr | 79:682ae3171a08 | 8 | // to schedule the next event, which will end up back here, which |
mjr | 79:682ae3171a08 | 9 | // will call the handler again, and so on. Forcing the event |
mjr | 79:682ae3171a08 | 10 | // into the future prevents this recursion and ensures bounded |
mjr | 79:682ae3171a08 | 11 | // stack use. The effect will be the same either way: the handler |
mjr | 79:682ae3171a08 | 12 | // will be called late, since we can't actually travel back in time |
mjr | 79:682ae3171a08 | 13 | // and call it in the past. But this way we don't blow the stack |
mjr | 79:682ae3171a08 | 14 | // if we have a high-frequency recurring event that has gotten |
mjr | 79:682ae3171a08 | 15 | // significantly behind (because of a long period with interrupts |
mjr | 79:682ae3171a08 | 16 | // disabled, say). |
mjr | 79:682ae3171a08 | 17 | extern void $Super$$us_ticker_set_interrupt(timestamp_t); |
mjr | 79:682ae3171a08 | 18 | void $Sub$$us_ticker_set_interrupt(timestamp_t timestamp) |
mjr | 79:682ae3171a08 | 19 | { |
mjr | 79:682ae3171a08 | 20 | // If the event was in the past, schedule it for almost (but not |
mjr | 79:682ae3171a08 | 21 | // quite) immediately. This prevents the base version from recursing |
mjr | 79:682ae3171a08 | 22 | // into the handler; instead, we'll schedule an interrupt as for any |
mjr | 79:682ae3171a08 | 23 | // other future event. |
mjr | 79:682ae3171a08 | 24 | int tcur = us_ticker_read(); |
mjr | 79:682ae3171a08 | 25 | int delta = (int)((uint32_t)timestamp - tcur); |
mjr | 79:682ae3171a08 | 26 | if (delta <= 0) |
mjr | 79:682ae3171a08 | 27 | timestamp = tcur + 2; |
mjr | 79:682ae3171a08 | 28 | |
mjr | 79:682ae3171a08 | 29 | // call the base handler |
mjr | 79:682ae3171a08 | 30 | $Super$$us_ticker_set_interrupt(timestamp); |
mjr | 79:682ae3171a08 | 31 | } |