Skip to content

Commit 720b8d9

Browse files
committed
usb_serial_jtag: Fix bug of blocking TX xfer when using driver,
Merges #10208
1 parent c39be8b commit 720b8d9

File tree

3 files changed

+20
-28
lines changed

3 files changed

+20
-28
lines changed

components/driver/usb_serial_jtag/usb_serial_jtag.c

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ typedef struct{
3232
// TX parameters
3333
uint32_t tx_buf_size; /*!< TX buffer size */
3434
RingbufHandle_t tx_ring_buf; /*!< TX ring buffer handler */
35-
bool tx_has_tried_blocking; /*!< TX have we tried a blocking send already? */
3635
} usb_serial_jtag_obj_t;
3736

3837
static usb_serial_jtag_obj_t *p_usb_serial_jtag_obj = NULL;
@@ -162,31 +161,11 @@ int usb_serial_jtag_write_bytes(const void* src, size_t size, TickType_t ticks_t
162161
ESP_RETURN_ON_FALSE(src != NULL, ESP_ERR_INVALID_ARG, USB_SERIAL_JTAG_TAG, "Invalid buffer pointer.");
163162
ESP_RETURN_ON_FALSE(p_usb_serial_jtag_obj != NULL, ESP_ERR_INVALID_ARG, USB_SERIAL_JTAG_TAG, "The driver hasn't been initialized");
164163

165-
usb_serial_jtag_obj_t* sjtag = p_usb_serial_jtag_obj;
166-
167-
// try to send without blocking
168-
if (xRingbufferSend(sjtag->tx_ring_buf, (void*) (src), size, 0)) {
169-
goto success;
170-
}
171-
172-
// If the ring buffer is full, try to send again with a short
173-
// blocking delay, hoping for the buffer to become available soon.
174-
// If we still fail, dont ever block again until the buffer has space again.
175-
if (sjtag->tx_has_tried_blocking == false) {
176-
if (xRingbufferSend(sjtag->tx_ring_buf, (void*) (src), size, ticks_to_wait)) {
177-
goto success;
178-
} else {
179-
sjtag->tx_has_tried_blocking = true;
180-
}
181-
}
182-
183-
// tx failure
184-
return 0;
185-
186-
success:
187-
// Now trigger the ISR to read more data from the ring buffer.
164+
const uint8_t *buff = (const uint8_t *)src;
165+
// Blocking method, Sending data to ringbuffer, and handle the data in ISR.
166+
xRingbufferSend(p_usb_serial_jtag_obj->tx_ring_buf, (void*) (buff), size, ticks_to_wait);
167+
// Now trigger the ISR to read data from the ring buffer.
188168
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
189-
sjtag->tx_has_tried_blocking = false; // clear
190169
return size;
191170
}
192171

components/vfs/vfs_usb_serial_jtag.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ typedef struct {
7777
// When the driver is used (via esp_vfs_usb_serial_jtag_use_driver),
7878
// reads are either blocking or non-blocking depending on this flag.
7979
bool non_blocking;
80+
// TX has already tried a blocking send.
81+
bool tx_tried_blocking;
8082
// Newline conversion mode when transmitting
8183
esp_line_endings_t tx_mode;
8284
// Newline conversion mode when receiving
@@ -405,7 +407,18 @@ static void usbjtag_tx_char_via_driver(int fd, int c)
405407
{
406408
char ch = (char) c;
407409
TickType_t ticks = (TX_FLUSH_TIMEOUT_US / 1000) / portTICK_PERIOD_MS;
408-
usb_serial_jtag_write_bytes(&ch, 1, ticks);
410+
if (usb_serial_jtag_write_bytes(&ch, 1, 0) != 0) {
411+
s_ctx.tx_tried_blocking = false;
412+
return;
413+
}
414+
415+
if (s_ctx.tx_tried_blocking == false) {
416+
if (usb_serial_jtag_write_bytes(&ch, 1, ticks) != 0) {
417+
return;
418+
} else {
419+
s_ctx.tx_tried_blocking = true;
420+
}
421+
}
409422
}
410423

411424
void esp_vfs_usb_serial_jtag_use_nonblocking(void)

docs/en/api-guides/usb-serial-jtag-console.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ There are several limitations to the USB Serial/JTAG console feature. These may
6161

6262
2. If the application enters deep sleep mode, the USB Serial/JTAG device will disappear from the system.
6363

64-
3. For data sent in the direction of ESP32 to PC Terminal (e.g. stdout, logs), the ESP32 first writes to a small internal buffer. If this buffer becomes full (for example, if no PC Terminal is connected), the ESP32 will do a one-time wait of 50ms hoping for the PC Terminal to request the data. This can appear as a very brief 'pause' in your application.
64+
3. For data sent in the direction of {IDF_TARGET_NAME} to PC Terminal (e.g. stdout, logs), the {IDF_TARGET_NAME} first writes to a small internal buffer. If this buffer becomes full (for example, if no PC Terminal is connected), the {IDF_TARGET_NAME} will do a one-time wait of 50ms hoping for the PC Terminal to request the data. This can appear as a very brief 'pause' in your application.
6565

66-
4. For data sent in the PC Terminal to ESP32 direction (e.g. console commands), many PC Terminals will wait for the ESP32 to ingest the bytes before allowing you to sending more data. This is in contrast to using a USB-to-Serial (UART) bridge chip, which will always ingest the bytes and send them to a (possibly not listening) ESP32.
66+
4. For data sent in the PC Terminal to {IDF_TARGET_NAME} direction (e.g. console commands), many PC Terminals will wait for the {IDF_TARGET_NAME} to ingest the bytes before allowing you to sending more data. This is in contrast to using a USB-to-Serial (UART) bridge chip, which will always ingest the bytes and send them to a (possibly not listening) {IDF_TARGET_NAME}.
6767

6868
5. The USB Serial/JTAG device won't work in sleep modes as normal due to the lack of APB clock in sleep modes. This includes deep-sleep, light-sleep (automataic light-sleep as well).
6969

0 commit comments

Comments
 (0)