mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-04 13:14:32 +02:00
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:
@@ -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
|
||||
*/
|
||||
@@ -96,6 +96,34 @@ esp_err_t usb_serial_jtag_driver_uninstall(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
|
||||
}
|
||||
#endif
|
||||
|
@@ -256,3 +256,33 @@ esp_err_t usb_serial_jtag_driver_uninstall(void)
|
||||
p_usb_serial_jtag_obj = NULL;
|
||||
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);
|
||||
}
|
||||
|
@@ -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
|
||||
*/
|
||||
@@ -189,39 +189,68 @@ 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)
|
||||
{
|
||||
assert(fd == USJ_LOCAL_FD);
|
||||
char *data_c = (char *) data;
|
||||
size_t received = 0;
|
||||
size_t available_size = 0;
|
||||
int c = NONE; // store the read char
|
||||
_lock_acquire_recursive(&s_ctx.read_lock);
|
||||
|
||||
while (received < size) {
|
||||
int c = usb_serial_jtag_read_char(fd);
|
||||
if (c == '\r') {
|
||||
if (s_ctx.rx_mode == ESP_LINE_ENDINGS_CR) {
|
||||
c = '\n';
|
||||
} else if (s_ctx.rx_mode == ESP_LINE_ENDINGS_CRLF) {
|
||||
/* look ahead */
|
||||
int c2 = usb_serial_jtag_read_char(fd);
|
||||
if (c2 == NONE) {
|
||||
/* could not look ahead, put the current character back */
|
||||
usb_serial_jtag_return_char(fd, c);
|
||||
break;
|
||||
}
|
||||
if (c2 == '\n') {
|
||||
/* this was \r\n sequence. discard \r, return \n */
|
||||
// if blocking read, wait for data to be available
|
||||
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 (s_ctx.rx_mode == ESP_LINE_ENDINGS_CR) {
|
||||
c = '\n';
|
||||
} else {
|
||||
/* \r followed by something else. put the second char back,
|
||||
* it will be processed on next iteration. return \r now.
|
||||
*/
|
||||
usb_serial_jtag_return_char(fd, c2);
|
||||
} else if (s_ctx.rx_mode == ESP_LINE_ENDINGS_CRLF) {
|
||||
/* look ahead */
|
||||
int c2 = usb_serial_jtag_read_char(fd);
|
||||
fetch_size--;
|
||||
if (c2 == NONE) {
|
||||
/* could not look ahead, put the current character back */
|
||||
usb_serial_jtag_return_char(fd, c);
|
||||
c = NONE;
|
||||
break;
|
||||
}
|
||||
if (c2 == '\n') {
|
||||
/* this was \r\n sequence. discard \r, return \n */
|
||||
c = '\n';
|
||||
} else {
|
||||
/* \r followed by something else. put the second char back,
|
||||
* it will be processed on next iteration. return \r now.
|
||||
*/
|
||||
usb_serial_jtag_return_char(fd, c2);
|
||||
fetch_size++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (c == NONE) {
|
||||
break;
|
||||
}
|
||||
data_c[received] = (char) c;
|
||||
++received;
|
||||
|
||||
data_c[received] = (char) c;
|
||||
++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);
|
||||
if (received > 0) {
|
||||
|
Reference in New Issue
Block a user