STM
General Information
The System Trace Macrocell (STM) is a component within the Arm Coresight technology ecosystem designed to enhance the tracing capabilities of embedded systems. It provides a mechanism for capturing and analyzing system events, allowing developers to gain insights into software behavior, performance, and debugging.
STM is particularly beneficial for real-time applications, as it enables the collection of trace data with minimal impact on system performance. This makes it an essential tool for developers working on complex embedded systems, where understanding the timing and sequence of events is crucial.
STM can be seen as an expansion of the Instrumentation Trace Macrocell (ITM). While ITM focuses on providing a lightweight mechanism for tracing software events, STM extends these capabilities by allowing for more extensive system-level event tracing.
How to use with J-Trace Pro
This section will explain how you can extract STM data from your target device via a TPIU with a J-Trace Pro.
Minimum Requirements
- J-Link Software version V7.94i
- J-Trace Pro V3 or later
- A target device with a TPIU
Guide
The J-Link software currently supports capturing of raw STM data which can be dumped into a file or to a TCP socket. The trace protocol for analysis is described here. The data is wrapped in the TPIU format which is described here.
Note: The following steps will require setting command strings. How to use command strings in your setup is explained here.
The setup steps are as follows:
- Make sure that all board or chip specific init steps (e.g. trace pin init, clock init etc.) are handled either in the target application or via a J-Link Script. An example J-Link Script snippet can be found below:
int OnTraceStart(void) {
U32 v;
U32 ExampleRegsiter;
//
// Add register address defines below
//
ExampleRegsiter = 0x12345678;
//
// Insert chip/board specific init here
//
v = JLINK_MEM_ReadU32(ExampleRegsiter);
v |= 1 << 16; // Sets some register bit to 1
JLINK_MEM_WriteU32(ExampleRegsiter, v);
return 0;
}
- Set command string CORESIGHT_SetSTMBaseAddr . An example J-Link Script snippet can be found below:
- Set either TRACE_SetSTMDataFile path or TRACE_SetSTMDataPort.
- Optionally you can change the TraceID we filter for via CORESIGHT_SetSTMTraceID. (Default trace ID we look for is 0x40.)
int SetupTarget(void) {
JLINK_ExecCommand("CORESIGHT_SetSTMBaseAddr = 0xE0047000");
JLINK_ExecCommand("TRACE_SetSTMDataFile = C:\Temp\STMData.bin");
JLINK_ExecCommand("CORESIGHT_SetSTMTraceID = 0x40");
return 0;
}
- Now start the trace function (STRACE) in your debug software e.g. Ozone.
If everything worked correctly you should now see the STM data being dumped into the chosen output channel.
Example target code
The following code block shows an example implementation using one of the STM stimulus ports to output data from the target device. To make the example run on your target device make sure to adjust the STM_BASE_ADDR value to reflect the right address in your system.
#define STM_BASE_ADDR 0xF8000000UL // Edit value to fit your device
//
// STM Registers (offsets from STM_BASE_ADDR)
//
#define STMSTIMULUS0 (*(volatile unsigned int *)(STM_BASE_ADDR + 0x000)) // Basic Stimulus Port 0
#define STMSPER (*(volatile unsigned int *)(STM_BASE_ADDR + 0xE00)) // Stimulus Port Enable Register
#define STMSCR (*(volatile unsigned int *)(STM_BASE_ADDR + 0xE80)) // System Control Register
void STM_Init(void) {
STMSCR = (1U << 0); // Enable STM component
STMSPER = (1U << 0); // Enable Stimulus Port 0
}
void STM_Send(unsigned int Data) {
STMSTIMULUS0 = Data; // Send data to Stimulus Port 0
}
int main(void) {
unsigned int ExampleValue = 0xC0FFEE00;
STM_Init();
STM_Send(ExampleValue);
while (1);
return 0;
}