Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Silabs] Fix some uart cli hang #35723

Merged
merged 6 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 34 additions & 8 deletions examples/platform/silabs/syscalls_stubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,31 @@ extern "C" {
#include "uart.h"
#endif

int _open(char * path, int flags, ...);
int _close(int file);
int _fstat(int file, struct stat * st);
int _isatty(int file);
int _lseek(int file, int ptr, int dir);
int _read(int file, char * ptr, int len);
int _write(int file, const char * ptr, int len);

/**************************************************************************
* @brief
* Open a file.
*
* @param[in] file
* File you want to open.
*
* @return
* Returns -1 since there is not logic here to open file.
**************************************************************************/

int __attribute__((weak)) _open(char * path, int flags, ...)
{
/* Pretend like we always fail */
return -1;
}

/**************************************************************************
* @brief
* Close a file.
Expand Down Expand Up @@ -170,17 +188,22 @@ int __attribute__((weak)) _lseek(int file, int ptr, int dir)
* @return
* Number of characters that have been read.
*************************************************************************/
int __attribute__((weak)) _read(int file, char * ptr, int len)
#if SILABS_LOG_OUT_UART
int _read(int file, char * ptr, int len)
{
(void) file;
#if SILABS_LOG_OUT_UART
return uartConsoleRead(ptr, len);
}
#else
int __attribute__((weak)) _read(int file, char * ptr, int len)
{
(void) file;
(void) ptr;
(void) len;
#endif

return 0;
}
#endif // SILABS_LOG_OUT_UART

/**************************************************************************
* @brief
Expand All @@ -198,17 +221,20 @@ int __attribute__((weak)) _read(int file, char * ptr, int len)
* @return
* Number of characters that have been written.
**************************************************************************/
int __attribute__((weak)) _write(int file, const char * ptr, int len)
#if SILABS_LOG_OUT_UART
int _write(int file, const char * ptr, int len)
{
(void) file;
#if SILABS_LOG_OUT_UART
uartConsoleWrite(ptr, len);
return uartConsoleWrite(ptr, len);
}
#else
int __attribute__((weak)) _write(int file, const char * ptr, int len)
{
(void) file;
(void) ptr;
#endif

return len;
}
#endif // SILABS_LOG_OUT_UART

#ifdef __cplusplus
}
Expand Down
68 changes: 53 additions & 15 deletions examples/platform/silabs/uart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,12 @@ extern "C" {
#include "rsi_rom_egpio.h"
#include "sl_si91x_usart.h"
#else // For EFR32
#if (_SILICON_LABS_32B_SERIES < 3)
#include "em_core.h"
#include "em_usart.h"
#else
#include "sl_hal_eusart.h"
#endif //_SILICON_LABS_32B_SERIES
#include "uartdrv.h"
#ifdef SL_BOARD_NAME
#include "sl_board_control.h"
Expand Down Expand Up @@ -86,11 +90,34 @@ extern "C" {
#define USART_IRQ HELPER2(SL_UARTDRV_EUSART_VCOM_PERIPHERAL_NO)
#define USART_IRQHandler HELPER4(SL_UARTDRV_EUSART_VCOM_PERIPHERAL_NO)
#define vcom_handle sl_uartdrv_eusart_vcom_handle

#if (_SILICON_LABS_32B_SERIES < 3)
#define EUSART_INT_ENABLE EUSART_IntEnable
#define EUSART_INT_DISABLE EUSART_IntDisable
#define EUSART_INT_CLEAR EUSART_IntClear
#define EUSART_CLEAR_RX
#define EUSART_GET_PENDING_INT EUSART_IntGet
#define EUSART_ENABLE(eusart) EUSART_Enable(eusart, eusartEnable)
#else
#define EUSART_INT_ENABLE sl_hal_eusart_enable_interrupts
#define EUSART_INT_DISABLE sl_hal_eusart_disable_interrupts
#define EUSART_INT_SET sl_hal_eusart_set_interrupts
#define EUSART_INT_CLEAR sl_hal_eusart_clear_interrupts
#define EUSART_CLEAR_RX sl_hal_eusart_clear_rx
#define EUSART_GET_PENDING_INT sl_hal_eusart_get_pending_interrupts
#define EUSART_ENABLE(eusart) \
{ \
sl_hal_eusart_enable(eusart); \
sl_hal_eusart_enable_tx(eusart); \
sl_hal_eusart_enable_rx(eusart); \
}
#endif //_SILICON_LABS_32B_SERIES

#else
#define USART_IRQ HELPER2(SL_UARTDRV_USART_VCOM_PERIPHERAL_NO)
#define USART_IRQHandler HELPER4(SL_UARTDRV_USART_VCOM_PERIPHERAL_NO)
#define vcom_handle sl_uartdrv_usart_vcom_handle
#endif // EFR32MG24
#endif // SL_CATALOG_UARTDRV_EUSART_PRESENT

namespace {
// In order to reduce the probability of data loss during the dmaFull callback handler we use
Expand Down Expand Up @@ -118,7 +145,11 @@ typedef struct
#if SILABS_LOG_OUT_UART
#define UART_MAX_QUEUE_SIZE 125
#else
#if (_SILICON_LABS_32B_SERIES < 3)
#define UART_MAX_QUEUE_SIZE 25
#else
#define UART_MAX_QUEUE_SIZE 50
#endif
#endif

#ifdef CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE
Expand All @@ -138,13 +169,7 @@ constexpr osThreadAttr_t kUartTaskAttr = { .name = "UART",
.cb_size = osThreadCbSize,
.stack_mem = uartStack,
.stack_size = kUartTaskSize,
#if SLI_SI91X_MCU_INTERFACE
// Reducing the priority of the UART task to avoid priority inversion
.priority = osPriorityNormal
#else
.priority = osPriorityRealtime
#endif // SLI_SI91X_MCU_INTERFACE
};
.priority = osPriorityBelowNormal };

typedef struct
{
Expand Down Expand Up @@ -309,16 +334,17 @@ void uartConsoleInit(void)

#ifdef SL_CATALOG_UARTDRV_EUSART_PRESENT
// Clear previous RX interrupts
EUSART_IntClear(SL_UARTDRV_EUSART_VCOM_PERIPHERAL, EUSART_IF_RXFL);
EUSART_INT_CLEAR(SL_UARTDRV_EUSART_VCOM_PERIPHERAL, (EUSART_IF_RXFL | EUSART_IF_RXOF));
EUSART_CLEAR_RX(SL_UARTDRV_EUSART_VCOM_PERIPHERAL);

// Enable RX interrupts
EUSART_IntEnable(SL_UARTDRV_EUSART_VCOM_PERIPHERAL, EUSART_IF_RXFL);
EUSART_INT_ENABLE(SL_UARTDRV_EUSART_VCOM_PERIPHERAL, EUSART_IF_RXFL);

// Enable EUSART
EUSART_Enable(SL_UARTDRV_EUSART_VCOM_PERIPHERAL, eusartEnable);
EUSART_ENABLE(SL_UARTDRV_EUSART_VCOM_PERIPHERAL);
#else
USART_IntEnable(SL_UARTDRV_USART_VCOM_PERIPHERAL, USART_IF_RXDATAV);
#endif // EFR32MG24
#endif // SL_CATALOG_UARTDRV_EUSART_PRESENT
#endif // SLI_SI91X_MCU_INTERFACE == 0
}

Expand All @@ -344,9 +370,15 @@ void USART_IRQHandler(void)
#elif !defined(PW_RPC_ENABLED) && !defined(SL_WIFI)
otSysEventSignalPending();
#endif

#ifdef SL_CATALOG_UARTDRV_EUSART_PRESENT
EUSART_IntClear(SL_UARTDRV_EUSART_VCOM_PERIPHERAL, EUSART_IF_RXFL);
// disable RXFL IRQ until data read by uartConsoleRead
EUSART_INT_DISABLE(SL_UARTDRV_EUSART_VCOM_PERIPHERAL, EUSART_IF_RXFL);
EUSART_INT_CLEAR(SL_UARTDRV_EUSART_VCOM_PERIPHERAL, EUSART_IF_RXFL);

if (EUSART_GET_PENDING_INT(SL_UARTDRV_EUSART_VCOM_PERIPHERAL) & EUSART_IF_RXOF)
{
EUSART_CLEAR_RX(SL_UARTDRV_EUSART_VCOM_PERIPHERAL);
}
#endif
}

Expand Down Expand Up @@ -418,7 +450,8 @@ int16_t uartConsoleWrite(const char * Buf, uint16_t BufLength)
memcpy(workBuffer.data, Buf, BufLength);
workBuffer.length = BufLength;

if (osMessageQueuePut(sUartTxQueue, &workBuffer, osPriorityNormal, 0) == osOK)
// this is usually a command response. Wait on queue if full.
if (osMessageQueuePut(sUartTxQueue, &workBuffer, osPriorityNormal, osWaitForever) == osOK)
{
return BufLength;
}
Expand All @@ -445,6 +478,7 @@ int16_t uartLogWrite(const char * log, uint16_t length)
memcpy(workBuffer.data + length, "\r\n", 2);
workBuffer.length = length + 2;

// Don't wait when queue is full. Drop the log and return UART_CONSOLE_ERR
if (osMessageQueuePut(sUartTxQueue, &workBuffer, osPriorityNormal, 0) == osOK)
{
return length;
Expand All @@ -462,6 +496,10 @@ int16_t uartConsoleRead(char * Buf, uint16_t NbBytesToRead)
{
uint8_t * data;

#ifdef SL_CATALOG_UARTDRV_EUSART_PRESENT
EUSART_INT_ENABLE(SL_UARTDRV_EUSART_VCOM_PERIPHERAL, EUSART_IF_RXFL);
#endif

if (Buf == NULL || NbBytesToRead < 1)
{
return UART_CONSOLE_ERR;
Expand Down
8 changes: 7 additions & 1 deletion src/lib/shell/streamer_silabs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,13 @@ ssize_t streamer_efr_read(streamer_t * streamer, char * buffer, size_t length)
ssize_t streamer_efr_write(streamer_t * streamer, const char * buffer, size_t length)
{
(void) streamer;
return uartConsoleWrite(buffer, (uint16_t) length);
int16_t bytesWritten = uartConsoleWrite(buffer, (uint16_t) length);
if (bytesWritten < 0) // The Write failed
{
bytesWritten = 0;
}

return bytesWritten;
}

static streamer_t streamer_efr = {
Expand Down
6 changes: 5 additions & 1 deletion third_party/silabs/SiWx917_sdk.gni
Original file line number Diff line number Diff line change
Expand Up @@ -773,8 +773,12 @@ template("siwx917_sdk") {
public_deps = [
"${segger_rtt_root}:segger_rtt",
"${segger_rtt_root}:segger_rtt_printf",
"${segger_rtt_root}:segger_rtt_syscalls",
]

if (!sl_uart_log_output) {
public_deps += [ "${segger_rtt_root}:segger_rtt_syscalls" ]
}

if (chip_crypto == "platform") {
if (sl_si91x_crypto_flavor == "tinycrypt") {
public_deps += [ ":siwx917_tinycrypt" ]
Expand Down
5 changes: 4 additions & 1 deletion third_party/silabs/efr32_sdk.gni
Original file line number Diff line number Diff line change
Expand Up @@ -1069,9 +1069,12 @@ template("efr32_sdk") {
":efr32_mbedtls_config",
"${segger_rtt_root}:segger_rtt",
"${segger_rtt_root}:segger_rtt_printf",
"${segger_rtt_root}:segger_rtt_syscalls",
]

if (!sl_uart_log_output) {
public_deps += [ "${segger_rtt_root}:segger_rtt_syscalls" ]
}

if (defined(invoker.sources)) {
sources += invoker.sources
}
Expand Down
Loading