feat(usb_serial_jtag): Update vfs read to be POSIX compliant

The function now returns with available data in blocking mode
instead of waiting for the requested size to be available before
returning.
This commit is contained in:
Guillaume Souchere
2025-06-09 09:03:40 +02:00
parent d9c001cbc1
commit 422dd808e4
3 changed files with 115 additions and 28 deletions

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -96,6 +96,34 @@ esp_err_t usb_serial_jtag_driver_uninstall(void);
*/ */
bool usb_serial_jtag_is_connected(void); bool usb_serial_jtag_is_connected(void);
/**
* @brief Get information whether the USB serial JTAG driver is installed or not
*
* @return True if driver is installed and False if driver not installed
*/
bool usb_serial_jtag_is_driver_installed(void);
/**
* @brief Return the number of bytes available for reading
*
* @return the number of bytes available for reading in the buffer
*/
size_t usb_serial_jtag_get_read_bytes_available(void);
/**
* @brief Return the readiness status of the driver for read operation
*
* @return true if driver read ready, false if not
*/
bool usb_serial_jtag_read_ready(void);
/**
* @brief Return the readiness status of the driver for write operation
*
* @return true if driver is write ready, false if not
*/
bool usb_serial_jtag_write_ready(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -256,3 +256,33 @@ esp_err_t usb_serial_jtag_driver_uninstall(void)
p_usb_serial_jtag_obj = NULL; p_usb_serial_jtag_obj = NULL;
return ESP_OK; return ESP_OK;
} }
bool usb_serial_jtag_is_driver_installed(void)
{
return (p_usb_serial_jtag_obj != NULL);
}
size_t usb_serial_jtag_get_read_bytes_available(void)
{
// sign the the driver is read ready is that data is waiting in the RX ringbuffer
UBaseType_t bytes_available = 0;
if (usb_serial_jtag_is_driver_installed()) {
vRingbufferGetInfo(p_usb_serial_jtag_obj->rx_ring_buf, NULL, NULL, NULL, NULL, &bytes_available);
if (bytes_available <= 0) {
return 0;
}
}
return (size_t)bytes_available;
}
bool usb_serial_jtag_read_ready(void)
{
return usb_serial_jtag_get_read_bytes_available() != 0;
}
bool usb_serial_jtag_write_ready(void)
{
// sign that the driver is write ready is that the TX ring buffer is not full
return (xRingbufferGetCurFreeSize(p_usb_serial_jtag_obj->tx_ring_buf) > 0);
}

View File

@@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -189,22 +189,45 @@ static void usb_serial_jtag_return_char(int fd, int c)
static ssize_t usb_serial_jtag_read(int fd, void* data, size_t size) static ssize_t usb_serial_jtag_read(int fd, void* data, size_t size)
{ {
assert(fd == USJ_LOCAL_FD);
char *data_c = (char *) data; char *data_c = (char *) data;
size_t received = 0; size_t received = 0;
size_t available_size = 0;
int c = NONE; // store the read char
_lock_acquire_recursive(&s_ctx.read_lock); _lock_acquire_recursive(&s_ctx.read_lock);
while (received < size) { // if blocking read, wait for data to be available
int c = usb_serial_jtag_read_char(fd); if (!s_ctx.non_blocking) {
c = usb_serial_jtag_read_char(fd);
}
// find the actual fetch size
available_size += usb_serial_jtag_get_read_bytes_available();
if (c != NONE) {
available_size++;
}
if (s_ctx.peek_char != NONE) {
available_size++;
}
size_t fetch_size = MIN(available_size, size);
if (fetch_size > 0) {
do {
if (c == NONE) { // for non-O_NONBLOCK mode, there is already a pre-fetched char
c = usb_serial_jtag_read_char(fd);
}
assert(c != NONE);
if (c == '\r') { if (c == '\r') {
if (s_ctx.rx_mode == ESP_LINE_ENDINGS_CR) { if (s_ctx.rx_mode == ESP_LINE_ENDINGS_CR) {
c = '\n'; c = '\n';
} else if (s_ctx.rx_mode == ESP_LINE_ENDINGS_CRLF) { } else if (s_ctx.rx_mode == ESP_LINE_ENDINGS_CRLF) {
/* look ahead */ /* look ahead */
int c2 = usb_serial_jtag_read_char(fd); int c2 = usb_serial_jtag_read_char(fd);
fetch_size--;
if (c2 == NONE) { if (c2 == NONE) {
/* could not look ahead, put the current character back */ /* could not look ahead, put the current character back */
usb_serial_jtag_return_char(fd, c); usb_serial_jtag_return_char(fd, c);
c = NONE;
break; break;
} }
if (c2 == '\n') { if (c2 == '\n') {
@@ -215,13 +238,19 @@ static ssize_t usb_serial_jtag_read(int fd, void* data, size_t size)
* it will be processed on next iteration. return \r now. * it will be processed on next iteration. return \r now.
*/ */
usb_serial_jtag_return_char(fd, c2); usb_serial_jtag_return_char(fd, c2);
fetch_size++;
} }
} }
} else if (c == NONE) {
break;
} }
data_c[received] = (char) c; data_c[received] = (char) c;
++received; ++received;
c = NONE;
} while (received < fetch_size);
}
if (c != NONE) { // fetched, but not used
usb_serial_jtag_return_char(fd, c);
} }
_lock_release_recursive(&s_ctx.read_lock); _lock_release_recursive(&s_ctx.read_lock);
if (received > 0) { if (received > 0) {