Merge branch 'test/sysview_uart' into 'master'

test(app_trace): add SystemView UART tracing tests for all targets

Closes IDF-11919, IDF-11920, IDF-11921, DOC-12212, and IDF-7660

See merge request espressif/esp-idf!41552
This commit is contained in:
Erhan Kurubas
2025-08-29 09:37:37 +02:00
29 changed files with 279 additions and 241 deletions

View File

@@ -10,8 +10,7 @@ set(srcs
"host_file_io.c") "host_file_io.c")
if(CONFIG_ESP_DEBUG_STUBS_ENABLE) if(CONFIG_ESP_DEBUG_STUBS_ENABLE)
list(APPEND srcs list(APPEND srcs "debug_stubs.c")
"debug_stubs.c")
endif() endif()
set(include_dirs "include") set(include_dirs "include")
@@ -19,20 +18,21 @@ set(include_dirs "include")
set(priv_include_dirs "private_include" "port/include") set(priv_include_dirs "private_include" "port/include")
if(CONFIG_APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE) if(CONFIG_APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE)
list(APPEND srcs list(APPEND srcs "app_trace_membufs_proto.c")
"app_trace_membufs_proto.c") endif()
if(CONFIG_APPTRACE_DEST_JTAG)
if(CONFIG_IDF_TARGET_ARCH_XTENSA) if(CONFIG_IDF_TARGET_ARCH_XTENSA)
list(APPEND srcs list(APPEND srcs "port/xtensa/port_jtag.c")
"port/xtensa/port.c")
endif() endif()
if(CONFIG_IDF_TARGET_ARCH_RISCV) if(CONFIG_IDF_TARGET_ARCH_RISCV)
list(APPEND srcs list(APPEND srcs "port/riscv/port_jtag.c")
"port/riscv/port.c")
endif() endif()
endif() endif()
list(APPEND srcs
"port/port_uart.c") if(CONFIG_APPTRACE_DEST_UART)
list(APPEND srcs "port/port_uart.c")
endif()
if(CONFIG_APPTRACE_SV_ENABLE) if(CONFIG_APPTRACE_SV_ENABLE)
list(APPEND include_dirs list(APPEND include_dirs

View File

@@ -17,65 +17,43 @@ menu "Application Level Tracing"
endchoice endchoice
config APPTRACE_DEST_UART
bool
config APPTRACE_DEST_UART_NOUSB
bool
choice APPTRACE_DESTINATION2 choice APPTRACE_DESTINATION2
prompt "Data Destination 2" prompt "Data Destination 2"
default APPTRACE_DEST_UART_NONE default APPTRACE_DEST_UART_NONE
help help
Select destination for application trace: UART(XX) or none (to disable). Select destination for application trace: UART or none (to disable).
config APPTRACE_DEST_UART0 config APPTRACE_DEST_UART
bool "UART0" bool "UART"
select APPTRACE_ENABLE select APPTRACE_ENABLE
select APPTRACE_DEST_UART
select APPTRACE_DEST_UART_NOUSB
depends on (ESP_CONSOLE_UART_NUM !=0)
config APPTRACE_DEST_UART1
bool "UART1"
select APPTRACE_ENABLE
select APPTRACE_DEST_UART
select APPTRACE_DEST_UART_NOUSB
depends on (ESP_CONSOLE_UART_NUM !=1)
config APPTRACE_DEST_UART2
bool "UART2"
select APPTRACE_ENABLE
select APPTRACE_DEST_UART
select APPTRACE_DEST_UART_NOUSB
depends on (ESP_CONSOLE_UART_NUM !=2) && (SOC_UART_NUM > 2)
config APPTRACE_DEST_USB_CDC
bool "USB_CDC"
select APPTRACE_ENABLE
select APPTRACE_DEST_UART
depends on !ESP_CONSOLE_USB_CDC && (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3) && !USB_ENABLED
config APPTRACE_DEST_UART_NONE config APPTRACE_DEST_UART_NONE
bool "None" bool "None"
endchoice endchoice
config APPTRACE_DEST_UART_NUM
int "UART port number"
depends on APPTRACE_DEST_UART
range 0 1 if (SOC_UART_NUM <= 2)
range 0 2 if (SOC_UART_NUM <= 3)
range 0 5 if (SOC_UART_NUM <= 6)
default 1
help
UART communication port number for the apptrace destination.
See UART documentation for available port numbers.
config APPTRACE_UART_TX_GPIO config APPTRACE_UART_TX_GPIO
int "UART TX on GPIO<num>" int "UART TX on GPIO<num>"
depends on APPTRACE_DEST_UART_NOUSB depends on APPTRACE_DEST_UART
range 0 46 range 0 46
default 12 if IDF_TARGET_ESP32
default 12 if IDF_TARGET_ESP32C3
default 12 default 12
help help
This GPIO is used for UART TX pin. This GPIO is used for UART TX pin.
config APPTRACE_UART_RX_GPIO config APPTRACE_UART_RX_GPIO
int "UART RX on GPIO<num>" int "UART RX on GPIO<num>"
depends on APPTRACE_DEST_UART_NOUSB depends on APPTRACE_DEST_UART
range 0 46 range 0 46
default 13 if IDF_TARGET_ESP32
default 13 if IDF_TARGET_ESP32C3
default 13 default 13
help help
This GPIO is used for UART RX pin. This GPIO is used for UART RX pin.

View File

@@ -11,16 +11,8 @@
#include "esp_app_trace_port.h" #include "esp_app_trace_port.h"
#include "esp_private/startup_internal.h" #include "esp_private/startup_internal.h"
#ifdef CONFIG_APPTRACE_DEST_UART0 #if CONFIG_ESP_CONSOLE_UART && CONFIG_APPTRACE_DEST_UART && (CONFIG_APPTRACE_DEST_UART_NUM == CONFIG_ESP_CONSOLE_UART_NUM)
#define ESP_APPTRACE_DEST_UART_NUM 0 #error "Application trace UART and console UART cannot use the same port number"
#elif CONFIG_APPTRACE_DEST_UART1
#define ESP_APPTRACE_DEST_UART_NUM 1
#elif CONFIG_APPTRACE_DEST_UART2
#define ESP_APPTRACE_DEST_UART_NUM 2
#elif CONFIG_APPTRACE_DEST_USB_CDC
#define ESP_APPTRACE_DEST_UART_NUM 10
#else
#define ESP_APPTRACE_DEST_UART_NUM 0
#endif #endif
#define ESP_APPTRACE_MAX_VPRINTF_ARGS 256 #define ESP_APPTRACE_MAX_VPRINTF_ARGS 256
@@ -39,24 +31,19 @@ static bool s_inited;
esp_err_t esp_apptrace_init(void) esp_err_t esp_apptrace_init(void)
{ {
int res; __attribute__((unused)) void *hw_data = NULL;
esp_apptrace_hw_t *hw = NULL;
void *hw_data = NULL;
// 'esp_apptrace_init()' is called on every core, so ensure to do main initialization only once // 'esp_apptrace_init()' is called on every core, so ensure to do main initialization only once
if (esp_cpu_get_core_id() == 0) { if (esp_cpu_get_core_id() == 0) {
memset(&s_trace_channels, 0, sizeof(s_trace_channels)); memset(&s_trace_channels, 0, sizeof(s_trace_channels));
hw = esp_apptrace_jtag_hw_get(&hw_data); #if CONFIG_APPTRACE_DEST_JTAG
ESP_APPTRACE_LOGD("HW interface %p", hw); s_trace_channels[ESP_APPTRACE_DEST_JTAG].hw = esp_apptrace_jtag_hw_get(&hw_data);
if (hw != NULL) { s_trace_channels[ESP_APPTRACE_DEST_JTAG].hw_data = hw_data;
s_trace_channels[ESP_APPTRACE_DEST_JTAG].hw = hw; #endif
s_trace_channels[ESP_APPTRACE_DEST_JTAG].hw_data = hw_data; #if CONFIG_APPTRACE_DEST_UART
} s_trace_channels[ESP_APPTRACE_DEST_UART].hw = esp_apptrace_uart_hw_get(CONFIG_APPTRACE_DEST_UART_NUM, &hw_data);
hw = esp_apptrace_uart_hw_get(ESP_APPTRACE_DEST_UART_NUM, &hw_data); s_trace_channels[ESP_APPTRACE_DEST_UART].hw_data = hw_data;
if (hw != NULL) { #endif
s_trace_channels[ESP_APPTRACE_DEST_UART].hw = hw;
s_trace_channels[ESP_APPTRACE_DEST_UART].hw_data = hw_data;
}
s_inited = true; s_inited = true;
} }
@@ -64,7 +51,7 @@ esp_err_t esp_apptrace_init(void)
for (int i = 0; i < sizeof(s_trace_channels) / sizeof(s_trace_channels[0]); i++) { for (int i = 0; i < sizeof(s_trace_channels) / sizeof(s_trace_channels[0]); i++) {
esp_apptrace_channel_t *ch = &s_trace_channels[i]; esp_apptrace_channel_t *ch = &s_trace_channels[i];
if (ch->hw) { if (ch->hw) {
res = ch->hw->init(ch->hw_data); int res = ch->hw->init(ch->hw_data);
if (res != ESP_OK) { if (res != ESP_OK) {
ESP_APPTRACE_LOGE("Failed to init trace channel HW interface (%d)!", res); ESP_APPTRACE_LOGE("Failed to init trace channel HW interface (%d)!", res);
return res; return res;
@@ -441,10 +428,3 @@ bool esp_apptrace_host_is_connected(esp_apptrace_dest_t dest)
return ch->hw->host_is_connected(ch->hw_data); return ch->hw->host_is_connected(ch->hw_data);
} }
#if !CONFIG_APPTRACE_DEST_JTAG
esp_apptrace_hw_t *esp_apptrace_jtag_hw_get(void **data)
{
return NULL;
}
#endif

View File

@@ -2,12 +2,13 @@
archive: libapp_trace.a archive: libapp_trace.a
entries: entries:
app_trace (noflash) app_trace (noflash)
port_uart (noflash)
app_trace_util (noflash) app_trace_util (noflash)
if APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE: if APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE:
app_trace_membufs_proto (noflash) app_trace_membufs_proto (noflash)
if APPTRACE_DEST_JTAG = y: if APPTRACE_DEST_JTAG = y:
port (noflash) port_jtag (noflash)
if APPTRACE_DEST_UART = y:
port_uart (noflash)
if APPTRACE_SV_ENABLE = y: if APPTRACE_SV_ENABLE = y:
SEGGER_SYSVIEW (noflash) SEGGER_SYSVIEW (noflash)
SEGGER_RTT_esp (noflash) SEGGER_RTT_esp (noflash)

View File

@@ -14,8 +14,6 @@
#include "string.h" #include "string.h"
#include "driver/gpio.h" #include "driver/gpio.h"
#define APPTRACE_DEST_UART (CONFIG_APPTRACE_DEST_UART0 | CONFIG_APPTRACE_DEST_UART1 | CONFIG_APPTRACE_DEST_UART2)
#define APP_TRACE_MAX_TX_BUFF_UART CONFIG_APPTRACE_UART_TX_BUFF_SIZE #define APP_TRACE_MAX_TX_BUFF_UART CONFIG_APPTRACE_UART_TX_BUFF_SIZE
#define APP_TRACE_MAX_TX_MSG_UART CONFIG_APPTRACE_UART_TX_MSG_SIZE #define APP_TRACE_MAX_TX_MSG_UART CONFIG_APPTRACE_UART_TX_MSG_SIZE
@@ -42,47 +40,8 @@ typedef struct {
bool circular_buff_overflow; bool circular_buff_overflow;
} esp_apptrace_uart_data_t; } esp_apptrace_uart_data_t;
#if APPTRACE_DEST_UART
static esp_err_t esp_apptrace_uart_init(esp_apptrace_uart_data_t *hw_data);
static esp_err_t esp_apptrace_uart_flush(esp_apptrace_uart_data_t *hw_data, esp_apptrace_tmo_t *tmo);
static esp_err_t esp_apptrace_uart_flush_nolock(esp_apptrace_uart_data_t *hw_data, uint32_t min_sz, esp_apptrace_tmo_t *tmo);
static uint8_t *esp_apptrace_uart_up_buffer_get(esp_apptrace_uart_data_t *hw_data, uint32_t size, esp_apptrace_tmo_t *tmo);
static esp_err_t esp_apptrace_uart_up_buffer_put(esp_apptrace_uart_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo);
static void esp_apptrace_uart_down_buffer_config(esp_apptrace_uart_data_t *hw_data, uint8_t *buf, uint32_t size);
static uint8_t *esp_apptrace_uart_down_buffer_get(esp_apptrace_uart_data_t *hw_data, uint32_t *size, esp_apptrace_tmo_t *tmo);
static esp_err_t esp_apptrace_uart_down_buffer_put(esp_apptrace_uart_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo);
static bool esp_apptrace_uart_host_is_connected(esp_apptrace_uart_data_t *hw_data);
#endif // APPTRACE_DEST_UART
const static char *TAG = "esp_apptrace_uart"; const static char *TAG = "esp_apptrace_uart";
esp_apptrace_hw_t *esp_apptrace_uart_hw_get(int num, void **data)
{
ESP_LOGD(TAG, "esp_apptrace_uart_hw_get - %i", num);
#if APPTRACE_DEST_UART
static esp_apptrace_uart_data_t s_uart_hw_data = {
};
static esp_apptrace_hw_t s_uart_hw = {
.init = (esp_err_t (*)(void *))esp_apptrace_uart_init,
.get_up_buffer = (uint8_t *(*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_uart_up_buffer_get,
.put_up_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_uart_up_buffer_put,
.flush_up_buffer_nolock = (esp_err_t (*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_uart_flush_nolock,
.flush_up_buffer = (esp_err_t (*)(void *, esp_apptrace_tmo_t *))esp_apptrace_uart_flush,
.down_buffer_config = (void (*)(void *, uint8_t *, uint32_t))esp_apptrace_uart_down_buffer_config,
.get_down_buffer = (uint8_t *(*)(void *, uint32_t *, esp_apptrace_tmo_t *))esp_apptrace_uart_down_buffer_get,
.put_down_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_uart_down_buffer_put,
.host_is_connected = (bool (*)(void *))esp_apptrace_uart_host_is_connected,
};
s_uart_hw_data.port_num = num;
*data = &s_uart_hw_data;
return &s_uart_hw;
#else
return NULL;
#endif
}
#if APPTRACE_DEST_UART
static esp_err_t esp_apptrace_uart_lock(esp_apptrace_uart_data_t *hw_data, esp_apptrace_tmo_t *tmo) static esp_err_t esp_apptrace_uart_lock(esp_apptrace_uart_data_t *hw_data, esp_apptrace_tmo_t *tmo)
{ {
#if CONFIG_APPTRACE_LOCK_ENABLE #if CONFIG_APPTRACE_LOCK_ENABLE
@@ -348,4 +307,23 @@ static esp_err_t esp_apptrace_uart_flush(esp_apptrace_uart_data_t *hw_data, esp_
return ESP_OK; return ESP_OK;
} }
#endif // APPTRACE_DEST_UART esp_apptrace_hw_t *esp_apptrace_uart_hw_get(int num, void **data)
{
ESP_LOGD(TAG, "esp_apptrace_uart_hw_get - %i", num);
static esp_apptrace_uart_data_t s_uart_hw_data;
static esp_apptrace_hw_t s_uart_hw = {
.init = (esp_err_t (*)(void *))esp_apptrace_uart_init,
.get_up_buffer = (uint8_t *(*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_uart_up_buffer_get,
.put_up_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_uart_up_buffer_put,
.flush_up_buffer_nolock = (esp_err_t (*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_uart_flush_nolock,
.flush_up_buffer = (esp_err_t (*)(void *, esp_apptrace_tmo_t *))esp_apptrace_uart_flush,
.down_buffer_config = (void (*)(void *, uint8_t *, uint32_t))esp_apptrace_uart_down_buffer_config,
.get_down_buffer = (uint8_t *(*)(void *, uint32_t *, esp_apptrace_tmo_t *))esp_apptrace_uart_down_buffer_get,
.put_down_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_uart_down_buffer_put,
.host_is_connected = (bool (*)(void *))esp_apptrace_uart_host_is_connected,
};
s_uart_hw_data.port_num = num;
*data = &s_uart_hw_data;
return &s_uart_hw;
}

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 OR MIT * SPDX-License-Identifier: Apache-2.0 OR MIT
*/ */
@@ -40,20 +40,6 @@ typedef struct {
#define ESP_APPTRACE_RISCV_INITED(_hw_) ((_hw_)->inited & (1 << 0/*esp_cpu_get_core_id()*/)) #define ESP_APPTRACE_RISCV_INITED(_hw_) ((_hw_)->inited & (1 << 0/*esp_cpu_get_core_id()*/))
static esp_err_t esp_apptrace_riscv_init(esp_apptrace_riscv_data_t *hw_data);
static esp_err_t esp_apptrace_riscv_flush(esp_apptrace_riscv_data_t *hw_data, esp_apptrace_tmo_t *tmo);
static esp_err_t esp_apptrace_riscv_flush_nolock(esp_apptrace_riscv_data_t *hw_data, uint32_t min_sz, esp_apptrace_tmo_t *tmo);
static uint8_t *esp_apptrace_riscv_up_buffer_get(esp_apptrace_riscv_data_t *hw_data, uint32_t size, esp_apptrace_tmo_t *tmo);
static esp_err_t esp_apptrace_riscv_up_buffer_put(esp_apptrace_riscv_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo);
static void esp_apptrace_riscv_down_buffer_config(esp_apptrace_riscv_data_t *hw_data, uint8_t *buf, uint32_t size);
static uint8_t *esp_apptrace_riscv_down_buffer_get(esp_apptrace_riscv_data_t *hw_data, uint32_t *size, esp_apptrace_tmo_t *tmo);
static esp_err_t esp_apptrace_riscv_down_buffer_put(esp_apptrace_riscv_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo);
static bool esp_apptrace_riscv_host_is_connected(esp_apptrace_riscv_data_t *hw_data);
static esp_err_t esp_apptrace_riscv_buffer_swap_start(uint32_t curr_block_id);
static esp_err_t esp_apptrace_riscv_buffer_swap(uint32_t new_block_id, uint32_t prev_block_len);
static esp_err_t esp_apptrace_riscv_buffer_swap_end(uint32_t new_block_id, uint32_t prev_block_len);
static bool esp_apptrace_riscv_host_data_pending(void);
const static char *TAG = "esp_apptrace"; const static char *TAG = "esp_apptrace";
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
@@ -64,38 +50,6 @@ const static char *TAG = "esp_apptrace";
static APPTRACE_DRAM_ATTR esp_apptrace_riscv_ctrl_block_t s_tracing_ctrl[CONFIG_FREERTOS_NUMBER_OF_CORES]; static APPTRACE_DRAM_ATTR esp_apptrace_riscv_ctrl_block_t s_tracing_ctrl[CONFIG_FREERTOS_NUMBER_OF_CORES];
esp_apptrace_hw_t *esp_apptrace_jtag_hw_get(void **data)
{
#if CONFIG_APPTRACE_DEST_JTAG
static esp_apptrace_membufs_proto_hw_t s_trace_proto_hw = {
.swap_start = esp_apptrace_riscv_buffer_swap_start,
.swap = esp_apptrace_riscv_buffer_swap,
.swap_end = esp_apptrace_riscv_buffer_swap_end,
.host_data_pending = esp_apptrace_riscv_host_data_pending,
};
static esp_apptrace_riscv_data_t s_trace_hw_data = {
.membufs = {
.hw = &s_trace_proto_hw,
},
};
static esp_apptrace_hw_t s_trace_hw = {
.init = (esp_err_t (*)(void *))esp_apptrace_riscv_init,
.get_up_buffer = (uint8_t *(*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_riscv_up_buffer_get,
.put_up_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_riscv_up_buffer_put,
.flush_up_buffer_nolock = (esp_err_t (*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_riscv_flush_nolock,
.flush_up_buffer = (esp_err_t (*)(void *, esp_apptrace_tmo_t *))esp_apptrace_riscv_flush,
.down_buffer_config = (void (*)(void *, uint8_t *, uint32_t))esp_apptrace_riscv_down_buffer_config,
.get_down_buffer = (uint8_t *(*)(void *, uint32_t *, esp_apptrace_tmo_t *))esp_apptrace_riscv_down_buffer_get,
.put_down_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_riscv_down_buffer_put,
.host_is_connected = (bool (*)(void *))esp_apptrace_riscv_host_is_connected,
};
*data = &s_trace_hw_data;
return &s_trace_hw;
#else
return NULL;
#endif
}
/* Advertises apptrace control block address to host. /* Advertises apptrace control block address to host.
This function can be overridden with custom implementation, This function can be overridden with custom implementation,
e.g. OpenOCD flasher stub use own implementation of it. */ e.g. OpenOCD flasher stub use own implementation of it. */
@@ -364,3 +318,31 @@ static bool esp_apptrace_riscv_host_data_pending(void)
// ESP_APPTRACE_LOGV("%s() 0x%x", __func__, ctrl_reg); // ESP_APPTRACE_LOGV("%s() 0x%x", __func__, ctrl_reg);
return (ctrl_reg & ESP_APPTRACE_RISCV_HOST_DATA) ? true : false; return (ctrl_reg & ESP_APPTRACE_RISCV_HOST_DATA) ? true : false;
} }
esp_apptrace_hw_t *esp_apptrace_jtag_hw_get(void **data)
{
static esp_apptrace_membufs_proto_hw_t s_trace_proto_hw = {
.swap_start = esp_apptrace_riscv_buffer_swap_start,
.swap = esp_apptrace_riscv_buffer_swap,
.swap_end = esp_apptrace_riscv_buffer_swap_end,
.host_data_pending = esp_apptrace_riscv_host_data_pending,
};
static esp_apptrace_riscv_data_t s_trace_hw_data = {
.membufs = {
.hw = &s_trace_proto_hw,
},
};
static esp_apptrace_hw_t s_trace_hw = {
.init = (esp_err_t (*)(void *))esp_apptrace_riscv_init,
.get_up_buffer = (uint8_t *(*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_riscv_up_buffer_get,
.put_up_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_riscv_up_buffer_put,
.flush_up_buffer_nolock = (esp_err_t (*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_riscv_flush_nolock,
.flush_up_buffer = (esp_err_t (*)(void *, esp_apptrace_tmo_t *))esp_apptrace_riscv_flush,
.down_buffer_config = (void (*)(void *, uint8_t *, uint32_t))esp_apptrace_riscv_down_buffer_config,
.get_down_buffer = (uint8_t *(*)(void *, uint32_t *, esp_apptrace_tmo_t *))esp_apptrace_riscv_down_buffer_get,
.put_down_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_riscv_down_buffer_put,
.host_is_connected = (bool (*)(void *))esp_apptrace_riscv_host_is_connected,
};
*data = &s_trace_hw_data;
return &s_trace_hw;
}

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 OR MIT * SPDX-License-Identifier: Apache-2.0 OR MIT
*/ */
@@ -188,20 +188,6 @@ typedef struct {
esp_apptrace_membufs_proto_data_t membufs; esp_apptrace_membufs_proto_data_t membufs;
} esp_apptrace_trax_data_t; } esp_apptrace_trax_data_t;
static esp_err_t esp_apptrace_trax_init(esp_apptrace_trax_data_t *hw_data);
static esp_err_t esp_apptrace_trax_flush(esp_apptrace_trax_data_t *hw_data, esp_apptrace_tmo_t *tmo);
static esp_err_t esp_apptrace_trax_flush_nolock(esp_apptrace_trax_data_t *hw_data, uint32_t min_sz, esp_apptrace_tmo_t *tmo);
static uint8_t *esp_apptrace_trax_up_buffer_get(esp_apptrace_trax_data_t *hw_data, uint32_t size, esp_apptrace_tmo_t *tmo);
static esp_err_t esp_apptrace_trax_up_buffer_put(esp_apptrace_trax_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo);
static void esp_apptrace_trax_down_buffer_config(esp_apptrace_trax_data_t *hw_data, uint8_t *buf, uint32_t size);
static uint8_t *esp_apptrace_trax_down_buffer_get(esp_apptrace_trax_data_t *hw_data, uint32_t *size, esp_apptrace_tmo_t *tmo);
static esp_err_t esp_apptrace_trax_down_buffer_put(esp_apptrace_trax_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo);
static bool esp_apptrace_trax_host_is_connected(esp_apptrace_trax_data_t *hw_data);
static esp_err_t esp_apptrace_trax_buffer_swap_start(uint32_t curr_block_id);
static esp_err_t esp_apptrace_trax_buffer_swap(uint32_t new_block_id, uint32_t prev_block_len);
static esp_err_t esp_apptrace_trax_buffer_swap_end(uint32_t new_block_id, uint32_t prev_block_len);
static bool esp_apptrace_trax_host_data_pending(void);
const static char *TAG = "esp_apptrace"; const static char *TAG = "esp_apptrace";
static uint8_t * const s_trax_blocks[] = { static uint8_t * const s_trax_blocks[] = {
@@ -209,38 +195,6 @@ static uint8_t * const s_trax_blocks[] = {
(uint8_t *)TRACEMEM_BLK1_ADDR (uint8_t *)TRACEMEM_BLK1_ADDR
}; };
esp_apptrace_hw_t *esp_apptrace_jtag_hw_get(void **data)
{
#if CONFIG_APPTRACE_DEST_JTAG
static esp_apptrace_membufs_proto_hw_t s_trax_proto_hw = {
.swap_start = esp_apptrace_trax_buffer_swap_start,
.swap = esp_apptrace_trax_buffer_swap,
.swap_end = esp_apptrace_trax_buffer_swap_end,
.host_data_pending = esp_apptrace_trax_host_data_pending,
};
static esp_apptrace_trax_data_t s_trax_hw_data = {
.membufs = {
.hw = &s_trax_proto_hw,
},
};
static esp_apptrace_hw_t s_trax_hw = {
.init = (esp_err_t (*)(void *))esp_apptrace_trax_init,
.get_up_buffer = (uint8_t *(*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_trax_up_buffer_get,
.put_up_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_trax_up_buffer_put,
.flush_up_buffer_nolock = (esp_err_t (*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_trax_flush_nolock,
.flush_up_buffer = (esp_err_t (*)(void *, esp_apptrace_tmo_t *))esp_apptrace_trax_flush,
.down_buffer_config = (void (*)(void *, uint8_t *, uint32_t))esp_apptrace_trax_down_buffer_config,
.get_down_buffer = (uint8_t *(*)(void *, uint32_t *, esp_apptrace_tmo_t *))esp_apptrace_trax_down_buffer_get,
.put_down_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_trax_down_buffer_put,
.host_is_connected = (bool (*)(void *))esp_apptrace_trax_host_is_connected,
};
*data = &s_trax_hw_data;
return &s_trax_hw;
#else
return NULL;
#endif
}
static esp_err_t esp_apptrace_trax_lock(esp_apptrace_trax_data_t *hw_data, esp_apptrace_tmo_t *tmo) static esp_err_t esp_apptrace_trax_lock(esp_apptrace_trax_data_t *hw_data, esp_apptrace_tmo_t *tmo)
{ {
#if CONFIG_APPTRACE_LOCK_ENABLE #if CONFIG_APPTRACE_LOCK_ENABLE
@@ -539,3 +493,31 @@ static bool esp_apptrace_trax_host_data_pending(void)
uint32_t ctrl_reg = eri_read(ESP_APPTRACE_TRAX_CTRL_REG); uint32_t ctrl_reg = eri_read(ESP_APPTRACE_TRAX_CTRL_REG);
return (ctrl_reg & ESP_APPTRACE_TRAX_HOST_DATA) ? true : false; return (ctrl_reg & ESP_APPTRACE_TRAX_HOST_DATA) ? true : false;
} }
esp_apptrace_hw_t *esp_apptrace_jtag_hw_get(void **data)
{
static esp_apptrace_membufs_proto_hw_t s_trax_proto_hw = {
.swap_start = esp_apptrace_trax_buffer_swap_start,
.swap = esp_apptrace_trax_buffer_swap,
.swap_end = esp_apptrace_trax_buffer_swap_end,
.host_data_pending = esp_apptrace_trax_host_data_pending,
};
static esp_apptrace_trax_data_t s_trax_hw_data = {
.membufs = {
.hw = &s_trax_proto_hw,
},
};
static esp_apptrace_hw_t s_trax_hw = {
.init = (esp_err_t (*)(void *))esp_apptrace_trax_init,
.get_up_buffer = (uint8_t *(*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_trax_up_buffer_get,
.put_up_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_trax_up_buffer_put,
.flush_up_buffer_nolock = (esp_err_t (*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_trax_flush_nolock,
.flush_up_buffer = (esp_err_t (*)(void *, esp_apptrace_tmo_t *))esp_apptrace_trax_flush,
.down_buffer_config = (void (*)(void *, uint8_t *, uint32_t))esp_apptrace_trax_down_buffer_config,
.get_down_buffer = (uint8_t *(*)(void *, uint32_t *, esp_apptrace_tmo_t *))esp_apptrace_trax_down_buffer_get,
.put_down_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_trax_down_buffer_put,
.host_is_connected = (bool (*)(void *))esp_apptrace_trax_host_is_connected,
};
*data = &s_trax_hw_data;
return &s_trax_hw;
}

View File

@@ -41,7 +41,7 @@ Using of this feature depends on two components:
1. **Host side:** Application tracing is done over JTAG, so it needs OpenOCD to be set up and running on host machine. For instructions on how to set it up, please see :doc:`JTAG Debugging <../api-guides/jtag-debugging/index>` for details. 1. **Host side:** Application tracing is done over JTAG, so it needs OpenOCD to be set up and running on host machine. For instructions on how to set it up, please see :doc:`JTAG Debugging <../api-guides/jtag-debugging/index>` for details.
2. **Target side:** Application tracing functionality can be enabled in menuconfig. Please go to ``Component config`` > ``Application Level Tracing`` menu, which allows selecting destination for the trace data (hardware interface for transport: JTAG or/and UART). Choosing any of the destinations automatically enables the ``CONFIG_APPTRACE_ENABLE`` option. For UART interfaces, users have to define baud rate, TX and RX pins numbers, and additional UART-related parameters. 2. **Target side:** Application tracing functionality can be enabled in menuconfig. Please go to ``Component config`` > ``Application Level Tracing`` menu, which allows selecting destination for the trace data (hardware interface for transport: JTAG or/and UART). Choosing any of the destinations automatically enables the ``CONFIG_APPTRACE_ENABLE`` option. For UART interfaces, users have to define port number, baud rate, TX and RX pins numbers, and additional UART-related parameters.
.. note:: .. note::

View File

@@ -81,6 +81,28 @@ Update to:
return res; return res;
} }
The UART destination configuration has been simplified:
- Removed: Individual UART selection via ``CONFIG_APPTRACE_DEST_UARTx=y``
- Added: Single UART port selection via ``CONFIG_APPTRACE_DEST_UART_NUM``
To migrate, update your sdkconfig:
Old configuration:
.. code-block:: none
CONFIG_APPTRACE_DEST_UART0=y
# or
CONFIG_APPTRACE_DEST_UART1=y
New configuration:
.. code-block:: none
CONFIG_APPTRACE_DEST_UART=y
CONFIG_APPTRACE_DEST_UART_NUM=0 # or 1, 2 depending on target
FreeRTOS FreeRTOS
-------- --------

View File

@@ -41,7 +41,7 @@ ESP-IDF 中提供了应用层跟踪功能,用于分析应用程序的行为。
1. **主机端:** 应用程序跟踪通过 JTAG 来完成,因此需要在主机上安装并运行 OpenOCD。详细信息请参阅 :doc:`JTAG 调试 <../api-guides/jtag-debugging/index>` 1. **主机端:** 应用程序跟踪通过 JTAG 来完成,因此需要在主机上安装并运行 OpenOCD。详细信息请参阅 :doc:`JTAG 调试 <../api-guides/jtag-debugging/index>`
2. **目标端:** 在 menuconfig 中开启应用程序跟踪功能。前往 ``Component config`` > ``Application Level Tracing`` 菜单选择跟踪数据的传输目标具体用于传输的硬件接口JTAG 和/或 UART选择任一非 None 的目标都会自动开启 ``CONFIG_APPTRACE_ENABLE`` 这个选项。对于 UART 接口,用户必须定义波特率、TX 和 RX 管脚及其他相关参数。 2. **目标端:** 在 menuconfig 中开启应用程序跟踪功能。前往 ``Component config`` > ``Application Level Tracing`` 菜单选择跟踪数据的传输目标具体用于传输的硬件接口JTAG 和/或 UART选择任一非 None 的目标都会自动开启 ``CONFIG_APPTRACE_ENABLE`` 这个选项。对于 UART 接口,用户需要定义端口号、波特率、TX 和 RX 管脚及其他相关参数。
.. note:: .. note::

View File

@@ -81,6 +81,28 @@ App 追踪
return res; return res;
} }
UART 目标配置已简化:
- 移除:通过 ``CONFIG_APPTRACE_DEST_UARTx=y`` 选择单个 UART
- 新增:通过 ``CONFIG_APPTRACE_DEST_UART_NUM`` 选择 UART 端口
迁移方法,更新你的 sdkconfig 配置:
旧配置:
.. code-block:: none
CONFIG_APPTRACE_DEST_UART0=y
# 或
CONFIG_APPTRACE_DEST_UART1=y
新配置:
.. code-block:: none
CONFIG_APPTRACE_DEST_UART=y
CONFIG_APPTRACE_DEST_UART_NUM=0 # 或 1、2具体取决于目标芯片
FreeRTOS FreeRTOS
-------- --------

View File

@@ -134,7 +134,7 @@ static void example_task(void *p)
void app_main(void) void app_main(void)
{ {
ESP_LOGI(TAG, "Ready for OpenOCD connection"); ESP_LOGI(TAG, "Hello from sysview_tracing example!");
static example_event_data_t event_data[CONFIG_FREERTOS_NUMBER_OF_CORES]; static example_event_data_t event_data[CONFIG_FREERTOS_NUMBER_OF_CORES];

View File

@@ -7,6 +7,7 @@ import typing
import pexpect import pexpect
import pytest import pytest
import serial
from pytest_embedded_idf import IdfDut from pytest_embedded_idf import IdfDut
from pytest_embedded_idf.utils import idf_parametrize from pytest_embedded_idf.utils import idf_parametrize
@@ -14,7 +15,7 @@ if typing.TYPE_CHECKING:
from conftest import OpenOCD from conftest import OpenOCD
def _test_examples_sysview_tracing(openocd_dut: 'OpenOCD', dut: IdfDut) -> None: def _test_sysview_tracing_jtag(openocd_dut: 'OpenOCD', dut: IdfDut) -> None:
# Construct trace log paths # Construct trace log paths
trace_log = [ trace_log = [
os.path.join(dut.logdir, 'sys_log0.svdat') # pylint: disable=protected-access os.path.join(dut.logdir, 'sys_log0.svdat') # pylint: disable=protected-access
@@ -27,7 +28,7 @@ def _test_examples_sysview_tracing(openocd_dut: 'OpenOCD', dut: IdfDut) -> None:
gdb_logfile = os.path.join(dut.logdir, 'gdb.txt') gdb_logfile = os.path.join(dut.logdir, 'gdb.txt')
gdbinit_orig = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'gdbinit') gdbinit_orig = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'gdbinit')
gdbinit = os.path.join(dut.logdir, 'gdbinit') gdbinit = os.path.join(dut.logdir, 'gdbinit')
with open(gdbinit_orig, 'r') as f_r, open(gdbinit, 'w') as f_w: with open(gdbinit_orig) as f_r, open(gdbinit, 'w') as f_w:
for line in f_r: for line in f_r:
if line.startswith('mon esp sysview start'): if line.startswith('mon esp sysview start'):
f_w.write(f'mon esp sysview start {trace_files}\n') f_w.write(f'mon esp sysview start {trace_files}\n')
@@ -37,14 +38,18 @@ def _test_examples_sysview_tracing(openocd_dut: 'OpenOCD', dut: IdfDut) -> None:
def dut_expect_task_event() -> None: def dut_expect_task_event() -> None:
dut.expect(re.compile(rb'example: Task\[0x[0-9A-Fa-f]+\]: received event \d+'), timeout=30) dut.expect(re.compile(rb'example: Task\[0x[0-9A-Fa-f]+\]: received event \d+'), timeout=30)
dut.expect_exact('example: Ready for OpenOCD connection', timeout=5) dut.expect_exact('example: Hello from sysview_tracing example!', timeout=5)
with openocd_dut.run() as openocd, open(gdb_logfile, 'w') as gdb_log, pexpect.spawn( with (
f'idf.py -B {dut.app.binary_path} gdb --batch -x {gdbinit}', openocd_dut.run() as openocd,
timeout=60, open(gdb_logfile, 'w') as gdb_log,
logfile=gdb_log, pexpect.spawn(
encoding='utf-8', f'idf.py -B {dut.app.binary_path} gdb --batch -x {gdbinit}',
codec_errors='ignore', timeout=60,
) as p: logfile=gdb_log,
encoding='utf-8',
codec_errors='ignore',
) as p,
):
p.expect_exact('hit Breakpoint 1, app_main ()') p.expect_exact('hit Breakpoint 1, app_main ()')
dut.expect('example: Created task') # dut has been restarted by gdb since the last dut.expect() dut.expect('example: Created task') # dut has been restarted by gdb since the last dut.expect()
dut_expect_task_event() dut_expect_task_event()
@@ -55,14 +60,59 @@ def _test_examples_sysview_tracing(openocd_dut: 'OpenOCD', dut: IdfDut) -> None:
@pytest.mark.jtag @pytest.mark.jtag
@idf_parametrize('config', ['sysview_jtag'], indirect=['config'])
@idf_parametrize('target', ['esp32', 'esp32c2', 'esp32s2'], indirect=['target']) @idf_parametrize('target', ['esp32', 'esp32c2', 'esp32s2'], indirect=['target'])
def test_examples_sysview_tracing(openocd_dut: 'OpenOCD', dut: IdfDut) -> None: def test_sysview_tracing_jtag(openocd_dut: 'OpenOCD', dut: IdfDut) -> None:
_test_examples_sysview_tracing(openocd_dut, dut) _test_sysview_tracing_jtag(openocd_dut, dut)
@pytest.mark.usb_serial_jtag @pytest.mark.usb_serial_jtag
@idf_parametrize('config', ['sysview_jtag'], indirect=['config'])
@idf_parametrize( @idf_parametrize(
'target', ['esp32s3', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32c61', 'esp32h2', 'esp32p4'], indirect=['target'] 'target', ['esp32s3', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32c61', 'esp32h2', 'esp32p4'], indirect=['target']
) )
def test_examples_sysview_tracing_usj(openocd_dut: 'OpenOCD', dut: IdfDut) -> None: def test_sysview_tracing_usj(openocd_dut: 'OpenOCD', dut: IdfDut) -> None:
_test_examples_sysview_tracing(openocd_dut, dut) _test_sysview_tracing_jtag(openocd_dut, dut)
def _test_sysview_tracing_uart(dut: IdfDut) -> None:
dut.serial.close()
time.sleep(2) # Wait for the DUT to reboot
with serial.Serial(dut.serial.port, baudrate=dut.app.sdkconfig.get('APPTRACE_UART_BAUDRATE'), timeout=10) as ser:
trace_log = os.path.join(dut.logdir, 'sys_log_uart.svdat') # pylint: disable=protected-access
# Send Start command to start SysView tracing
ser.write(b'\x01')
with open(trace_log, 'w+b') as f:
start_time = time.time()
while True:
try:
if ser.in_waiting:
data = ser.read(1024)
f.write(data)
if time.time() - start_time > 3:
break
except serial.SerialTimeoutException:
assert False, 'Timeout reached while reading from serial port, exiting...'
# Send Stop command
ser.write(b'\x02')
f.seek(0)
content = f.read()
search_str = f'N=FreeRTOS Application,D={dut.target},C=core0,O=FreeRTOS'.encode()
assert search_str in content, 'SysView trace data not found in the log file'
@pytest.mark.generic
@idf_parametrize('config', ['sysview_uart'], indirect=['config'])
@idf_parametrize('target', ['supported_targets'], indirect=['target'])
def test_sysview_tracing_uart(dut: IdfDut) -> None:
_test_sysview_tracing_uart(dut)
@pytest.mark.generic
@pytest.mark.xtal_26mhz
@idf_parametrize('config', ['sysview_uart_esp32c2_26Mhz'], indirect=['config'])
@idf_parametrize('target', ['esp32c2'], indirect=['target'])
def test_sysview_tracing_uart_c2(dut: IdfDut) -> None:
_test_sysview_tracing_uart(dut)

View File

@@ -0,0 +1 @@
CONFIG_APPTRACE_DEST_JTAG=y

View File

@@ -0,0 +1,5 @@
CONFIG_ESP_CONSOLE_NONE=y
CONFIG_ESP_CONSOLE_SECONDARY_NONE=y
CONFIG_APPTRACE_DEST_UART=y
CONFIG_APPTRACE_DEST_UART_NUM=0
CONFIG_APPTRACE_SV_DEST_UART=y

View File

@@ -0,0 +1,8 @@
CONFIG_IDF_TARGET="esp32c2"
CONFIG_ESP_CONSOLE_NONE=y
CONFIG_ESP_CONSOLE_SECONDARY_NONE=y
CONFIG_APPTRACE_DEST_UART=y
CONFIG_APPTRACE_DEST_UART_NUM=0
CONFIG_APPTRACE_SV_DEST_UART=y
CONFIG_APPTRACE_UART_BAUDRATE=74880
CONFIG_XTAL_FREQ_26=y

View File

@@ -1,9 +1,7 @@
# 1ms tick period # 1ms tick period
CONFIG_FREERTOS_HZ=1000 CONFIG_FREERTOS_HZ=1000
# Enable application tracing by default
CONFIG_APPTRACE_DEST_JTAG=y
CONFIG_APPTRACE_ENABLE=y
# Enable FreeRTOS SystemView Tracing by default # Enable FreeRTOS SystemView Tracing by default
CONFIG_APPTRACE_ENABLE=y
CONFIG_APPTRACE_SV_ENABLE=y CONFIG_APPTRACE_SV_ENABLE=y
CONFIG_APPTRACE_SV_TS_SOURCE_ESP_TIMER=y CONFIG_APPTRACE_SV_TS_SOURCE_ESP_TIMER=y
CONFIG_APPTRACE_SV_EVT_OVERFLOW_ENABLE=y CONFIG_APPTRACE_SV_EVT_OVERFLOW_ENABLE=y

View File

@@ -0,0 +1,3 @@
CONFIG_IDF_TARGET="esp32"
CONFIG_APPTRACE_UART_TX_GPIO=1
CONFIG_APPTRACE_UART_RX_GPIO=3

View File

@@ -0,0 +1,3 @@
CONFIG_IDF_TARGET="esp32c2"
CONFIG_APPTRACE_UART_TX_GPIO=20
CONFIG_APPTRACE_UART_RX_GPIO=19

View File

@@ -0,0 +1,3 @@
CONFIG_IDF_TARGET="esp32c3"
CONFIG_APPTRACE_UART_TX_GPIO=21
CONFIG_APPTRACE_UART_RX_GPIO=20

View File

@@ -0,0 +1,3 @@
CONFIG_IDF_TARGET="esp32c5"
CONFIG_APPTRACE_UART_TX_GPIO=11
CONFIG_APPTRACE_UART_RX_GPIO=12

View File

@@ -0,0 +1,3 @@
CONFIG_IDF_TARGET="esp32c6"
CONFIG_APPTRACE_UART_TX_GPIO=16
CONFIG_APPTRACE_UART_RX_GPIO=17

View File

@@ -0,0 +1,3 @@
CONFIG_IDF_TARGET="esp32c61"
CONFIG_APPTRACE_UART_TX_GPIO=11
CONFIG_APPTRACE_UART_RX_GPIO=10

View File

@@ -0,0 +1,3 @@
CONFIG_IDF_TARGET="esp32h2"
CONFIG_APPTRACE_UART_TX_GPIO=24
CONFIG_APPTRACE_UART_RX_GPIO=23

View File

@@ -0,0 +1,3 @@
CONFIG_IDF_TARGET="esp32p4"
CONFIG_APPTRACE_UART_TX_GPIO=37
CONFIG_APPTRACE_UART_RX_GPIO=38

View File

@@ -0,0 +1,3 @@
CONFIG_IDF_TARGET="esp32s2"
CONFIG_APPTRACE_UART_TX_GPIO=43
CONFIG_APPTRACE_UART_RX_GPIO=44

View File

@@ -0,0 +1,3 @@
CONFIG_IDF_TARGET="esp32s3"
CONFIG_APPTRACE_UART_TX_GPIO=43
CONFIG_APPTRACE_UART_RX_GPIO=44

View File

@@ -1 +1,2 @@
CONFIG_APPTRACE_DEST_UART1=y CONFIG_APPTRACE_DEST_UART=y
CONFIG_APPTRACE_DEST_UART_NUM=1

View File

@@ -175,8 +175,8 @@ app_trace:
- components/app_trace/app_trace.c - components/app_trace/app_trace.c
- components/app_trace/app_trace_membufs_proto.c - components/app_trace/app_trace_membufs_proto.c
- components/app_trace/app_trace_util.c - components/app_trace/app_trace_util.c
- components/app_trace/port/riscv/port.c - components/app_trace/port/riscv/port_jtag.c
- components/app_trace/port/xtensa/port.c - components/app_trace/port/xtensa/port_jtag.c
allowed_licenses: allowed_licenses:
- Apache-2.0 - Apache-2.0
- MIT - MIT