Skip to content

Commit

Permalink
drivers: serial: nrfx_uarte: Fix race condition in TX path
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
nordic-krch authored and carlescufi committed Dec 7, 2020
1 parent 2f6164e commit 2db49c4
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions drivers/serial/uart_nrfx_uarte.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 2db49c4

Please sign in to comment.