Skip to content

Commit 482fae7

Browse files
nordic-krchcarlescufi
authored andcommitted
drivers: timer: nrf_rtc_timer: Fix race condition
RTC interrupt was reading CC value and passing it to the handler. However, higher priority interrupt could preempt RTC interrupt and set new CC value. In that case CC value read in the RTC interrupt context was not the one that triggered the interrupt. Added fallback to COUNTER value if that case is detected. Using COUNTER is not as precise as CC because it returns time when event was handled and not when event occured but it is the only option since CC value is overwritten. Signed-off-by: Krzysztof Chruscinski <[email protected]>
1 parent 8cbef2d commit 482fae7

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

drivers/timer/nrf_rtc_timer.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,11 +262,23 @@ void rtc_nrf_isr(const void *arg)
262262
if (nrf_rtc_int_enable_check(RTC, RTC_CHANNEL_INT_MASK(chan)) &&
263263
nrf_rtc_event_check(RTC, RTC_CHANNEL_EVENT_ADDR(chan))) {
264264
uint32_t cc_val;
265+
uint32_t now;
265266
z_nrf_rtc_timer_compare_handler_t handler;
266267

267268
event_clear(chan);
268269
event_disable(chan);
269270
cc_val = get_comparator(chan);
271+
now = counter();
272+
273+
/* Higher priority interrupt may already changed cc_val
274+
* which now points to the future. In that case return
275+
* current counter value. It is less precise than
276+
* returning exact CC value but this one is already lost.
277+
*/
278+
if (counter_sub(now, cc_val) > COUNTER_HALF_SPAN) {
279+
cc_val = now;
280+
}
281+
270282
handler = cc_data[chan].callback;
271283
cc_data[chan].callback = NULL;
272284
if (handler) {

0 commit comments

Comments
 (0)