STM: Difference between revisions

From SEGGER Knowledge Base
Jump to navigation Jump to search
No edit summary
Line 24: Line 24:
int OnTraceStart(void) {
int OnTraceStart(void) {
   U32 v;
   U32 v;
   U32 ExampleRegsiter;
   U32 ExampleRegister;
   //
   //
   // Add register address defines below
   // Add register address defines below
   //
   //
   ExampleRegsiter = 0x12345678;
   ExampleRegister= 0x12345678;
   //
   //
   // Insert chip/board specific init here
   // Insert chip/board specific init here
   //
   //
   v  =  JLINK_MEM_ReadU32(ExampleRegsiter);
   v  =  JLINK_MEM_ReadU32(ExampleRegister);
   v |= 1 << 16; // Sets some register bit to 1
   v |= 1 << 16; // Sets some register bit to 1
   JLINK_MEM_WriteU32(ExampleRegsiter, v);
   JLINK_MEM_WriteU32(ExampleRegister, v);
   return 0;
   return 0;
}
}

Revision as of 11:56, 22 August 2025

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 ExampleRegister;
  //
  // Add register address defines below
  //
  ExampleRegister= 0x12345678;
  //
  // Insert chip/board specific init here
  //
  v  =  JLINK_MEM_ReadU32(ExampleRegister);
  v |= 1 << 16; // Sets some register bit to 1
  JLINK_MEM_WriteU32(ExampleRegister, v);
  return 0;
}
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;
}