diff --git a/components/esp_trace/Kconfig b/components/esp_trace/Kconfig index a54719e68b2..88a41ac8bd8 100644 --- a/components/esp_trace/Kconfig +++ b/components/esp_trace/Kconfig @@ -91,6 +91,7 @@ menu "ESP Trace Configuration" prompt "Trace timestamp source" default ESP_TRACE_TS_SOURCE_CCOUNT if ESP_SYSTEM_SINGLE_CORE_MODE && !PM_ENABLE && !IDF_TARGET_ESP32C3 default ESP_TRACE_TS_SOURCE_GPTIMER if !ESP_SYSTEM_SINGLE_CORE_MODE && !PM_ENABLE && !IDF_TARGET_ESP32C3 + default ESP_TRACE_TS_SOURCE_SYSTIMER if SOC_SYSTIMER_SUPPORTED && (PM_ENABLE || IDF_TARGET_ESP32C3) default ESP_TRACE_TS_SOURCE_ESP_TIMER if PM_ENABLE || IDF_TARGET_ESP32C3 help Select the timestamp source for tracing. @@ -103,6 +104,15 @@ menu "ESP Trace Configuration" bool "General Purpose Timer (Timer Group)" depends on !PM_ENABLE && !IDF_TARGET_ESP32C3 + config ESP_TRACE_TS_SOURCE_SYSTIMER + bool "Systimer raw ticks" + depends on SOC_SYSTIMER_SUPPORTED + help + Read the systimer counter directly. This is the same clock + esp_timer uses, without the tick-to-microsecond conversion. + Timestamps are in raw ticks (16 MHz on most targets); host + tools get the rate from the trace stream. + config ESP_TRACE_TS_SOURCE_ESP_TIMER bool "esp_timer high resolution timer" diff --git a/components/esp_trace/include/esp_trace_util.h b/components/esp_trace/include/esp_trace_util.h index 5e814731363..902579a1ea2 100644 --- a/components/esp_trace/include/esp_trace_util.h +++ b/components/esp_trace/include/esp_trace_util.h @@ -20,8 +20,8 @@ extern "C" { * @brief Initialize the trace timestamp source. * * This function initializes the trace timestamp source based on the configured - * source. The timestamp source can be the CPU cycle counter, esp_timer, or - * Timer Group, depending on configuration. + * source. The timestamp source can be the CPU cycle counter, esp_timer, + * Timer Group, or systimer, depending on configuration. * * @return The timestamp frequency in Hz. */ @@ -31,7 +31,8 @@ uint32_t esp_trace_timestamp_init(void); * @brief Get the current timestamp value from the configured source for ESP trace. * * This function returns the current timestamp value, which can be sourced from - * the CPU cycle counter, esp_timer, or Timer Group, depending on configuration. + * the CPU cycle counter, esp_timer, Timer Group, or systimer, depending on + * configuration. * * @return The current timestamp value as a 32-bit unsigned integer. */ diff --git a/components/esp_trace/src/ports/port_utils.c b/components/esp_trace/src/ports/port_utils.c index 4870016b95c..3d7baf923db 100644 --- a/components/esp_trace/src/ports/port_utils.c +++ b/components/esp_trace/src/ports/port_utils.c @@ -25,12 +25,20 @@ // Determine which timer to use as timestamp source #if CONFIG_ESP_TRACE_TS_SOURCE_CCOUNT #define TS_USE_CCOUNT 1 +#elif CONFIG_ESP_TRACE_TS_SOURCE_SYSTIMER +#define TS_USE_SYSTIMER 1 #elif CONFIG_ESP_TRACE_TS_SOURCE_ESP_TIMER #define TS_USE_ESP_TIMER 1 #else #define TS_USE_TIMERGROUP 1 #endif +#if TS_USE_SYSTIMER +#include "hal/systimer_ll.h" +#include "soc/systimer_struct.h" +#include "esp_private/systimer.h" +#endif // TS_USE_SYSTIMER + #if TS_USE_TIMERGROUP #include "driver/gptimer.h" @@ -52,13 +60,17 @@ static gptimer_handle_t s_trace_gptimer; #define ESP_TRACE_TIMESTAMP_FREQ (CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ * 1000000) #endif // TS_USE_CCOUNT +#if TS_USE_SYSTIMER +#define ESP_TRACE_TIMESTAMP_FREQ ((uint32_t)systimer_us_to_ticks(1000000)) +#endif // TS_USE_SYSTIMER + // System Frequency. #define ESP_TRACE_CPU_FREQ (esp_clk_cpu_freq()) uint32_t esp_trace_timestamp_init(void) { /* We only need to initialize something if we use Timer Group. - * esp_timer and ccount can be used as is. + * esp_timer, systimer, and ccount can be used as is. */ #if TS_USE_TIMERGROUP // get clock source frequency @@ -83,7 +95,12 @@ uint32_t esp_trace_timestamp_init(void) uint32_t esp_trace_timestamp_get(void) { -#if TS_USE_TIMERGROUP +#if TS_USE_SYSTIMER + /* Set the "update" bit and wait for acknowledgment */ + systimer_ll_counter_snapshot(&SYSTIMER, SYSTIMER_COUNTER_ESPTIMER); + while (!systimer_ll_is_counter_value_valid(&SYSTIMER, SYSTIMER_COUNTER_ESPTIMER)) {} + return systimer_ll_get_counter_value_low(&SYSTIMER, SYSTIMER_COUNTER_ESPTIMER); +#elif TS_USE_TIMERGROUP uint64_t ts = 0; gptimer_get_raw_count(s_trace_gptimer, &ts); return (uint32_t)ts; // return lower part of counter value @@ -133,6 +150,11 @@ void esp_trace_lock_init(esp_trace_lock_t *lock) esp_err_t esp_trace_lock_take(esp_trace_lock_t *lock, uint32_t tmo_us) { + /* Skip tmo_init's esp_timer read when the lock is free. */ + if (portTRY_ENTER_CRITICAL(&lock->mux, 0) == pdTRUE) { + return ESP_OK; + } + esp_trace_tmo_t tmo; esp_trace_tmo_init(&tmo, tmo_us); diff --git a/examples/system/tracing/sysview_tracing/sdkconfig.defaults b/examples/system/tracing/sysview_tracing/sdkconfig.defaults index b58df2ad9cd..5fba151e272 100644 --- a/examples/system/tracing/sysview_tracing/sdkconfig.defaults +++ b/examples/system/tracing/sysview_tracing/sdkconfig.defaults @@ -3,7 +3,7 @@ CONFIG_FREERTOS_HZ=1000 # Enable FreeRTOS SystemView Tracing by default CONFIG_ESP_TRACE_ENABLE=y CONFIG_ESP_TRACE_LIB_EXTERNAL=y -CONFIG_ESP_TRACE_TS_SOURCE_ESP_TIMER=y +CONFIG_ESP_TRACE_TS_SOURCE_SYSTIMER=y CONFIG_SEGGER_SYSVIEW_EVT_OVERFLOW_ENABLE=y CONFIG_SEGGER_SYSVIEW_EVT_ISR_ENTER_ENABLE=y CONFIG_SEGGER_SYSVIEW_EVT_ISR_EXIT_ENABLE=y diff --git a/examples/system/tracing/sysview_tracing/sdkconfig.defaults.esp32 b/examples/system/tracing/sysview_tracing/sdkconfig.defaults.esp32 new file mode 100644 index 00000000000..283aa7c3257 --- /dev/null +++ b/examples/system/tracing/sysview_tracing/sdkconfig.defaults.esp32 @@ -0,0 +1 @@ +CONFIG_ESP_TRACE_TS_SOURCE_ESP_TIMER=y