Skip to content

Commit 18709fa

Browse files
fix(uart): uart rx timeout validation with proper log message (espressif#11141)
* feat(uart): adds a function to calculate maximum valid rx timeout * fix(uart): check uart rx timeout value and log an error msg * fix(uart): changes log message to a more clear one * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
1 parent e2915c4 commit 18709fa

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

cores/esp32/esp32-hal-uart.c

+25-1
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,11 @@ bool uartSetRxTimeout(uart_t *uart, uint8_t numSymbTimeout) {
757757
if (uart == NULL) {
758758
return false;
759759
}
760-
760+
uint16_t maxRXTimeout = uart_get_max_rx_timeout(uart->num);
761+
if (numSymbTimeout > maxRXTimeout) {
762+
log_e("Invalid RX Timeout value, its limit is %d", maxRXTimeout);
763+
return false;
764+
}
761765
UART_MUTEX_LOCK();
762766
bool retCode = (ESP_OK == uart_set_rx_timeout(uart->num, numSymbTimeout));
763767
UART_MUTEX_UNLOCK();
@@ -1382,4 +1386,24 @@ int uart_send_msg_with_break(uint8_t uartNum, uint8_t *msg, size_t msgSize) {
13821386
return uart_write_bytes_with_break(uartNum, (const void *)msg, msgSize, 12);
13831387
}
13841388

1389+
// returns the maximum valid uart RX Timeout based on the UART Source Clock and Baudrate
1390+
uint16_t uart_get_max_rx_timeout(uint8_t uartNum) {
1391+
if (uartNum >= SOC_UART_NUM) {
1392+
log_e("UART%d is invalid. This device has %d UARTs, from 0 to %d.", uartNum, SOC_UART_NUM, SOC_UART_NUM - 1);
1393+
return (uint16_t)-1;
1394+
}
1395+
uint16_t tout_max_thresh = uart_ll_max_tout_thrd(UART_LL_GET_HW(uartNum));
1396+
uint8_t symbol_len = 1; // number of bits per symbol including start
1397+
uart_parity_t parity_mode;
1398+
uart_stop_bits_t stop_bit;
1399+
uart_word_length_t data_bit;
1400+
uart_ll_get_data_bit_num(UART_LL_GET_HW(uartNum), &data_bit);
1401+
uart_ll_get_stop_bits(UART_LL_GET_HW(uartNum), &stop_bit);
1402+
uart_ll_get_parity(UART_LL_GET_HW(uartNum), &parity_mode);
1403+
symbol_len += (data_bit < UART_DATA_BITS_MAX) ? (uint8_t)data_bit + 5 : 8;
1404+
symbol_len += (stop_bit > UART_STOP_BITS_1) ? 2 : 1;
1405+
symbol_len += (parity_mode > UART_PARITY_DISABLE) ? 1 : 0;
1406+
return (uint16_t)(tout_max_thresh / symbol_len);
1407+
}
1408+
13851409
#endif /* SOC_UART_SUPPORTED */

cores/esp32/esp32-hal-uart.h

+4
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ void uart_send_break(uint8_t uartNum);
116116
// Sends a buffer and at the end of the stream, it generates BREAK in the line
117117
int uart_send_msg_with_break(uint8_t uartNum, uint8_t *msg, size_t msgSize);
118118

119+
// UART RX Timeout (in UART Symbols) depends on the UART Clock Source and the SoC that is used
120+
// This is a helper function that calculates what is the maximum RX Timeout that a running UART IDF driver allows.
121+
uint16_t uart_get_max_rx_timeout(uint8_t uartNum);
122+
119123
#ifdef __cplusplus
120124
}
121125
#endif

0 commit comments

Comments
 (0)