From f423642f6e8959f34bf25d6fb6d5135904553be9 Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Wed, 10 Sep 2025 18:24:40 +0200 Subject: [PATCH] Add uart_read_some_bytes() to allow reading into a buffer without waiting until that buffer is full --- .../esp_driver_uart/include/driver/uart.h | 16 +++++++++++ components/esp_driver_uart/src/uart.c | 28 +++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/components/esp_driver_uart/include/driver/uart.h b/components/esp_driver_uart/include/driver/uart.h index 8946ce1260..9f0540dc76 100644 --- a/components/esp_driver_uart/include/driver/uart.h +++ b/components/esp_driver_uart/include/driver/uart.h @@ -556,6 +556,7 @@ int uart_write_bytes_with_break(uart_port_t uart_num, const void* src, size_t si /** * @brief UART read bytes from UART buffer + * Blocks until the buffer to fill is filled completely or timeout is expired * * @param uart_num UART port number, the max port number is (UART_NUM_MAX -1). * @param buf pointer to the buffer. @@ -568,6 +569,21 @@ int uart_write_bytes_with_break(uart_port_t uart_num, const void* src, size_t si */ int uart_read_bytes(uart_port_t uart_num, void* buf, uint32_t length, TickType_t ticks_to_wait); +/** + * @brief UART read bytes from UART buffer + * Blocks until there is at least something to read (might be smaller than length!) or timeout is expired + * + * @param uart_num UART port number, the max port number is (UART_NUM_MAX -1). + * @param buf pointer to the buffer. + * @param length data length + * @param ticks_to_wait sTimeout, count in RTOS ticks + * + * @return + * - (-1) Error + * - OTHERS (>=0) The number of bytes read from UART buffer + */ +int uart_read_some_bytes(uart_port_t uart_num, void* buf, uint32_t length, TickType_t ticks_to_wait); + /** * @brief Alias of uart_flush_input. * UART ring buffer flush. This will discard all data in the UART RX buffer. diff --git a/components/esp_driver_uart/src/uart.c b/components/esp_driver_uart/src/uart.c index 9656a3ff06..3b52953f2e 100644 --- a/components/esp_driver_uart/src/uart.c +++ b/components/esp_driver_uart/src/uart.c @@ -1556,6 +1556,34 @@ int uart_read_bytes(uart_port_t uart_num, void *buf, uint32_t length, TickType_t return copy_len; } +int uart_read_some_bytes(uart_port_t uart_num, void *buf, uint32_t length, TickType_t ticks_to_wait) +{ + ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), (-1), UART_TAG, "uart_num error"); + ESP_RETURN_ON_FALSE((buf), (-1), UART_TAG, "uart data null"); + ESP_RETURN_ON_FALSE((p_uart_obj[uart_num]), (-1), UART_TAG, "uart driver error"); + uint8_t *data = NULL; + size_t size = 0; + if (xSemaphoreTake(p_uart_obj[uart_num]->rx_mux, (TickType_t)ticks_to_wait) != pdTRUE) { + return -1; + } + + data = (uint8_t *) xRingbufferReceiveUpTo(p_uart_obj[uart_num]->rx_ring_buf, &size, (TickType_t) ticks_to_wait, length); + if (!data) { + xSemaphoreGive(p_uart_obj[uart_num]->rx_mux); + return 0; + } + memcpy((uint8_t *)buf, data, size); + UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); + p_uart_obj[uart_num]->rx_buffered_len -= size; + uart_pattern_queue_update(uart_num, size); + UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); + vRingbufferReturnItem(p_uart_obj[uart_num]->rx_ring_buf, data); + uart_check_buf_full(uart_num); + + xSemaphoreGive(p_uart_obj[uart_num]->rx_mux); + return size; +} + esp_err_t uart_get_buffered_data_len(uart_port_t uart_num, size_t *size) { ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error");