mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-10 04:43:33 +00:00
fix(esp_vfs_console): USB CDC read when non blocking
In non blocking mode, the read function is expected to return weather data is available for reading or not. In case data are available but the size does not match the expected size, the function read should return whatever data is available. Previously, the function was returning -1 with errno set to EWOULDBLOCK even if the size of data in the buffer was less than the requested size. It would only return the available data if the size in the buffer was greater or equal to the requested size. The implementation of cdcacm_read is modified to return the avilable data from the buffer even is the size is lesser than the requested size.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -181,15 +181,15 @@ static ssize_t cdcacm_read(int fd, void *data, size_t size)
|
||||
ssize_t received = 0;
|
||||
_lock_acquire_recursive(&s_read_lock);
|
||||
|
||||
while (cdcacm_data_length_in_buffer() < size) {
|
||||
if (!s_blocking) {
|
||||
errno = EWOULDBLOCK;
|
||||
_lock_release_recursive(&s_read_lock);
|
||||
return -1;
|
||||
if (s_blocking) {
|
||||
while (cdcacm_data_length_in_buffer() < size) {
|
||||
xSemaphoreTake(s_rx_semaphore, portMAX_DELAY);
|
||||
}
|
||||
xSemaphoreTake(s_rx_semaphore, portMAX_DELAY);
|
||||
} else {
|
||||
/* process pending interrupts before requesting available data */
|
||||
esp_usb_console_poll_interrupts();
|
||||
size = MIN(size, cdcacm_data_length_in_buffer());
|
||||
}
|
||||
|
||||
if (s_rx_mode == ESP_LINE_ENDINGS_CR || s_rx_mode == ESP_LINE_ENDINGS_LF) {
|
||||
/* This is easy. Just receive, and if needed replace \r by \n. */
|
||||
received = esp_usb_console_read_buf(data_c, size);
|
||||
@@ -443,6 +443,9 @@ static esp_err_t cdcacm_start_select(int nfds, fd_set *readfds, fd_set *writefds
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* make sure the driver processes any pending interrupts before checking read or write
|
||||
* readiness */
|
||||
esp_usb_console_poll_interrupts();
|
||||
bool trigger_select = false;
|
||||
if (FD_ISSET(USB_CDC_LOCAL_FD, &args->readfds_orig) &&
|
||||
esp_usb_console_available_for_read() > 0) {
|
||||
|
Reference in New Issue
Block a user