change(esp_trace): skip unused timer reads on the per-event path

Lock take called esp_timer_get_time() before trying the spinlock, and the
C3 default timestamp went through esp_timer's tick-to-us conversion.
Try the lock first, and read systimer ticks directly.
This commit is contained in:
Erhan Kurubas
2026-08-20 13:28:38 +02:00
parent 44a38047bb
commit 4709507f3e
6 changed files with 41 additions and 6 deletions

View File

@@ -33,6 +33,7 @@ set(priv_requires
"esp_driver_gptimer"
"esp_hal_usb"
"esp_driver_usb_serial_jtag"
"esp_hal_systimer"
"esp_timer"
"esp_system"
)

View File

@@ -142,6 +142,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.
@@ -154,6 +155,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"

View File

@@ -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.
*/

View File

@@ -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);

View File

@@ -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

View File

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