drivers: serial: nrfx_uarte: Fix race condition in TX path

If interrupt handler contains while loop which depends on
uart_irq_tx_ready() and uart_fifo_fill is called inside this
loop then if TXSTOPPED event occurs while code executes the
loop then uart_irq_tx_ready() will return true but uart_fifo_fill
will fail to write any bytes. That is because fifo_fill_lock is
cleared in handling of TXSTOPPED. To solve that added clearing
the lock inside uart_irq_tx_ready() if STOPPED event is detected
there.

Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
Krzysztof Chruscinski 2020-12-04 14:13:03 +01:00 committed by Carles Cufí
commit 2db49c4b99

View file

@ -1259,9 +1259,16 @@ static int uarte_nrfx_irq_tx_ready_complete(const struct device *dev)
* enabled, otherwise this function would always return true no matter
* what would be the source of interrupt.
*/
return !data->int_driven->disable_tx_irq &&
nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_TXSTOPPED) &&
nrf_uarte_int_enable_check(uarte, NRF_UARTE_INT_TXSTOPPED_MASK);
bool ready = !data->int_driven->disable_tx_irq &&
nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_TXSTOPPED) &&
nrf_uarte_int_enable_check(uarte,
NRF_UARTE_INT_TXSTOPPED_MASK);
if (ready) {
data->int_driven->fifo_fill_lock = 0;
}
return ready;
}
static int uarte_nrfx_irq_rx_ready(const struct device *dev)