Files
esp-idf/components/esp_riscv_trace

RISC-V Trace Encoder Driver

Overview

The esp_riscv_trace component provides the public driver API for the RISC-V trace encoder peripheral. The driver is enabled by CONFIG_ESP_RISCV_TRACE_ENABLE and creates one encoder handle per core during startup.

Applications can override the weak esp_riscv_trace_get_user_config(int core_id) function to customize configuration per core, or use Kconfig defaults via ESP_RISCV_TRACE_DEFAULT_CONFIG().

State Transition

stateDiagram-v2
    [*] --> created: startup auto-init
    created --> started: esp_riscv_trace_start
    started --> stopped: esp_riscv_trace_stop
    stopped --> started: esp_riscv_trace_start

esp_riscv_trace_set_filter() and esp_riscv_trace_get_buffer() are valid only while the encoder is stopped. esp_riscv_trace_get_status() reads the current status.

With CONFIG_ESP_RISCV_TRACE_AUTOSTART the driver also starts each encoder during startup, so the application does not need to call esp_riscv_trace_start(). This option defaults to enabled when core dumps are enabled, so a panic always carries the recent execution history.

Concurrency

Public driver APIs use a per-core lock. They must only be called from FreeRTOS tasks, not from interrupt service routines (ISRs).

The driver checks lifecycle state and executes HAL register operations under the same per-core lock. This prevents race conditions between start, stop, filter configuration, and buffer cache synchronization.

Snapshot

The snapshot is an in-memory structure that describes a capture. Firmware updates g_esp_riscv_trace_snapshot as encoders start, stop, or freeze on panic.

The root descriptor contains the ABI version, chip ID, chip revision, capture reason, and a write_seq counter. The write_seq counter is odd while the snapshot is being updated and even when stable. cores_addr points to an array of per-core records. Each record stores the trace buffer address, size, head offset, encoder parameters, wire format, memory mode, and head offset.

g_esp_riscv_trace_snapshot
  `-- cores_addr --> core_desc[core_count]
        |-- buffer_addr --> raw encoder packets
        `-- encoder_params_addr --> encoder params

How Coredump Reads the Snapshot

On panic, the driver freezes the snapshot. The coredump writer copies a core buffer when that core is stopped or frozen, head_valid is set, and the encoder FIFO is empty.

The coredump writer adds those buffers as PT_LOAD segments and writes metadata into an ESP_RISCV_TRACE ELF note (type 680). The esp-riscv-trace tool reads the note and trace segments directly from the coredump ELF file.

Buffer and Trace Stream Notes

The trace buffer must be reachable by the trace encoder AHB master. Driver-allocated buffers are placed in internal RAM or PSRAM based on configuration, and are cache-line aligned when placed in cached memory. Caller-provided buffers are validated for memory reachability and cache-line alignment. PSRAM placement is only available on targets where the encoder can access external RAM (SOC_RISCV_TRACE_MEM_SUPPORT_PSRAM). On other targets, the buffer is always in internal RAM.

In loop memory mode, wrapped buffers require periodic resynchronization packets to remain decodable after the initial sync packet is overwritten.

Dependencies

This driver depends on the RISC-V trace HAL (hal component) and supports SoCs with RISC-V trace hardware.