mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-27 15:31:17 +01:00
cpu/stm32: avoid deadlock on nonblocking write
If a write to a full tsrb is attempted with disabled interrupts or in a interrupt then a deadlock will occure. To avoid this make space in the ringbuffer by synchrnously writing to uart.
This commit is contained in:
parent
f7d124e141
commit
09f0fd4526
@ -322,22 +322,18 @@ static inline void uart_init_lpuart(uart_t uart, uint32_t baudrate)
|
||||
#endif /* MODULE_PERIPH_LPUART */
|
||||
#endif /* STM32L0 || STM32L4 || STM32WB */
|
||||
|
||||
#ifndef MODULE_PERIPH_UART_NONBLOCKING
|
||||
static inline void send_byte(uart_t uart, uint8_t byte)
|
||||
{
|
||||
while (!(dev(uart)->ISR_REG & ISR_TXE)) {}
|
||||
dev(uart)->TDR_REG = byte;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef MODULE_PERIPH_UART_NONBLOCKING
|
||||
static inline void wait_for_tx_complete(uart_t uart)
|
||||
{
|
||||
#ifdef MODULE_PERIPH_UART_NONBLOCKING
|
||||
(void) uart;
|
||||
#else
|
||||
while (!(dev(uart)->ISR_REG & ISR_TC)) {}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void uart_write(uart_t uart, const uint8_t *data, size_t len)
|
||||
{
|
||||
@ -387,17 +383,28 @@ void uart_write(uart_t uart, const uint8_t *data, size_t len)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
#ifdef MODULE_PERIPH_UART_NONBLOCKING
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
dev(uart)->CR1 |= (USART_CR1_TCIE);
|
||||
while (tsrb_add_one(&uart_tx_rb[uart], data[i]) < 0) {}
|
||||
if (irq_is_in() || __get_PRIMASK()) {
|
||||
/* if ring buffer is full free up a spot */
|
||||
if (tsrb_full(&uart_tx_rb[uart])) {
|
||||
send_byte(uart, tsrb_get_one(&uart_tx_rb[uart]));
|
||||
}
|
||||
tsrb_add_one(&uart_tx_rb[uart], data[i]);
|
||||
}
|
||||
else {
|
||||
while (tsrb_add_one(&uart_tx_rb[uart], data[i]) < 0) {}
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
send_byte(uart, data[i]);
|
||||
#endif
|
||||
}
|
||||
/* make sure the function is synchronous by waiting for the transfer to
|
||||
* finish */
|
||||
wait_for_tx_complete(uart);
|
||||
#endif
|
||||
}
|
||||
|
||||
void uart_poweron(uart_t uart)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user