From b2e79959b188a40de39f0cd7daac0c5fe162acef Mon Sep 17 00:00:00 2001 From: jfbortolotti <jfbortolotti@gmail.com> Date: Tue, 6 Dec 2016 10:52:27 +0100 Subject: [PATCH] cpu: nRF52: move clearing of TXRDY flag ... before writing the data to avoid an infinite loop in case of multiple thread accessing the UART. (#6029) --- cpu/nrf5x_common/periph/uart.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/cpu/nrf5x_common/periph/uart.c b/cpu/nrf5x_common/periph/uart.c index fa6b6f5582..7b90cad4d7 100644 --- a/cpu/nrf5x_common/periph/uart.c +++ b/cpu/nrf5x_common/periph/uart.c @@ -140,12 +140,22 @@ void uart_write(uart_t uart, const uint8_t *data, size_t len) { if (uart == 0) { for (size_t i = 0; i < len; i++) { + /* This section of the function is not thread safe: + - another thread may mess up with the uart at the same time. + In order to avoid an infinite loop in the interrupted thread, + the TXRDY flag must be cleared before writing the data to be + sent and not after. This way, the higher priority thread will + exit this function with the TXRDY flag set, then the interrupted + thread may have not transmitted his data but will still exit the + while loop. + */ + + /* reset ready flag */ + NRF_UART0->EVENTS_TXDRDY = 0; /* write data into transmit register */ NRF_UART0->TXD = data[i]; /* wait for any transmission to be done */ while (NRF_UART0->EVENTS_TXDRDY == 0) {} - /* reset ready flag */ - NRF_UART0->EVENTS_TXDRDY = 0; } } } -- GitLab