From 454d1ac65d8bd1fe5e8b561ed29a4edeece58814 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Mon, 13 Oct 2025 15:49:23 +0800 Subject: [PATCH 1/2] fix(esp_driver_usb_serial_jtag): check USJ accessibility before read/write Add connection checks to usb_serial_jtag_write and usb_serial_jtag_read functions to return -EIO error code when the USB Serial JTAG is not connected. --- .../src/usb_serial_jtag_vfs.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag_vfs.c b/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag_vfs.c index c6a3aac01d6..f2b2e4ee993 100644 --- a/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag_vfs.c +++ b/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag_vfs.c @@ -176,6 +176,10 @@ static int usb_serial_jtag_rx_char(int fd) static ssize_t usb_serial_jtag_write(int fd, const void * data, size_t size) { + if (!usb_serial_jtag_is_connected()) { + // TODO: IDF-14303 + return -1; + } const char *data_c = (const char *)data; /* Even though newlib does stream locking on each individual stream, we need * a dedicated lock if two streams (stdout and stderr) point to the @@ -220,6 +224,10 @@ 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) { + if (!usb_serial_jtag_is_connected()) { + // TODO: IDF-14303 + return -1; + } char *data_c = (char *) data; size_t received = 0; size_t available_size = 0; @@ -323,6 +331,10 @@ static int usb_serial_jtag_fcntl(int fd, int cmd, int arg) static int usb_serial_jtag_fsync(int fd) { + if (!usb_serial_jtag_is_connected()) { + // TODO: IDF-14303 + return -1; + } _lock_acquire_recursive(&s_ctx.write_lock); usb_serial_jtag_ll_txfifo_flush(); //Wait for the host to have picked up the buffer, but honour the timeout in From 92ed9c8d9059f03b97ba11dc20431dba71c8871f Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Mon, 13 Oct 2025 17:20:04 +0800 Subject: [PATCH 2/2] test(esp_pm): add test case for USJ printing performance during wake-up Add a new test case to verify that USJ printing doesn't block CPU on chip wake-up from light sleep. The test measures the average time per print operation and ensures it's below 5000 microseconds. --- .../test_apps/esp_pm/main/CMakeLists.txt | 2 +- .../esp_pm/test_apps/esp_pm/main/test_pm.c | 26 ++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/components/esp_pm/test_apps/esp_pm/main/CMakeLists.txt b/components/esp_pm/test_apps/esp_pm/main/CMakeLists.txt index 48c7ad8ed7a..8f23c7c0574 100644 --- a/components/esp_pm/test_apps/esp_pm/main/CMakeLists.txt +++ b/components/esp_pm/test_apps/esp_pm/main/CMakeLists.txt @@ -5,5 +5,5 @@ set(sources "test_app_main.c" # the component must be registered as a WHOLE_ARCHIVE idf_component_register(SRCS ${sources} INCLUDE_DIRS "." - PRIV_REQUIRES unity esp_pm ulp driver esp_timer esp_psram + PRIV_REQUIRES unity esp_pm ulp driver esp_timer esp_psram esp_vfs_console WHOLE_ARCHIVE) diff --git a/components/esp_pm/test_apps/esp_pm/main/test_pm.c b/components/esp_pm/test_apps/esp_pm/main/test_pm.c index dfba174a243..d08e5900545 100644 --- a/components/esp_pm/test_apps/esp_pm/main/test_pm.c +++ b/components/esp_pm/test_apps/esp_pm/main/test_pm.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -397,6 +398,29 @@ TEST_CASE("esp_timer with SKIP_UNHANDLED_EVENTS does not wake up CPU from sleep" TEST_ESP_OK(esp_timer_delete(periodic_timer)); } +TEST_CASE("Test USJ printing doesn't block CPU on chip wake-up", "[pm]") +{ + light_sleep_enable(); + fflush(stdout); + fsync(fileno(stdout)); + int64_t printing_time_cost_us = 0, time_end, time_start; + + for (int i = 0; i < 20; ++i) + { + time_start = esp_timer_get_time(); + printf("Dummy print %02d\n", i); + fflush(stdout); + fsync(fileno(stdout)); + time_end = esp_timer_get_time(); + printing_time_cost_us += time_end - time_start; + vTaskDelay(10); + } + int32_t avg_cost = (int32_t)(printing_time_cost_us / 20); + printf("Average cost per print %ld\n", avg_cost); + TEST_ASSERT_LESS_THAN(5000, avg_cost); + light_sleep_disable(); +} + #endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE #endif // CONFIG_PM_ENABLE