drivers: serial: nrfx_uarte: Fix race condition in async isr

RXTO event is generated always after ENDRX and driver relies
on assumption that ENDRX event is handled before RXTO. However,
when interrupt is preempted after ENDRX check returned false
and RXTO event is already set handling order would be swapped.

Added addtional check to handle RXTO event only if ENDRX is not
set. If ENDRX is set, it means that it is not yet handled. RXTO
event is not cleared and interrupt will be triggered again and
ENDRX event will be handled first.

Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
Krzysztof Chruscinski 2021-06-23 07:27:07 +02:00 committed by Anas Nashif
commit 520ba93f5d

View file

@ -1334,7 +1334,14 @@ static void uarte_nrfx_isr_async(const struct device *dev)
rxstarted_isr(dev);
}
if (nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_RXTO)) {
/* RXTO must be handled after ENDRX which should notify the buffer.
* Skip if ENDRX is set when RXTO is set. It means that
* ENDRX occurred after check for ENDRX in isr which may happen when
* UARTE interrupt got preempted. Events are not cleared
* and isr will be called again. ENDRX will be handled first.
*/
if (nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_RXTO) &&
!nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_ENDRX)) {
nrf_uarte_event_clear(uarte, NRF_UARTE_EVENT_RXTO);
rxto_isr(dev);
}