Wednesday, 15 October 2025

SEGGER SystemView + FreeRTOS: Install, Integrate, Record (the clean way)

SystemView lets you see your RTOS: who ran, when, how long, and why. You’ll install the host app, drop target sources into your project, enable timestamping, and then record—either real-time (via RTT/J-Link) or single-shot (dump a RAM buffer).


✅ Minimal wiring (headers + start)

// main.c #include "SEGGER_SYSVIEW.h" #include "SEGGER_SYSVIEW_Conf.h" // from target sources int main(void) { // ... HAL/init ... SEGGER_SYSVIEW_Conf(); // configure app/device names, RTT, etc. SEGGER_SYSVIEW_Start(); // begin recording (single-shot or live) // create tasks... vTaskStartScheduler(); }

⏱ Enable precise timestamps (Cortex-M3/M4/M7)

// Enable DWT cycle counter (timestamps) #define DEMCR (*(volatile uint32_t*)0xE000EDFC) #define DWT_CTRL (*(volatile uint32_t*)0xE0001000) #define DWT_CYCCNT (*(volatile uint32_t*)0xE0001004) static inline void dwt_time_start(void){ DEMCR |= (1u<<24); // TRCENA DWT_CYCCNT = 0; // reset DWT_CTRL |= 1u; // CYCCNTENA }

Call dwt_time_start() early in main() before starting the scheduler.


⚙️ FreeRTOS config touch-ups

// FreeRTOSConfig.h #define configUSE_TRACE_FACILITY 1 #define configTICK_RATE_HZ 1000 // 1 ms ticks (typical)

(If you don’t use software timers, you can set configUSE_TIMERS to 0 to skip the timer task.)


๐Ÿ” Real-time vs. ๐Ÿ–ผ Single-shot

  • Real-time (continuous): J-Link + RTT streams events to the PC as they happen.

  • Single-shot: Fill the RTT buffer in RAM, pause, dump it to a .SVDat file, then File → Load Data in SystemView.

Tip (single-shot): In your IDE, locate the RTT control symbol (e.g., _SEGGER_RTT), open Memory Browser at its address, and Export RAW for the configured buffer size (e.g., 4096 bytes).


๐Ÿ—ฃ Sending messages to the timeline (cleanly)

#include <stdio.h> static char msg[100]; snprintf(msg, sizeof(msg), "Hello from %s", "Task-1"); SEGGER_SYSVIEW_PrintfTarget("%s", msg); // appears in Terminal & Timeline

๐Ÿงน Avoid garbled prints under pre-emption

Shared sinks (ITM/UART) need a mutex or switch to co-operative segments using taskYIELD() after complete messages.


⚡ Pro Tips

  • Increase SEGGER_SYSVIEW_RTT_BUFFER_SIZE (e.g., 4096) if you drop events.

  • Define the right core in SystemView config (e.g., Cortex-M3/M4/M7).

  • Keep include paths for SEGGER/Config, SEGGER/OS, and SEGGER target folders.

  • In Cube projects, put changes inside USER CODE BEGIN/END blocks.

๐ŸŽฏ Conclusion

Wire up SystemView once, and you’ll never guess again—timestamps, context switches, ISR time, CPU load are all on one timeline.


Written By: Musaab Taha


This article was improved with the assistance of AI.

No comments:

Post a Comment