Merge branch 'tracing_test_fixes_v6.0' into 'release/v6.0'

Tracing test fixes (v6.0)

See merge request espressif/esp-idf!52328
This commit is contained in:
Alexey Gerenkov
2026-09-08 18:43:46 +08:00
97 changed files with 365 additions and 275 deletions

View File

@@ -47,7 +47,6 @@ menu "Application Level Tracing"
config APPTRACE_UART_TX_GPIO
int "UART TX on GPIO<num>"
depends on APPTRACE_DEST_UART
range 0 46
default 12
help
This GPIO is used for UART TX pin.
@@ -55,7 +54,6 @@ menu "Application Level Tracing"
config APPTRACE_UART_RX_GPIO
int "UART RX on GPIO<num>"
depends on APPTRACE_DEST_UART
range 0 46
default 13
help
This GPIO is used for UART RX pin.

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*/
@@ -75,7 +75,7 @@ static esp_err_t esp_apptrace_membufs_swap(esp_apptrace_membufs_proto_data_t *pr
esp_err_t res = proto->hw->swap_start(proto->state.in_block);
if (res != ESP_OK) {
ESP_APPTRACE_LOGE("Failed to swap to new block: %d", res);
ESP_APPTRACE_LOGV("Failed to swap to new block: %s", esp_err_to_name(res));
return res;
}
@@ -100,7 +100,7 @@ static esp_err_t esp_apptrace_membufs_swap(esp_apptrace_membufs_proto_data_t *pr
*(p - 8), *(p - 7), *(p - 6), *(p - 5), *(p - 4), *(p - 3), *(p - 2), *(p - 1));
uint32_t sz = esp_apptrace_membufs_down_buffer_write_nolock(proto, (uint8_t *)(hdr + 1), hdr->block_sz);
if (sz != hdr->block_sz) {
ESP_APPTRACE_LOGE("Failed to write %" PRIu32 " bytes to down buffer (%" PRIu16 " %" PRIu32 ")!",
ESP_APPTRACE_LOGE("Failed to write %" PRIu32 " bytes to down buffer (%" PRIu32 " %" PRIu32 ")!",
hdr->block_sz - sz, hdr->block_sz, sz);
}
hdr->block_sz = 0;
@@ -149,20 +149,18 @@ uint8_t *esp_apptrace_membufs_down_buffer_get(esp_apptrace_membufs_proto_data_t
}
break;
}
// may need to flush
// may need to flush to expose host down-channel data
if (proto->hw->host_data_pending()) {
ESP_APPTRACE_LOGD("force flush");
int res = esp_apptrace_membufs_swap_waitus(proto, tmo);
if (res != ESP_OK) {
ESP_APPTRACE_LOGE("Failed to switch to another block to recv data from host!");
/*do not return error because data can be in down buffer already*/
}
} else {
// check tmo only if there is no data from host
int res = esp_apptrace_tmo_check(tmo);
if (res != ESP_OK) {
return NULL;
if (res == ESP_OK) {
continue; /* re-check rb_down */
}
ESP_APPTRACE_LOGE("Failed to switch to another block to recv data from host!");
}
/* Check the timeout even while host data is pending so a zero timeout returns immediately instead of spinning. */
if (esp_apptrace_tmo_check(tmo) != ESP_OK) {
return NULL;
}
}
return ptr;

View File

@@ -343,7 +343,7 @@ void esp_panic_handler(panic_info_t *info)
// then only print up to details. Users should be able to probe for the other information
// in debug mode.
#if CONFIG_ESP_DEBUG_OCDAWARE
if (esp_cpu_dbgr_is_attached()) {
if (esp_cpu_dbgr_is_attached() && g_panic_entry_count[esp_cpu_get_core_id()] <= 1) {
char *panic_reason_str = NULL;
if (info->pseudo_excause) {
panic_reason_str = (char *)info->reason;

View File

@@ -76,12 +76,13 @@ menu "ESP Trace Configuration"
config ESP_TRACE_USJ_TX_BUFFER_SIZE
int "TX buffer size"
default 2048
range 256 32768
range 2048 32768
help
Size of the TX ring buffer for USB Serial JTAG trace transport.
Larger buffer allows more trace data to be queued before blocking.
Note: Buffer size must be a power of 2.
Note: Buffer size must be a power of 2. Minimum is 2048 since
smaller buffers overflow easily on the USJ transport.
endmenu

View File

@@ -420,7 +420,7 @@ For detailed usage instructions, see:
## Examples
Examples demonstrating trace usage can be found in:
- `examples/system/app_trace_basic/` - Basic application tracing
- `examples/system/sysview_tracing/` - SystemView tracing example
- `examples/system/esp_trace_custom_library/` - Minimal template for integrating an external trace library (encoder + FreeRTOS hooks + vtable lock)
- `examples/system/sysview_tracing_heap_log/` - SystemView heap and log tracing example
- `examples/system/tracing/app_trace_basic/` - Basic application tracing
- `examples/system/tracing/sysview_tracing/` - SystemView tracing example
- `examples/system/tracing/esp_trace_custom_library/` - Minimal template for integrating an external trace library (encoder + FreeRTOS hooks + vtable lock)
- `examples/system/tracing/sysview_tracing_heap_log/` - SystemView heap and log tracing example

View File

@@ -15,6 +15,8 @@
* is responsible for serializing access using esp_trace_lock_init(), esp_trace_lock_take(),
* and esp_trace_lock_give(). All transport operations (read, write, flush_nolock) are
* invoked while the encoder holds the lock, so no transport-level locking is required.
*
* Logging: use ESP_EARLY_LOGx only, ESP_LOGx is not safe in ISR context.
*/
#include <stdlib.h>
@@ -29,6 +31,7 @@
#include "esp_cpu.h"
#include "esp_attr.h"
#include "esp_rom_caps.h"
#include "esp_rom_sys.h"
#include "esp_heap_caps.h"
#include "esp_private/periph_ctrl.h"
#include "hal/usb_serial_jtag_ll.h"
@@ -51,7 +54,6 @@ static const char *TAG = "usj_transport";
*/
typedef enum {
USJ_TX_IDLE,
USJ_TX_SHORT_PENDING,
USJ_TX_ZLP_PENDING,
} usj_tx_state_t;
@@ -67,11 +69,8 @@ typedef struct {
uint32_t flush_thresh; ///< Flush threshold in bytes
} usj_ctx_t;
/*
* flush_nolock() runs with interrupts masked, so normal flushes use a short
* fixed timeout even if an encoder requests a longer one.
*/
#define USJ_FLUSH_TIMEOUT_US (1000) // 1 ms
/* Default flush timeout, used on non-masked paths (e.g. panic handler). */
#define USJ_FLUSH_TIMEOUT_US (1000000) // 1 s
#define USJ_FLUSH_THRESH_BYTES (0) // 0 bytes
#define USJ_FLUSH_MAX_INTR_MASKED_US (2000) // 2 ms
#define USJ_FLUSH_POLL_STEP_US (100) // delay between no-progress polls
@@ -84,7 +83,7 @@ typedef struct {
static uint32_t usj_write_fifo(usj_ctx_t *ctx, esp_trace_rb_t *rb)
{
if (!usb_serial_jtag_ll_txfifo_writable()) {
/* FIFO is full, no blocking */
/* Previous packet is not sent yet */
return 0;
}
@@ -97,17 +96,21 @@ static uint32_t usj_write_fifo(usj_ctx_t *ctx, esp_trace_rb_t *rb)
uint32_t written = usb_serial_jtag_ll_write_txfifo(ptr, to_send);
esp_trace_rb_consume(rb, written);
ctx->tx_state = usb_serial_jtag_ll_txfifo_writable() ? USJ_TX_SHORT_PENDING : USJ_TX_ZLP_PENDING;
/* Checked before wr_done, which also clears the writable flag */
ctx->tx_state = usb_serial_jtag_ll_txfifo_writable() ? USJ_TX_IDLE : USJ_TX_ZLP_PENDING;
/* Send the packet. A no-op if the HW already flushed a full FIFO. */
usb_serial_jtag_ll_txfifo_flush();
return written;
}
static uint32_t usj_fill_txfifo(usj_ctx_t *ctx, bool commit_short)
static uint32_t usj_fill_txfifo(usj_ctx_t *ctx)
{
esp_trace_rb_t *rb = &ctx->tx_ring;
uint32_t total_written = 0;
while (esp_trace_rb_data_len(rb) > 0 && usb_serial_jtag_ll_txfifo_writable()) {
while (esp_trace_rb_data_len(rb) > 0) {
uint32_t written = usj_write_fifo(ctx, rb);
if (written == 0) {
break;
@@ -115,11 +118,6 @@ static uint32_t usj_fill_txfifo(usj_ctx_t *ctx, bool commit_short)
total_written += written;
}
if (commit_short && ctx->tx_state == USJ_TX_SHORT_PENDING) {
usb_serial_jtag_ll_txfifo_flush();
ctx->tx_state = USJ_TX_IDLE;
}
return total_written;
}
@@ -127,7 +125,15 @@ static void usj_read_rx_fifo(usj_ctx_t *ctx)
{
uint8_t tmp[USJ_HW_FIFO_SIZE];
while (usb_serial_jtag_ll_rxfifo_data_available()) {
uint32_t n = usb_serial_jtag_ll_read_rxfifo(tmp, sizeof(tmp));
/* Read only what fits, the rest stays in the HW FIFO */
uint32_t space = esp_trace_rb_free_len(&ctx->rx_ring);
if (space == 0) {
break;
}
if (space > sizeof(tmp)) {
space = sizeof(tmp);
}
uint32_t n = usb_serial_jtag_ll_read_rxfifo(tmp, space);
if (n == 0) {
break;
}
@@ -185,22 +191,23 @@ static esp_err_t usj_init(esp_trace_transport_t *tp, const void *tp_cfg)
/* Initialize TX ring buffer */
esp_err_t ret = esp_trace_rb_init(&ctx->tx_ring, CONFIG_ESP_TRACE_USJ_TX_BUFFER_SIZE);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to initialize TX ring buffer");
ESP_EARLY_LOGE(TAG, "Failed to initialize TX ring buffer");
goto err_ctx;
}
/* Initialize RX ring buffer to capture host commands */
ret = esp_trace_rb_init(&ctx->rx_ring, USJ_RX_BUFFER_SIZE);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to initialize RX ring buffer");
ESP_EARLY_LOGE(TAG, "Failed to initialize RX ring buffer");
goto err_tx_ring;
}
#if ESP_ROM_HAS_ETS_PRINTF_BUG
/* Make sure no printf output is sent to USB-Serial-JTAG */
#if ESP_ROM_HAS_ETS_PRINTF_BUG
extern bool g_usb_print;
g_usb_print = false;
#endif
esp_rom_install_channel_putc(2, NULL);
}
@@ -267,13 +274,15 @@ static esp_err_t usj_write(esp_trace_transport_t *tp, const void *data, size_t s
/* Read any new RX data into the RX ring buffer to avoid losing host commands in case of heavy trace output */
usj_read_rx_fifo(ctx);
/* Add data to TX ring buffer */
esp_trace_rb_put(rb, (const uint8_t *)data, size);
esp_err_t ret = esp_trace_rb_put(rb, (const uint8_t *)data, size);
if (ret != ESP_OK) {
/* Free what the HW can take, then retry before dropping the record */
usj_fill_txfifo(ctx);
ret = esp_trace_rb_put(rb, (const uint8_t *)data, size);
}
usj_fill_txfifo(ctx);
/* Try to move data to HW FIFO immediately, without forcing a short packet. */
usj_fill_txfifo(ctx, false);
return ESP_OK;
return ret;
}
static esp_err_t usj_down_buffer_config(esp_trace_transport_t *tp, uint8_t *buf, uint32_t size)
@@ -292,7 +301,7 @@ static esp_err_t usj_flush_with_timeout(usj_ctx_t *ctx, uint32_t tmo_us)
esp_trace_rb_t *rb = &ctx->tx_ring;
uint32_t pending = esp_trace_rb_data_len(rb);
if (pending < ctx->flush_thresh && ctx->tx_state == USJ_TX_IDLE) {
if ((pending == 0 || pending < ctx->flush_thresh) && ctx->tx_state == USJ_TX_IDLE) {
return ESP_OK;
}
@@ -300,9 +309,11 @@ static esp_err_t usj_flush_with_timeout(usj_ctx_t *ctx, uint32_t tmo_us)
esp_trace_tmo_init(&timeout, tmo_us);
while (esp_trace_rb_data_len(rb) > 0 || ctx->tx_state != USJ_TX_IDLE) {
uint32_t written = usj_fill_txfifo(ctx, true);
uint32_t written = usj_fill_txfifo(ctx);
if (ctx->tx_state == USJ_TX_ZLP_PENDING && usb_serial_jtag_ll_txfifo_writable()) {
/* Ring is empty: send a ZLP if the last packet filled the endpoint */
if (esp_trace_rb_data_len(rb) == 0 && ctx->tx_state == USJ_TX_ZLP_PENDING
&& usb_serial_jtag_ll_txfifo_writable()) {
usb_serial_jtag_ll_txfifo_flush();
ctx->tx_state = USJ_TX_IDLE;
continue;
@@ -363,7 +374,7 @@ static esp_err_t usj_set_config(esp_trace_transport_t *tp, esp_trace_transport_c
ctx->flush_thresh = *(const uint32_t *)value;
return ESP_OK;
default:
ESP_LOGE(TAG, "Key %d is not supported", key);
ESP_EARLY_LOGE(TAG, "Key %d is not supported", key);
return ESP_ERR_NOT_SUPPORTED;
}
}
@@ -387,7 +398,7 @@ static esp_err_t usj_get_config(esp_trace_transport_t *tp, esp_trace_transport_c
*(uint32_t *)value = ctx->flush_thresh;
return ESP_OK;
default:
ESP_LOGE(TAG, "Key %d is not supported", key);
ESP_EARLY_LOGE(TAG, "Key %d is not supported", key);
return ESP_ERR_NOT_SUPPORTED;
}
}

View File

@@ -157,12 +157,22 @@ static inline uint32_t esp_trace_rb_data_len(const esp_trace_rb_t *rb)
}
/**
* @brief Write data into the ring buffer (overwrites oldest data if full)
* @brief Get number of bytes that can still be written to the ring buffer
*/
static inline uint32_t esp_trace_rb_free_len(const esp_trace_rb_t *rb)
{
return rb->max_size - rb->count;
}
/**
* @brief Write data into the ring buffer, all of it or none
*
* Data already in the buffer is never overwritten.
*
* @param rb Ring buffer
* @param data Source data
* @param len Number of bytes to write
* @return ESP_OK always (data is always accepted; oldest data may be dropped)
* @return ESP_OK on success, ESP_ERR_NO_MEM if the data does not fit
*/
esp_err_t esp_trace_rb_put(esp_trace_rb_t *rb, const uint8_t *data, uint32_t len);

View File

@@ -195,10 +195,10 @@ esp_err_t esp_trace_rb_init(esp_trace_rb_t *rb, uint32_t size)
esp_err_t esp_trace_rb_put(esp_trace_rb_t *rb, const uint8_t *data, uint32_t len)
{
/* Drop oldest data if needed to make room */
uint32_t free_len = rb->max_size - rb->count;
if (len > free_len) {
rb_advance_tail(rb, len - free_len);
/* Drop the new record instead of overwriting old ones, so that the records
* in the buffer stay complete */
if (len > rb->max_size - rb->count) {
return ESP_ERR_NO_MEM;
}
uint32_t head = rb->head;

View File

@@ -272,6 +272,14 @@ class OpenOCD:
resp += self.telnet.read_until(b'>')
return to_str(resp)
def consume_output(self, duration: float) -> None:
if self.telnet is None:
return
end = time.time() + duration
while time.time() < end:
self.telnet.read_very_eager()
time.sleep(0.05)
def apptrace_wait_stop(self, timeout: int = 30) -> None:
stopped = False
end_before = time.time() + timeout

View File

@@ -69,4 +69,4 @@ To capture FreeRTOS events, the external component implementing a trace encoder
Application Example
-------------------
- :example:`system/esp_trace_custom_library` is a minimal template that wires up an external encoder, demonstrates the FreeRTOS trace-hook include chain, and shows cross-core serialization through the encoder lock.
- :example:`system/tracing/esp_trace_custom_library` is a minimal template that wires up an external encoder, demonstrates the FreeRTOS trace-hook include chain, and shows cross-core serialization through the encoder lock.

View File

@@ -23,4 +23,4 @@ Coverage data can be dumped either at a hard-coded point in your application (ov
Application Example
-------------------
- :example:`system/gcov` demonstrates how to add code coverage to a project and collect coverage data over JTAG.
- :example:`system/tracing/gcov` demonstrates how to add code coverage to a project and collect coverage data over JTAG.

View File

@@ -101,8 +101,8 @@ Related Documentation
Examples
--------
- :example:`system/app_trace_basic`: Basic application tracing
- :example:`system/sysview_tracing`: SystemView tracing example
- :example:`system/sysview_tracing_heap_log`: Heap tracing with SystemView
- :example:`system/gcov`: Source code coverage over JTAG
- :example:`system/esp_trace_custom_library`: External trace library integration template
- :example:`system/tracing/app_trace_basic`: Basic application tracing
- :example:`system/tracing/sysview_tracing`: SystemView tracing example
- :example:`system/tracing/sysview_tracing_heap_log`: Heap tracing with SystemView
- :example:`system/tracing/gcov`: Source code coverage over JTAG
- :example:`system/tracing/esp_trace_custom_library`: External trace library integration template

View File

@@ -136,5 +136,5 @@ Good instructions on how to install, configure, and visualize data in Impulse fr
Application Examples
--------------------
- :example:`system/sysview_tracing` demonstrates how to trace FreeRTOS task and system events using SEGGER SystemView.
- :example:`system/sysview_tracing_heap_log` demonstrates heap allocation tracing alongside SystemView events.
- :example:`system/tracing/sysview_tracing` demonstrates how to trace FreeRTOS task and system events using SEGGER SystemView.
- :example:`system/tracing/sysview_tracing_heap_log` demonstrates heap allocation tracing alongside SystemView events.

View File

@@ -396,8 +396,8 @@ Optional arguments:
Application Examples
--------------------
- :example:`system/app_trace_basic` demonstrates how to use the Application Level Tracing Library to log messages to a host via JTAG, providing a faster alternative to UART logs.
- :example:`system/app_trace_to_plot` demonstrates how to send and plot dummy sensor data to a host via JTAG.
- :example:`system/tracing/app_trace_basic` demonstrates how to use the Application Level Tracing Library to log messages to a host via JTAG, providing a faster alternative to UART logs.
- :example:`system/tracing/app_trace_to_plot` demonstrates how to send and plot dummy sensor data to a host via JTAG.
API Reference
-------------

View File

@@ -17,9 +17,9 @@ Developers can use this library to send application specific state of execution
Application Examples
--------------------
- :example:`system/app_trace_to_plot` demonstrates how to use the Application Level Tracing Library to send and plot dummy sensor data to a host via JTAG, providing a faster alternative to logging via UART.
- :example:`system/tracing/app_trace_to_plot` demonstrates how to use the Application Level Tracing Library to send and plot dummy sensor data to a host via JTAG, providing a faster alternative to logging via UART.
- :example:`system/app_trace_basic` demonstrates how to use the Application Level Tracing Library to log messages to a host via JTAG, providing a faster alternative to UART logs.
- :example:`system/tracing/app_trace_basic` demonstrates how to use the Application Level Tracing Library to log messages to a host via JTAG, providing a faster alternative to UART logs.
API Reference
-------------

View File

@@ -13,7 +13,7 @@ For a conceptual overview, architecture, and usage guides, see :doc:`/api-guides
Application Examples
--------------------
- :example:`system/esp_trace_custom_library` demonstrates how to integrate an external trace library (encoder) with the ``esp_trace`` core.
- :example:`system/tracing/esp_trace_custom_library` demonstrates how to integrate an external trace library (encoder) with the ``esp_trace`` core.
API Reference
-------------

View File

@@ -653,15 +653,15 @@ The output from the heap trace has a similar format to the following example:
Stop parsing trace. (Timeout 0.000000 sec while reading 1 bytes!)
Process events from '['/tmp/heap.svdat']'...
[0.002244575] HEAP: Allocated 1 bytes @ 0x3ffaffd8 from task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.002258425] HEAP: Allocated 2 bytes @ 0x3ffaffe0 from task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:48
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:48
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.002563725] HEAP: Freed bytes @ 0x3ffaffe0 from task "free" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:31 (discriminator 9)
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:31 (discriminator 9)
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.002782950] HEAP: Freed bytes @ 0x3ffb40b8 from task "main" on core 0 by:
@@ -673,39 +673,39 @@ The output from the heap trace has a similar format to the following example:
/home/user/projects/esp/esp-idf/components/freertos/tasks.c:4590
[0.102436025] HEAP: Allocated 2 bytes @ 0x3ffaffe0 from task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.102449800] HEAP: Allocated 4 bytes @ 0x3ffaffe8 from task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:48
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:48
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.102666150] HEAP: Freed bytes @ 0x3ffaffe8 from task "free" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:31 (discriminator 9)
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:31 (discriminator 9)
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.202436200] HEAP: Allocated 3 bytes @ 0x3ffaffe8 from task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.202451725] HEAP: Allocated 6 bytes @ 0x3ffafff0 from task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:48
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:48
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.202667075] HEAP: Freed bytes @ 0x3ffafff0 from task "free" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:31 (discriminator 9)
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:31 (discriminator 9)
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.302436000] HEAP: Allocated 4 bytes @ 0x3ffafff0 from task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.302451475] HEAP: Allocated 8 bytes @ 0x3ffb40b8 from task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:48
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:48
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.302667500] HEAP: Freed bytes @ 0x3ffb40b8 from task "free" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:31 (discriminator 9)
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:31 (discriminator 9)
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
Processing completed.
@@ -717,19 +717,19 @@ The output from the heap trace has a similar format to the following example:
Processed 14 heap events.
[0.002244575] HEAP: Allocated 1 bytes @ 0x3ffaffd8 from task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.102436025] HEAP: Allocated 2 bytes @ 0x3ffaffe0 from task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.202436200] HEAP: Allocated 3 bytes @ 0x3ffaffe8 from task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.302436000] HEAP: Allocated 4 bytes @ 0x3ffafff0 from task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
Found 10 leaked bytes in 4 blocks.

View File

@@ -69,4 +69,4 @@ FreeRTOS 跟踪钩子
应用示例
--------
- :example:`system/esp_trace_custom_library` 是一个最简模板,演示如何接入外部编码器、说明 FreeRTOS 跟踪钩子头文件的包含链,以及通过编码器锁实现多核序列化。
- :example:`system/tracing/esp_trace_custom_library` 是一个最简模板,演示如何接入外部编码器、说明 FreeRTOS 跟踪钩子头文件的包含链,以及通过编码器锁实现多核序列化。

View File

@@ -23,4 +23,4 @@ Gcov 使用跟踪基础设施进行主机数据传输,但尚未完全遵循 :d
应用示例
--------
- :example:`system/gcov` 演示如何为项目添加代码覆盖率,并通过 JTAG 收集覆盖率数据。
- :example:`system/tracing/gcov` 演示如何为项目添加代码覆盖率,并通过 JTAG 收集覆盖率数据。

View File

@@ -101,8 +101,8 @@ ESP-IDF 提供了一套跟踪系统,用于程序行为分析和调试。以较
示例
----
- :example:`system/app_trace_basic`:基础应用程序跟踪
- :example:`system/sysview_tracing`SystemView 跟踪示例
- :example:`system/sysview_tracing_heap_log`:基于 SystemView 的堆跟踪
- :example:`system/gcov`:通过 JTAG 获取源代码覆盖率
- :example:`system/esp_trace_custom_library`:外部跟踪库集成模板
- :example:`system/tracing/app_trace_basic`:基础应用程序跟踪
- :example:`system/tracing/sysview_tracing`SystemView 跟踪示例
- :example:`system/tracing/sysview_tracing_heap_log`:基于 SystemView 的堆跟踪
- :example:`system/tracing/gcov`:通过 JTAG 获取源代码覆盖率
- :example:`system/tracing/esp_trace_custom_library`:外部跟踪库集成模板

View File

@@ -136,5 +136,5 @@ Start 子命令语法:
应用示例
--------
- :example:`system/sysview_tracing` 演示如何使用 SEGGER SystemView 记录 FreeRTOS 任务与系统事件。
- :example:`system/sysview_tracing_heap_log` 演示如何在记录 SystemView 事件的同时,对堆内存分配进行跟踪。
- :example:`system/tracing/sysview_tracing` 演示如何使用 SEGGER SystemView 记录 FreeRTOS 任务与系统事件。
- :example:`system/tracing/sysview_tracing_heap_log` 演示如何在记录 SystemView 事件的同时,对堆内存分配进行跟踪。

View File

@@ -396,8 +396,8 @@ Log Trace Processor 命令选项
应用示例
--------
- :example:`system/app_trace_basic` 演示如何使用应用层跟踪库通过 JTAG 将日志消息记录到主机,作为 UART 日志的更快替代方案。
- :example:`system/app_trace_to_plot` 演示如何通过 JTAG 向主机发送并绘制虚拟传感器数据。
- :example:`system/tracing/app_trace_basic` 演示如何使用应用层跟踪库通过 JTAG 将日志消息记录到主机,作为 UART 日志的更快替代方案。
- :example:`system/tracing/app_trace_to_plot` 演示如何通过 JTAG 向主机发送并绘制虚拟传感器数据。
API 参考
--------

View File

@@ -17,9 +17,9 @@ ESP-IDF 支持用于程序行为分析的 **应用级追踪** 功能。在 menuc
应用示例
---------------
- :example:`system/app_trace_to_plot` 演示了如何使用应用层跟踪库通过 JTAG 发送并绘制虚拟传感器数据到主机上,提供了比通过 UART 记录更快的替代方案。
- :example:`system/tracing/app_trace_to_plot` 演示了如何使用应用层跟踪库通过 JTAG 发送并绘制虚拟传感器数据到主机上,提供了比通过 UART 记录更快的替代方案。
- :example:`system/app_trace_basic` 演示了如何使用应用层跟踪库通过 JTAG 向主机记录消息,提供了比 UART 记录更快的替代方案。
- :example:`system/tracing/app_trace_basic` 演示了如何使用应用层跟踪库通过 JTAG 向主机记录消息,提供了比 UART 记录更快的替代方案。
API 参考
-------------

View File

@@ -13,7 +13,7 @@ ESP Trace
应用示例
--------
- :example:`system/esp_trace_custom_library` 演示如何将外部跟踪库(编码器)与 ``esp_trace`` 核心集成。
- :example:`system/tracing/esp_trace_custom_library` 演示如何将外部跟踪库(编码器)与 ``esp_trace`` 核心集成。
API 参考
--------

View File

@@ -653,15 +653,15 @@ ESP-IDF 集成了用于请求 :ref:`堆内存信息 <heap-information>`、:ref:`
Stop parsing trace. (Timeout 0.000000 sec while reading 1 byte!)
Process events from '['/tmp/heap.svdat']'...
[0.002244575] HEAP: Allocated 1 byte @ 0x3ffaffd8 from task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.002258425] HEAP: Allocated 2 bytes @ 0x3ffaffe0 from task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:48
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:48
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.002563725] HEAP: Freed bytes @ 0x3ffaffe0 from the task "free" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:31 (discriminator 9)
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:31 (discriminator 9)
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.002782950] HEAP: Freed bytes @ 0x3ffb40b8 from the task "main" on core 0 by:
@@ -673,39 +673,39 @@ ESP-IDF 集成了用于请求 :ref:`堆内存信息 <heap-information>`、:ref:`
/home/user/projects/esp/esp-idf/components/freertos/tasks.c:4590
[0.102436025] HEAP: Allocated 2 bytes @ 0x3ffaffe0 from the task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.102449800] HEAP: Allocated 4 bytes @ 0x3ffaffe8 from the task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:48
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:48
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.102666150] HEAP: Freed bytes @ 0x3ffaffe8 from the task "free" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:31 (discriminator 9)
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:31 (discriminator 9)
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.202436200] HEAP: Allocated 3 bytes @ 0x3ffaffe8 from the task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.202451725] HEAP: Allocated 6 bytes @ 0x3ffafff0 from the task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:48
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:48
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.202667075] HEAP: Freed bytes @ 0x3ffafff0 from the task "free" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:31 (discriminator 9)
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:31 (discriminator 9)
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.302436000] HEAP: Allocated 4 bytes @ 0x3ffafff0 from the task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.302451475] HEAP: Allocated 8 bytes @ 0x3ffb40b8 from the task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:48
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:48
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.302667500] HEAP: Freed bytes @ 0x3ffb40b8 from the task "free" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:31 (discriminator 9)
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:31 (discriminator 9)
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
Processing completed.
@@ -717,19 +717,19 @@ ESP-IDF 集成了用于请求 :ref:`堆内存信息 <heap-information>`、:ref:`
Processed 14 heap events.
[0.002244575] HEAP: Allocated 1 bytes @ 0x3ffaffd8 from the task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.102436025] HEAP: Allocated 2 bytes @ 0x3ffaffe0 from the task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.202436200] HEAP: Allocated 3 bytes @ 0x3ffaffe8 from the task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
[0.302436000] HEAP: Allocated 4 bytes @ 0x3ffafff0 from the task "alloc" on core 0 by:
/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/examples/system/tracing/sysview_tracing_heap_log/main/sysview_heap_log.c:47
/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
Found 10 leaked bytes in 4 blocks.

View File

@@ -1,17 +1,5 @@
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
examples/system/app_trace_basic:
disable_test:
- if: IDF_TARGET == "esp32h21"
temporary: true
reason: not supported yet #TODO: OCD-1081
- if: IDF_TARGET == "esp32h4"
temporary: true
reason: not supported yet #TODO: OCD-1137
depends_components:
- esp_trace
- app_trace
examples/system/base_mac_address:
depends_components:
- *common_components
@@ -68,21 +56,6 @@ examples/system/esp_timer:
- *common_components
- esp_timer
examples/system/esp_trace_custom_library:
disable:
- if: SOC_USB_SERIAL_JTAG_SUPPORTED != 1
reason: example transport is USB Serial JTAG
disable_test:
- if: IDF_TARGET == "esp32h21"
temporary: true
reason: lack of runners
- if: IDF_TARGET == "esp32h4"
temporary: true
reason: lack of runners
depends_components:
- esp_trace
- freertos
examples/system/eventfd:
disable:
- if: SOC_GPTIMER_SUPPORTED != 1 and (IDF_TARGET != "esp32" and (NIGHTLY_RUN != "1" or IDF_TARGET == "linux"))
@@ -116,21 +89,6 @@ examples/system/freertos/real_time_stats:
- *common_components
- freertos
examples/system/gcov:
disable_test:
- if: IDF_TARGET == "esp32h21"
temporary: true
reason: not supported yet #TODO: OCD-1079
- if: IDF_TARGET == "esp32h4"
temporary: true
reason: not supported yet #TODO: OCD-1138
- if: IDF_TARGET == "esp32p4"
temporary: true
reason: p4 rev3 migration # TODO: IDF-14440
depends_components:
- esp_trace
- app_trace
examples/system/heap_task_tracking:
disable:
- if: IDF_TARGET != "esp32c3" and (NIGHTLY_RUN != "1" or IDF_TARGET == "linux")
@@ -299,34 +257,6 @@ examples/system/select:
- *common_components
- vfs
examples/system/sysview_tracing:
disable:
- if: SOC_GPTIMER_SUPPORTED != 1
disable_test:
- if: IDF_TARGET == "esp32h21"
temporary: true
reason: not supported yet #TODO: OCD-1082
- if: IDF_TARGET == "esp32h4"
temporary: true
reason: not supported yet #TODO: OCD-1136
depends_components:
- esp_trace
- app_trace
examples/system/sysview_tracing_heap_log:
disable:
- if: SOC_GPTIMER_SUPPORTED != 1
disable_test:
- if: IDF_TARGET == "esp32h21"
temporary: true
reason: not supported yet #TODO: OCD-1082
- if: IDF_TARGET == "esp32h4"
temporary: true
reason: not supported yet #TODO: OCD-1136
depends_components:
- esp_trace
- app_trace
examples/system/task_watchdog:
disable:
- if: IDF_TARGET != "esp32" and (NIGHTLY_RUN != "1" or IDF_TARGET == "linux")

View File

@@ -1,8 +0,0 @@
#include <stdio.h>
void blink_dummy_func(void)
{
static int i;
printf("blink_dummy_func: Counter = %d\n", i++);
}

View File

@@ -0,0 +1,71 @@
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
examples/system/tracing/app_trace_basic:
disable_test:
- if: IDF_TARGET == "esp32h21"
temporary: true
reason: not supported yet #TODO: OCD-1081
- if: IDF_TARGET == "esp32h4"
temporary: true
reason: not supported yet #TODO: OCD-1137
depends_components:
- esp_trace
- app_trace
examples/system/tracing/esp_trace_custom_library:
disable:
- if: SOC_USB_SERIAL_JTAG_SUPPORTED != 1
reason: example transport is USB Serial JTAG
disable_test:
- if: IDF_TARGET == "esp32h21"
temporary: true
reason: lack of runners
- if: IDF_TARGET == "esp32h4"
temporary: true
reason: lack of runners
depends_components:
- esp_trace
- freertos
examples/system/tracing/gcov:
disable_test:
- if: IDF_TARGET == "esp32h21"
temporary: true
reason: not supported yet #TODO: OCD-1079
- if: IDF_TARGET == "esp32h4"
temporary: true
reason: not supported yet #TODO: OCD-1138
- if: IDF_TARGET == "esp32p4"
temporary: true
reason: p4 rev3 migration # TODO: IDF-14440
depends_components:
- esp_trace
- app_trace
examples/system/tracing/sysview_tracing:
disable:
- if: SOC_GPTIMER_SUPPORTED != 1
disable_test:
- if: IDF_TARGET == "esp32h21"
temporary: true
reason: not supported yet #TODO: OCD-1082
- if: IDF_TARGET == "esp32h4"
temporary: true
reason: not supported yet #TODO: OCD-1136
depends_components:
- esp_trace
- app_trace
examples/system/tracing/sysview_tracing_heap_log:
disable:
- if: SOC_GPTIMER_SUPPORTED != 1
disable_test:
- if: IDF_TARGET == "esp32h21"
temporary: true
reason: not supported yet #TODO: OCD-1082
- if: IDF_TARGET == "esp32h4"
temporary: true
reason: not supported yet #TODO: OCD-1136
depends_components:
- esp_trace
- app_trace

View File

@@ -23,7 +23,7 @@ This example will assume that an ESP-WROVER-KIT is used.
1. Connect the JTAG interface to the target board. For details about how to set up JTAG interface, please see [JTAG Debugging](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/jtag-debugging/index.html). Power up both the JTAG debugger and target board.
2. To start the tcp socket server, you need to run `read_trace.py` tool under the `esp-idf/examples/system/app_trace_to_plot` path.
2. To start the tcp socket server, you need to run `read_trace.py` tool under the `esp-idf/examples/system/tracing/app_trace_to_plot` path.
3. After connecting JTAG interface and starting the tcp socket server, you need to [Run OpenOCD](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/jtag-debugging/index.html#run-openocd).
@@ -46,7 +46,7 @@ idf.py -p PORT flash monitor
(Replace PORT with the name of the serial port to use.)
**Run Plotting Tool** To plot data and open TCP socket, there is a tool named `read_trace.py` under the `examples/system/app_trace_to_plot` path. Run this tool in the terminal session with configured IDF development environment by entering the command below. This command opens a TCP socket and plots the given data when OpenOCD triggered to start App Trace. If you are running tool at first time, you need to install dash with `pip install dash` in the same terminal session after running configuring IDF development environment.
**Run Plotting Tool** To plot data and open TCP socket, there is a tool named `read_trace.py` under the `examples/system/tracing/app_trace_to_plot` path. Run this tool in the terminal session with configured IDF development environment by entering the command below. This command opens a TCP socket and plots the given data when OpenOCD triggered to start App Trace. If you are running tool at first time, you need to install dash with `pip install dash` in the same terminal session after running configuring IDF development environment.
```bash
python read_trace.py --plot-config data.json --source tcp://localhost:53535 --output-file data.log

View File

@@ -1,7 +1,7 @@
{
"//data.json": "Apptrace plotting config file for 'read_trace.py'",
"//Summary and usage": "This file is used for apptrace plotting. You can use this json file with '--plot-config' parameter of the 'read_trace.py' file is to configure graphs for visualizing sensor data",
"//More information": "To get more information about apptrace plotting and configuration file, please check 'app_trace_to_plot' example in '../examples/system' and 'read_trace.py' file",
"//More information": "To get more information about apptrace plotting and configuration file, please check 'app_trace_to_plot' example in '../examples/system/tracing' and 'read_trace.py' file",
"Temperature sensors": {
"data_streams" : {
"Outside temperature": {
@@ -27,7 +27,7 @@
}
},
"xaxis_title": "Timestamp",
"yaxis_title": "Temperature in Celcius"
"yaxis_title": "Temperature in Celsius"
},
"Altitude sensors": {
"data_streams" : {

View File

Before

Width:  |  Height:  |  Size: 787 KiB

After

Width:  |  Height:  |  Size: 787 KiB

View File

@@ -3,7 +3,7 @@
# ESP Trace External Library Integration Example
This example shows the **minimal** set of files and configuration needed to plug a third-party trace library into the [`esp_trace`](../../../components/esp_trace) component using the public `CONFIG_ESP_TRACE_LIB_EXTERNAL` extension point. It is meant as a copy-paste starting point for vendors and users who want to integrate their own trace recorder (e.g. Percepio TraceRecorder, a custom CTF emitter, a printf-style logger, …) without patching ESP-IDF itself.
This example shows the **minimal** set of files and configuration needed to plug a third-party trace library into the [`esp_trace`](../../../../components/esp_trace) component using the public `CONFIG_ESP_TRACE_LIB_EXTERNAL` extension point. It is meant as a copy-paste starting point for vendors and users who want to integrate their own trace recorder (e.g. Percepio TraceRecorder, a custom CTF emitter, a printf-style logger, …) without patching ESP-IDF itself.
The example covers:
@@ -94,7 +94,7 @@ esp_trace_custom_library/
### 2. Providing the FreeRTOS trace hooks
`esp_trace`'s public header [`esp_trace_freertos.h`](../../../components/esp_trace/include/esp_trace_freertos.h) is included from `FreeRTOSConfig.h`. When `CONFIG_ESP_TRACE_LIB_EXTERNAL=y` is set, it pulls in **your** `esp_trace_freertos_impl.h`:
`esp_trace`'s public header [`esp_trace_freertos.h`](../../../../components/esp_trace/include/esp_trace_freertos.h) is included from `FreeRTOSConfig.h`. When `CONFIG_ESP_TRACE_LIB_EXTERNAL=y` is set, it pulls in **your** `esp_trace_freertos_impl.h`:
```c
#if CONFIG_ESP_TRACE_LIB_EXTERNAL
@@ -177,7 +177,7 @@ Because the transport is USB-Serial-JTAG and the console is on UART (`CONFIG_ESP
## Runtime Control — `esp_trace_start` / `_stop` / `_flush`
[`esp_trace.h`](../../../components/esp_trace/include/esp_trace.h) exposes three generic lifecycle calls that dispatch to the active encoder's vtable. The application uses only the public API — it never reaches into the external library:
[`esp_trace.h`](../../../../components/esp_trace/include/esp_trace.h) exposes three generic lifecycle calls that dispatch to the active encoder's vtable. The application uses only the public API — it never reaches into the external library:
```c
esp_trace_start(); // resume emission (also resets the delta baseline)
@@ -194,7 +194,7 @@ In this example the library boots with `s_enabled = false`, so nothing is emitte
## Other `esp_trace` Helpers
Beyond what this example uses, [`esp_trace.h`](../../../components/esp_trace/include/esp_trace.h) and [`esp_trace_util.h`](../../../components/esp_trace/include/esp_trace_util.h) also expose:
Beyond what this example uses, [`esp_trace.h`](../../../../components/esp_trace/include/esp_trace.h) and [`esp_trace_util.h`](../../../../components/esp_trace/include/esp_trace_util.h) also expose:
* `esp_trace_is_host_connected()` — gate expensive work when no host is listening.
* `esp_trace_get_link_type()` — returns `ESP_TRACE_LINK_DEBUG_PROBE`, `_UART`, or `_USB_SERIAL_JTAG`.
@@ -203,5 +203,5 @@ Beyond what this example uses, [`esp_trace.h`](../../../components/esp_trace/inc
## See Also
* [`components/esp_trace/README.md`](../../../components/esp_trace/README.md) — full architecture overview and adapter API reference.
* [`components/esp_trace/README.md`](../../../../components/esp_trace/README.md) — full architecture overview and adapter API reference.
* [`examples/system/sysview_tracing`](../sysview_tracing) — a production-grade integration of SEGGER SystemView built on the same extension points.

View File

@@ -36,6 +36,9 @@ void init_trace_lib(esp_trace_encoder_t *enc);
void trace_lib_start(void);
void trace_lib_stop(void);
/* @brief Get the number of trace lines written to and dropped by the transport */
void trace_lib_get_stats(uint32_t *written, uint32_t *dropped);
/* Hook implementations — defined in trace_FreeRTOS.c.
* Kept void*-typed to avoid depending on FreeRTOS types in this header. */
void trace_lib_task_switched_in(void);

View File

@@ -85,14 +85,6 @@ static esp_err_t stop(esp_trace_encoder_t *enc)
return ESP_OK;
}
static esp_err_t flush(esp_trace_encoder_t *enc)
{
if (!enc || !enc->tp || !enc->tp->vt->flush_nolock) {
return ESP_ERR_NOT_SUPPORTED;
}
return enc->tp->vt->flush_nolock(enc->tp);
}
/**
* @brief Panic handler
*
@@ -104,7 +96,11 @@ static esp_err_t flush(esp_trace_encoder_t *enc)
static void panic_handler(esp_trace_encoder_t *enc, const void *info)
{
(void)info;
flush(enc);
/* No lock here, the panicking core may already hold it */
if (enc && enc->tp && enc->tp->vt->flush_nolock) {
enc->tp->vt->flush_nolock(enc->tp);
}
}
static unsigned int take_lock(esp_trace_encoder_t *enc, uint32_t tmo_us)
@@ -127,6 +123,34 @@ static void give_lock(esp_trace_encoder_t *enc, unsigned int int_state)
esp_trace_lock_give(&ctx->lock);
}
/* Total time for the flush, split over several flush_nolock() calls */
#define EXT_TRACE_LIB_FLUSH_TMO_US (1000000)
static esp_err_t flush(esp_trace_encoder_t *enc)
{
if (!enc || !enc->tp || !enc->tp->vt->flush_nolock) {
return ESP_ERR_NOT_SUPPORTED;
}
/* One call may be too short to send all the data, so repeat it and release
* the lock in between to keep interrupts enabled */
esp_trace_tmo_t tmo;
esp_trace_tmo_init(&tmo, EXT_TRACE_LIB_FLUSH_TMO_US);
esp_err_t err;
do {
unsigned int int_state = take_lock(enc, ESP_TRACE_TMO_INFINITE);
err = enc->tp->vt->flush_nolock(enc->tp);
give_lock(enc, int_state);
if (err != ESP_ERR_TIMEOUT) {
break; /* done, or an error that repeating cannot fix */
}
} while (esp_trace_tmo_check(&tmo) == ESP_OK);
return err;
}
static const esp_trace_encoder_vtable_t s_ext_trace_lib_vt = {
.init = init,
.write = write,

View File

@@ -35,6 +35,8 @@ static esp_trace_encoder_t *s_enc = NULL;
static uint32_t s_ts_freq_hz = 1000000; /* default assume 1 MHz */
static uint32_t s_last_ts = 0;
static volatile bool s_enabled = false;
static uint32_t s_written = 0;
static uint32_t s_dropped = 0;
void init_trace_lib(esp_trace_encoder_t *enc)
{
@@ -87,12 +89,26 @@ static void encode(const char *type, const char *detail)
if (n >= (int)sizeof(line)) {
n = (int)sizeof(line) - 1;
}
esp_trace_write(s_esp_trace_handle, line, (size_t)n, 0);
if (esp_trace_write(s_esp_trace_handle, line, (size_t)n, 0) == ESP_OK) {
s_written++;
} else {
s_dropped++; /* transport buffer was full, line dropped */
}
}
s_enc->vt->give_lock(s_enc, int_state);
}
void trace_lib_get_stats(uint32_t *written, uint32_t *dropped)
{
if (written) {
*written = s_written;
}
if (dropped) {
*dropped = s_dropped;
}
}
void trace_lib_task_switched_in(void)
{
TaskHandle_t h = xTaskGetCurrentTaskHandle();

View File

@@ -5,6 +5,7 @@
*/
#include "sdkconfig.h"
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
@@ -13,6 +14,7 @@
#include "freertos/queue.h"
#include "esp_log.h"
#include "esp_trace.h"
#include "trace_FreeRTOS.h"
static const char *TAG = "main";
@@ -70,7 +72,16 @@ void app_main(void)
vTaskDelay(1000 / portTICK_PERIOD_MS);
esp_trace_stop();
esp_trace_flush();
esp_err_t err = esp_trace_flush();
/* Logged from task context, so it goes to the console UART and not to the
* trace port. Shows whether the device sent the trace data or not. */
uint32_t written = 0;
uint32_t dropped = 0;
trace_lib_get_stats(&written, &dropped);
ESP_LOGI(TAG, "Trace flush: %s, host connected: %d, lines written: %" PRIu32 ", dropped: %" PRIu32,
esp_err_to_name(err), (int)esp_trace_is_host_connected(esp_trace_get_active_handle()),
written, dropped);
ESP_LOGI(TAG, "End of trace session");
}

View File

@@ -76,7 +76,6 @@ def _validate_trace_data(trace_log_path: str) -> None:
def _capture_trace(ser: serial.Serial, trace_log_path: str, capture_s: float = 5.0) -> None:
"""Capture trace output from the USB-Serial-JTAG endpoint."""
ser.reset_input_buffer()
with open(trace_log_path, 'w+b') as f:
end_time = time.time() + capture_s
while time.time() < end_time:
@@ -107,10 +106,13 @@ def _capture_trace(ser: serial.Serial, trace_log_path: str, capture_s: float = 5
def test_esp_trace_ext_lib_usj(dut: IdfDut) -> None:
dut.expect('Start of trace session', timeout=5)
time.sleep(1) # wait for USJ port to be ready
# Open the port before the DUT starts tracing
usj_port = '/dev/serial_ports/ttyACM-esp32'
ser = serial.Serial(usj_port, baudrate=1000000, timeout=10)
trace_log_path = os.path.join(dut.logdir, 'ext_trace.log')
time.sleep(1) # Wait for the USJ port to be ready
with serial.Serial(usj_port, baudrate=1000000, timeout=10) as ser:
# Discard data from before this test, the DUT is not tracing yet
ser.reset_input_buffer()
_capture_trace(ser, trace_log_path)
_capture_trace(ser, trace_log_path)
_validate_trace_data(trace_log_path)

View File

@@ -3,4 +3,4 @@ CONFIG_ESP_TRACE_LIB_EXTERNAL=y
CONFIG_ESP_TRACE_TS_SOURCE_ESP_TIMER=y
CONFIG_ESP_CONSOLE_SECONDARY_NONE=y
CONFIG_ESP_TRACE_TRANSPORT_USB_SERIAL_JTAG=y
CONFIG_ESP_TRACE_USJ_TX_BUFFER_SIZE=32768
CONFIG_ESP_TRACE_USJ_TX_BUFFER_SIZE=16384

View File

@@ -1,3 +1,8 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdio.h>

View File

@@ -0,0 +1,13 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdio.h>
void blink_dummy_func(void)
{
static int i;
printf("blink_dummy_func: Counter = %d\n", i++);
}

View File

@@ -1,11 +1,8 @@
/* Blink Example with covergae info
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

View File

@@ -1,11 +1,8 @@
/* Application Trace to Host Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "esp_err.h"
#include "sdkconfig.h"

View File

@@ -16,6 +16,24 @@ if typing.TYPE_CHECKING:
from conftest import OpenOCD
STOP_EVENT_ID = 0x0B # SYSVIEW_EVTID_TRACE_STOP
def _assert_has_stop_record(segment: bytes, label: str) -> None:
"""Assert a SysView data segment ends with a TRACE_STOP record.
A STOP record is the STOP event ID followed by a variable-length timestamp
delta. Walk back over the trailing continuation bytes (0x80 bit set) to find
the event ID, since its offset is not fixed.
"""
size = len(segment)
assert size >= 2, f'{label}: segment too small to contain STOP record'
i = size - 2
while i >= 0 and (segment[i] & 0x80):
i -= 1
assert i >= 0 and segment[i] == STOP_EVENT_ID, f'{label}: does not end with a TRACE_STOP record'
def _validate_trace_data(trace_log: list[str], target: str, is_uart: bool = False) -> None:
"""Validate SysView trace data in log file(s).
@@ -24,23 +42,14 @@ def _validate_trace_data(trace_log: list[str], target: str, is_uart: bool = Fals
target: Target chip name (e.g., 'esp32', 'esp32s3')
is_uart: If True, also validate STOP record at end of file
"""
STOP_EVENT_ID = 0x0B # SYSVIEW_EVTID_TRACE_STOP
for idx, log in enumerate(trace_log):
with open(log, 'rb') as f:
content = f.read()
search_str = f'N=FreeRTOS Application,D={target},C=core{idx},O=FreeRTOS'.encode()
assert search_str in content, f'SysView trace data not found in {log}'
# The file must end with a TRACE_STOP record: the STOP event ID
# followed by a variable-length timestamp delta. Walk back
# over the trailing continuation bytes (0x80 bit set)
# to find the event ID, since its offset is not fixed.
size = len(content)
assert size >= 2, 'Trace file too small to contain STOP record'
i = size - 2
while i >= 0 and (content[i] & 0x80):
i -= 1
assert i >= 0 and content[i] == STOP_EVENT_ID, 'STOP record does not start with STOP eventID'
search_str = f'N=FreeRTOS Application,D={target},C=core{idx},O=FreeRTOS'.encode()
assert search_str in content, f'SysView trace data not found in {log}'
# Each core is captured to its own file; require each to end
# with its own TRACE_STOP record.
_assert_has_stop_record(content, f'core{idx}')
def _capture_sysview_trace(ser: serial.Serial, trace_log_path: str) -> None:
@@ -125,8 +134,9 @@ def _test_sysview_tracing_jtag(openocd_dut: 'OpenOCD', dut: IdfDut) -> None:
dut.expect('example: Created task') # dut has been restarted by gdb since the last dut.expect()
dut_expect_task_event()
# Do a sleep while sysview samples are captured.
time.sleep(3)
# Capture sysview samples and keep reading telnet so OpenOCD's blocking log writes don't stall its
# main loop and leave the 'stop' below unserviced.
openocd.consume_output(3)
openocd.write('esp sysview stop')
openocd.apptrace_wait_stop()
@@ -173,7 +183,7 @@ def test_sysview_tracing_uart(dut: IdfDut) -> None:
def test_sysview_tracing_usj_serial(dut: IdfDut) -> None:
time.sleep(1) # wait for USJ port to be ready
usj_port = '/dev/serial_ports/ttyACM-esp32'
ser = serial.Serial(usj_port, baudrate=1000000, timeout=10)
trace_log = [os.path.join(dut.logdir, 'sys_log_usj.svdat')] # pylint: disable=protected-access
_capture_sysview_trace(ser, trace_log[0])
_validate_trace_data(trace_log, dut.target, is_uart=True)
with serial.Serial(usj_port, baudrate=1000000, timeout=10) as ser:
_capture_sysview_trace(ser, trace_log[0])
_validate_trace_data(trace_log, dut.target, is_uart=True)

View File

@@ -1,3 +1,4 @@
CONFIG_ESP_CONSOLE_SECONDARY_NONE=y
CONFIG_ESP_TRACE_TRANSPORT_USB_SERIAL_JTAG=y
CONFIG_USE_CUSTOM_EVENT_ID=y
CONFIG_ESP_TRACE_USJ_TX_BUFFER_SIZE=16384

View File

@@ -1,11 +1,8 @@
/* Application Trace to Host Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "sdkconfig.h"
#include <inttypes.h>

View File

@@ -845,9 +845,6 @@ examples/system/esp_event/user_event_loops/main/main.c
examples/system/esp_timer/main/esp_timer_example_main.c
examples/system/eventfd/main/eventfd_example.c
examples/system/freertos/real_time_stats/main/real_time_stats_example_main.c
examples/system/gcov/components/sample/some_funcs.c
examples/system/gcov/main/gcov_example_func.c
examples/system/gcov/main/gcov_example_main.c
examples/system/gdbstub/main/gdbstub_main.c
examples/system/himem/main/himem_example_main.c
examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c
@@ -858,8 +855,6 @@ examples/system/ota/simple_ota_example/main/simple_ota_example.c
examples/system/perfmon/main/perfmon_example_main.c
examples/system/select/main/select_example.c
examples/system/startup_time/main/hello_world_main.c
examples/system/sysview_tracing/main/sysview_tracing.c
examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c
examples/system/task_watchdog/main/task_watchdog_example_main.c
examples/system/unit_test/components/testable/include/testable.h
examples/system/unit_test/components/testable/mean.c

View File

@@ -42,10 +42,10 @@ examples/build_system/cmake/idf_as_lib/run.sh
examples/common_components/protocol_examples_tapif_io/make_tap_netif
examples/storage/parttool/parttool_example.py
examples/storage/parttool/parttool_example.sh
examples/system/app_trace_to_plot/read_trace.py
examples/system/ota/otatool/get_running_partition.py
examples/system/ota/otatool/otatool_example.py
examples/system/ota/otatool/otatool_example.sh
examples/system/tracing/app_trace_to_plot/read_trace.py
install.fish
install.sh
tools/activate.py

View File

@@ -5,7 +5,7 @@
Build example `sysview_tracing_heap_log` project.
```
cd $IDF_PATH/examples/system/sysview_tracing_heap_log
cd $IDF_PATH/examples/system/tracing/sysview_tracing_heap_log
idf.py set target esp32
idf.py build
cp build/sysview_tracing_heap_log.elf $IDF_PATH/tools/esp_app_trace/test/sysview/
@@ -18,12 +18,12 @@
Flash the example and run OpenOCD and GDB using the following command in a separate console
```
cd $IDF_PATH/examples/system/sysview_tracing_heap_log
cd $IDF_PATH/examples/system/tracing/sysview_tracing_heap_log
idf.py openocd
```
```
cd $IDF_PATH/examples/system/sysview_tracing_heap_log
cd $IDF_PATH/examples/system/tracing/sysview_tracing_heap_log
xtensa-esp32-elf-gdb -x $IDF_PATH/tools/esp_app_trace/test/sysview/gdbinit build/sysview_tracing_heap_log.elf
```
When program stops at `heap_trace_stop` quit GDB and OpenOCD
@@ -39,12 +39,12 @@
Flash the example and run OpenOCD and GDB using the following command in a separate console
```
cd $IDF_PATH/examples/system/sysview_tracing_heap_log
cd $IDF_PATH/examples/system/tracing/sysview_tracing_heap_log
idf.py openocd
```
```
cd $IDF_PATH/examples/system/sysview_tracing_heap_log
cd $IDF_PATH/examples/system/tracing/sysview_tracing_heap_log
xtensa-esp32-elf-gdb -x $IDF_PATH/tools/esp_app_trace/test/sysview/gdbinit-mcore build/sysview_tracing_heap_log.elf
```
When program stops at `heap_trace_stop` quit GDB and OpenOCD