From 4c88c77f9ca500abeff45d8ff5a3bba26be30d8f Mon Sep 17 00:00:00 2001 From: Erhan Kurubas Date: Fri, 15 May 2026 15:55:47 +0200 Subject: [PATCH] feat(esp_trace): extend encoder interface Add esp_trace_flush, esp_trace_start and esp_trace_stop APIs --- components/esp_trace/README.md | 9 ++-- components/esp_trace/include/esp_trace.h | 23 +++++++++- .../include/esp_trace_port_encoder.h | 16 ++++++- .../esp_trace/src/core/esp_trace_core.c | 42 +++++++++++++++++++ 4 files changed, 83 insertions(+), 7 deletions(-) diff --git a/components/esp_trace/README.md b/components/esp_trace/README.md index 45196dd0985..47564a2983d 100644 --- a/components/esp_trace/README.md +++ b/components/esp_trace/README.md @@ -33,11 +33,12 @@ end %% ======================= subgraph PRIMARY["🔌 PUBLIC INTERFACE"] api["- esp_trace.h - - esp_trace_init() - - esp_trace_record() - esp_trace_write() + - esp_trace_start() + - esp_trace_stop() - esp_trace_flush() - - esp_trace_print()"] + - esp_trace_is_host_connected() + - esp_trace_get_link_type()"] end %% wiring: App uses API (labels land on the short pre-edges to api_in) @@ -203,7 +204,7 @@ idf_component_register( ) ``` -This means you can directly use both the trace library APIs (e.g., SystemView) and `esp_trace` APIs (like `esp_trace_get_user_params()`, `esp_trace_is_host_connected()`, etc.) without explicitly declaring the dependency. +This means you can directly use both the trace library APIs (e.g., SystemView) and `esp_trace` APIs (like `esp_trace_get_user_params()`, `esp_trace_is_host_connected()`, `esp_trace_start()` / `esp_trace_stop()` / `esp_trace_flush()`, etc.) without explicitly declaring the dependency. ### When Using Standalone Apptrace diff --git a/components/esp_trace/include/esp_trace.h b/components/esp_trace/include/esp_trace.h index 5ed7ccb3247..d17f7f60738 100644 --- a/components/esp_trace/include/esp_trace.h +++ b/components/esp_trace/include/esp_trace.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -100,6 +100,27 @@ esp_trace_handle_t esp_trace_get_active_handle(void); */ esp_err_t esp_trace_write(esp_trace_handle_t handle, const void *data, size_t size, unsigned long tmo); +/** + * @brief Resume trace event emission on the active session. + * + * @return ESP_OK on success, otherwise see esp_err_t + */ +esp_err_t esp_trace_start(void); + +/** + * @brief Pause trace event emission on the active session. + * + * @return ESP_OK on success, otherwise see esp_err_t + */ +esp_err_t esp_trace_stop(void); + +/** + * @brief Flush pending trace data through the encoder + * + * @return ESP_OK on success, otherwise see esp_err_t + */ +esp_err_t esp_trace_flush(void); + /** * @brief Check if the host is connected * diff --git a/components/esp_trace/include/esp_trace_port_encoder.h b/components/esp_trace/include/esp_trace_port_encoder.h index 2aa7bd8b9f6..59a603ad0fe 100644 --- a/components/esp_trace/include/esp_trace_port_encoder.h +++ b/components/esp_trace/include/esp_trace_port_encoder.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -49,8 +49,20 @@ typedef struct { */ void (*panic_handler)(esp_trace_encoder_t *enc, const void *info); + /** @brief Resume trace event emission */ + esp_err_t (*start)(esp_trace_encoder_t *enc); + + /** @brief Pause trace event emission */ + esp_err_t (*stop)(esp_trace_encoder_t *enc); + + /** @brief Flush pending trace data through the encoder */ + esp_err_t (*flush)(esp_trace_encoder_t *enc); + /** - * @brief Take encoder lock + * @brief Take encoder lock. + * Callers should pass ESP_TRACE_TMO_INFINITE unless they explicitly + * check the return value — pairing a failed take with give_lock() + * causes a spinlock owner-mismatch assert. * @param enc Encoder instance * @param tmo Timeout in microseconds * @return Lock state (for recursive locking) or 0 on failure diff --git a/components/esp_trace/src/core/esp_trace_core.c b/components/esp_trace/src/core/esp_trace_core.c index 885b807b040..7fd81c5a544 100644 --- a/components/esp_trace/src/core/esp_trace_core.c +++ b/components/esp_trace/src/core/esp_trace_core.c @@ -151,6 +151,48 @@ esp_err_t esp_trace_write(esp_trace_handle_t h, const void *data, size_t size, u return h->encoder.vt->write(&h->encoder, data, size, tmo); } +esp_err_t esp_trace_start(void) +{ + esp_trace_handle_t h = s_active_handle; + if (!h) { + return ESP_ERR_INVALID_STATE; + } + + if (!h->encoder.vt->start) { + return ESP_ERR_NOT_SUPPORTED; + } + + return h->encoder.vt->start(&h->encoder); +} + +esp_err_t esp_trace_stop(void) +{ + esp_trace_handle_t h = s_active_handle; + if (!h) { + return ESP_ERR_INVALID_STATE; + } + + if (!h->encoder.vt->stop) { + return ESP_ERR_NOT_SUPPORTED; + } + + return h->encoder.vt->stop(&h->encoder); +} + +esp_err_t esp_trace_flush(void) +{ + esp_trace_handle_t h = s_active_handle; + if (!h) { + return ESP_ERR_INVALID_STATE; + } + + if (!h->encoder.vt->flush) { + return ESP_ERR_NOT_SUPPORTED; + } + + return h->encoder.vt->flush(&h->encoder); +} + bool esp_trace_is_host_connected(esp_trace_handle_t h) { if (!h || !h->transport.vt || !h->transport.vt->is_host_connected) {