Course contentsShow
← Embedded Systems & Computer Architecture
Lesson 589 of 9368. Advanced Debugging and Hardware VerificationFree lesson

Architecting Embedded Trace Macrocell Data Streams

Learners will configure the Embedded Trace Macrocell to capture instruction flow without halting the processor for cycle-accurate execution profiling.

In this lesson, you will learn how to configure the Embedded Trace Macrocell (ETM) to capture full instruction flow and profile cycle-accurate execution without ever halting the processor.

Non-Intrusive Execution Profiling

Traditional debugging relies on breakpoints, which force the processor to halt, thereby distorting timing and masking race conditions. By contrast, the ETM acts as a passive observer. It taps into the internal instruction bus and generates a compressed stream of data representing the program counter (PC) changes. Because this occurs at the hardware level via a dedicated trace port, the processor runs at full speed, maintaining the integrity of the execution environment.

Configuring the Data Stream

To perform cycle-accurate profiling, we must configure the ETM to output enough context for an external debugger (like a Trace Port Interface Unit) to reconstruct the control flow. We generally don't output every single PC value—that would overwhelm the bandwidth. Instead, the ETM emits "atoms" that describe branches:

// Example pseudo-register configuration for ETM flow
ETM_CONTROL |= ETM_ENABLE;           // Activate the macrocell
ETM_TRACE_MODE |= CYCLE_ACCURATE;    // Include timing packets
ETM_TRACE_EN |= INCLUDE_BRANCHES;    // Only log control flow changes

By logging branch outcomes (taken vs. not taken) and cycle counts between them, the host software uses the original ELF file's symbol table to "reconstruct" the execution path in real-time. If a branch is conditional, the ETM sends a single-bit packet (a "Waypoint") indicating the outcome. By injecting cycle-count packets into this stream, you can calculate the exact number of clock cycles consumed by specific code blocks, such as interrupt service routines or computationally heavy math functions.

This method allows you to profile your code's performance in a production-like state. You can identify exactly which loops are consuming the most cycles and detect if your interrupt latency is drifting due to architectural cache misses or pipeline stalls, all without adding a single printf or breakpoint.

Key Takeaway: The ETM allows you to reconstruct a complete, cycle-accurate execution trace by streaming compressed branch metadata, enabling precise performance profiling without the timing side effects of intrusive debugging.