From 326814784b4528257165e289ec654435a87db122 Mon Sep 17 00:00:00 2001 From: Rahix <rahix@rahix.de> Date: Sat, 24 Aug 2019 00:32:40 +0200 Subject: [PATCH] fix(serial): Perform serial prints in a critical section Sometimes during initialization, one `log_msg()` intercepts another one, leading to a whole lot of weird issues in other modules (like I2C). I suspect this to be memory corruption of some kind. The issues can be fixed by performing serial prints in a critical section, thus ensuring atomicity of prints. Note that this does not mean log messages will not interleave. The CDC-ACM and BLE-Serial writes cannot be put into a critical section and are thus a point where this code can still fail. For now, however, this fix ensures the race-conditions during startup, where USB and BLE are not yet running, don't happen anymore. Signed-off-by: Rahix <rahix@rahix.de> --- epicardium/modules/serial.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/epicardium/modules/serial.c b/epicardium/modules/serial.c index a7392056..b7be0594 100644 --- a/epicardium/modules/serial.c +++ b/epicardium/modules/serial.c @@ -27,7 +27,21 @@ static QueueHandle_t read_queue; */ void epic_uart_write_str(const char *str, intptr_t length) { + uint32_t basepri = __get_BASEPRI(); + if (xPortIsInsideInterrupt()) { + taskENTER_CRITICAL_FROM_ISR(); + } else { + taskENTER_CRITICAL(); + } + UART_Write(ConsoleUart, (uint8_t *)str, length); + + if (xPortIsInsideInterrupt()) { + taskEXIT_CRITICAL_FROM_ISR(basepri); + } else { + taskEXIT_CRITICAL(); + } + cdcacm_write((uint8_t *)str, length); ble_uart_write((uint8_t *)str, length); } -- GitLab