drivers: serial: nrfx_uarte: Fix race condition in async isr
When DMA switches from one buffer to another ENDRX followed by RXSTARTED is generated. Code flow assumes that ENDRX will be handled before RXSTARTED but this may not be the case if there is a short between ENDRX and RXSTARTED and event occurs after ENDRX event check but before RXSTARTED event check. In that case, RXSTARTED event is handled first. Such case may happen if there is a higher priority interrupt that may preempt UARTE interrupt handler. Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
parent
7cae49d22c
commit
c44a46f1f5
1 changed files with 9 additions and 1 deletions
|
@ -1329,7 +1329,15 @@ static void uarte_nrfx_isr_async(const struct device *dev)
|
|||
endrx_isr(dev);
|
||||
}
|
||||
|
||||
if (nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_RXSTARTED)) {
|
||||
/* RXSTARTED must be handled after ENDRX because it starts the RX timeout
|
||||
* and if order is swapped then ENDRX will stop this timeout.
|
||||
* Skip if ENDRX is set when RXSTARTED 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_RXSTARTED) &&
|
||||
!nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_ENDRX)) {
|
||||
nrf_uarte_event_clear(uarte, NRF_UARTE_EVENT_RXSTARTED);
|
||||
rxstarted_isr(dev);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue