Skip to content



FreeRTOS »

SEGGER SystemView - Record and Visualize System Activities

SEGGER's SystemView (SysView) is a real-time recording and visualization tool for embedded systems that reveals the true runtime behavior of an application, going far deeper than the system insights provided by debuggers. This is particularly effective when developing and working with complex embedded systems comprising multiple threads and interrupts. System View can ensure a system performs as designed, can track down inefficiencies, and find unintended interactions and resource conflicts.


J-Link System View — Manual SEGGER_SysView.zip STM32-Tutorials

System View#

Visit the Official J-Link System View page on SEGGER website for more information.

SEGGER’s J-Link System View is written on top of the excellent J-Link Real-Time Transfer to record many types of events in real-time in an embedded system. Those events can be interrupts, timers, task switches and scheduling within an RTOS, API function calls and returns, or user events and messages. The events are retrieved from the target, analyzed and visualized in the System View Application, while the target keeps running.

System View may be used with a non-commercial license for evaluation, educational and hobbyist purposes. When using System View under the non-commercial license, no activation is required.

How System View works#

To keep the communication overhead on the target system low, it only needs to record basic information, such as Function with ID X is called with parameter values y and z at the n ticks after the last event. System View analyzes all information from the events and shows:

  • The recording time or system time when the call happened
  • The task/context in which the call happened
  • The interrupt name, timer ID, and marker name
  • The API function name and its parameters and values
  • The duration of the any pair of start-stop, enter-exit events

The timestamps for events can be as accurate as 1 CPU cycle. A regular event is just 4 to 8 bytes long.

What System View helps#

Issues and inefficiencies in the system can be identified below ways:

  • Incorrect task priorities or priority inversion leading to starvation
  • Incorrect inter-task communication
  • Inefficient delays and timeouts
  • Spurious or unnecessary interrupts
  • Unexpected log run-time of a short task

High CPU Load can lead to:

  • Bottlenecks which may lead to delayed execution of important tasks
  • Dropped data or overflow of incoming buffer

System View APIs#

The SEGGER System View implementation is written in ANSI C on the top of RTT, therefore, it can be easily integrated into any embedded application. The System View needs to be initialized before it can be used. However, it does not automatically run to reduce CPU Load and power usage. System View only runs when it gets request from Host’s System View Application.


Control functions

Function Description
SEGGER_SYSVIEW_Init() Initializes the SYSVIEW module
SEGGER_SYSVIEW_Start() Start recording System View events. This function is triggered by the System View Application on connect.
SEGGER_SYSVIEW_Stop() Stop recording System View events. This function is triggered by the System View Application on disconnect.


Configuration functions

Function Description
SEGGER_SYSVIEW_Conf() Initialize and configures System View
SEGGER_SYSVIEW_SetRAMBase() Sets the RAM base address
SEGGER_SYSVIEW_SendSysDesc() Send the system description string to the host
SEGGER_SYSVIEW_SendTaskList() Send all tasks descriptors to the host
SEGGER_SYSVIEW_SendTaskInfo() Send a Task Info Packet, containing TaskId for identification, task priority and task name
SEGGER_SYSVIEW_X_GetTimestamp() Callback called by System View to get the timestamp in cycles


Event recording functions

Function Description
SEGGER_SYSVIEW_RecordEnterISR() Format and send an ISR entry event
SEGGER_SYSVIEW_RecordExitISR() Format and send an ISR exit event
SEGGER_SYSVIEW_RecordEnterTimer() Format and send a Timer entry event
SEGGER_SYSVIEW_RecordExitTimer() Format and send a Timer exit event
SEGGER_SYSVIEW_OnIdle() Record an Idle event
SEGGER_SYSVIEW_OnTaskCreate() Record a Task Create event
SEGGER_SYSVIEW_OnTaskStartExec() Record a Task Start Execution event
SEGGER_SYSVIEW_OnTaskStartReady() Record a Task Start Ready event
SEGGER_SYSVIEW_OnTaskStopExec() Record a Task Stop Execution event
SEGGER_SYSVIEW_OnTaskStopReady() Record a Task Stop Ready event
SEGGER_SYSVIEW_OnTaskTerminate() Record a Task termination event
SEGGER_SYSVIEW_MarkStart() Record a Performance Marker Start event to start measuring runtime
SEGGER_SYSVIEW_Mark() Record a Performance Marker intermediate event
SEGGER_SYSVIEW_MarkStop() Record a Performance Marker Stop event to stop measuring runtime


User API recording functions

Function Description
SEGGER_SYSVIEW_RecordVoid() Formats and sends a System View packet with an empty payload
SEGGER_SYSVIEW_RecordU32() Formats and sends a System View packet containing a single U32 parameter payload
SEGGER_SYSVIEW_RecordU32x[2:10]() Formats and sends a System View packet containing [2:10] U32 parameter payload
SEGGER_SYSVIEW_RecordString() Formats and sends a System View packet containing a string
SEGGER_SYSVIEW_RecordEndCall() Format and send an End API Call event without return value.
SEGGER_SYSVIEW_RecordEndCallU32() Format and send an End API Call event with a return value


Message recording functions

Function Description
SEGGER_SYSVIEW_Print() Print a string to the host
SEGGER_SYSVIEW_Warn() Print a warning string to the host
SEGGER_SYSVIEW_Error() Print an error string to the host
SEGGER_SYSVIEW_PrintfHost() Print a string which is formatted on the host by the System View Application
SEGGER_SYSVIEW_WarnfHost() Print a string which is formatted on the host by the System View Application
SEGGER_SYSVIEW_ErrorfHost() Print an error string which is formatted on the host by the System View Application

To reduce CPU cycles used by System View to format strings, System View function *fHost() just sends a raw string and its params to the host!

System View Integration#

Install the System View Application firstly at System View download page.

After installation, go the application folder to get the latest source code of System View target integration, for example C:\Program Files\SEGGER\System View\Src. Here is SEGGER_SysView.zip at version 3.32.

├─Config
│     Global.h                          # Typedef for data types
│     SEGGER_RTT_Conf.h                 # Default RTT configs
│     SEGGER_SYSVIEW_Conf.h             # User SysView Configs
|
├──SEGGER
│  │   SEGGER.h                         # Segger common defines
│  │   SEGGER_RTT.h                     # RTT Header
│  │   SEGGER_RTT.c                     # RTT implementation
│  │   SEGGER_RTT_ASM_ARMv7M.S          # for Cortex-M3/M4
│  │   SEGGER_RTT_printf.c              # Print functions
│  │   SEGGER_SYSVIEW_ConfDefaults.h    # SysView Default Configs
│  │   SEGGER_SYSVIEW_Int.h             # SysView Internal defines
│  │   SEGGER_SYSVIEW.h                 # SysView header
│  │   SEGGER_SYSVIEW.c                 # SysView implementation
│  │
│  └───Syscalls                         # Standard IO redirection
│
└─Sample                                # Sample configs for different targets
  ├───COMM                              # Example to record on UART
  ├───embOS                             #
  ├───FreeRTOSV10                       #
  ├───FreeRTOSV8                        #
  ├───FreeRTOSV9                        #
  ├───MicriumOSKernel                   #
  ├───uCOS-II                           #
  ├───uCOS-III                          #
  └───NoOS                              # Run without OS
     └───Config
         ├───RX
         ├───Cortex-M                   # 
         │       SEGGER_SYSVIEW_Config_NoOS.c
         └───Cortex-M0                  # Special setup for Cortex-M0
                 SEGGER_SYSVIEW_Config_NoOS_CM0.c

You can copy all files to your projects and add them to Paths and Symbols settings.

System View with FreeRTOS#

F411RE_FreeRTOS_SysView.zip

There is an example of integration System View on FreeRTOS using STM32CubeMX code generator. This guide is to add System View on the latest FreeRTOS version.

Import System View files#

The published SEGGER_SysView has 3 folders, here are what we will use:

  • Config
  • SEGGER
  • Sample/FreeRTOSV10.4

Copy all of those files to the project.

Add System View files for FreeRTOS to project

Apply patch#

SEGGER provides a patch for FreeRTOS 10.4.3 which can be used or FreeRTOS 10.4.6 also.

Configure System View#

  1. Include SEGGER_SYSVIEW_FreeRTOS.h at the end of the file FreeRTOSConfig.h to override some RTOS definitions of tracing functions.

  2. Finally, configure System View in the file SEGGER_SYSVIEW_Config_FreeRTOS.c which sends System Information, Interrupt ID & Name, Timers and Markers.

    #define SYSVIEW_APP_NAME        "Demo RTOS Application"
    #define SYSVIEW_DEVICE_NAME     "STM32F411RE"
    #define SYSVIEW_CORE_NAME       "Cortex-M4"
    #define SYSVIEW_OS_NAME         "FreeRTOS"
    
    #define SYSVIEW_RAM_BASE        (0x20000000)
    
    static void _cbSendSystemDesc(void) {
    SEGGER_SYSVIEW_SendSysDesc("N="SYSVIEW_APP_NAME","
                               "D="SYSVIEW_DEVICE_NAME","
                               "C="SYSVIEW_CORE_NAME","
                               "O="SYSVIEW_OS_NAME);
    SEGGER_SYSVIEW_SendSysDesc("I#15=SysTick");
    }
    
  3. Include SEGGER’s headers and call to SEGGER_SYSVIEW_Conf() to initialize System View:

    #include "SEGGER_SYSVIEW_Conf.h"
    #include "SEGGER_SYSVIEW.h"
    
    int main() {
        SEGGER_SYSVIEW_Conf();
        ...
    }
    

Implement an application#

We will create 2 tasks which print out 2 different messages to a shared Serial Wire Output using a Mutex.


Declare 2 messages, 2 tasks, and a mutex:

main.c
char* message1 = "................................................................";
char* message2 = "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";

TaskHandle_t task1Handler;
TaskHandle_t task2Handler;
SemaphoreHandle_t writeAccessMutex;

Redirect printf to SWO:

We add two logs to see the content of the message before and after the loop of writing out. We know that if reentrant is not enable, the printing buffer might be replaced. The log will help us to confirm the issue.

main.c
int _write(int file, char *ptr, int len) {
    char *msg = ptr;
    SEGGER_SYSVIEW_Print(msg);
    // wait for other to complete printing
    if ( xSemaphoreTake( writeAccessMutex, ( TickType_t ) portMAX_DELAY) == pdTRUE ) {
      int DataIdx;
      for (DataIdx = 0; DataIdx < len; DataIdx++) {
        ITM_SendChar(*ptr++);
      }
      SEGGER_SYSVIEW_Print(msg);
      // done our job
      xSemaphoreGive (writeAccessMutex);
    }
    return len;
}

The PrintTask prints out the selected messages

main.c
void PrintTask(void *argument) {
  char* name = pcTaskGetName(NULL);
  char* message = (char*)argument;
  char counter = 0;
  for(;;) {
    printf("%s: %03d %s\r\n",
        name,
        counter++,
        message
    );
    vTaskDelay(100);
  }
}

The main program initializes 2 tasks, 1 mutex, and starts the scheduler

main.c
int main(void)
{
  SystemInit();

  writeAccessMutex = xSemaphoreCreateMutex();

  xTaskCreate(
      PrintTask,
        "Task1",
        configMINIMAL_STACK_SIZE,
        (void *) message1,
        1,
        &task1Handler);

  xTaskCreate(
      PrintTask,
        "Task2",
        configMINIMAL_STACK_SIZE,
        (void *) message2,
        1,
        &task2Handler);

  vTaskStartScheduler();

  for(;;);
}

Build and run#

When build and run, you will see the messages printed out on SWC channel 0 as below:

Corrupted messages from Task 2

We will use System View to debug the issue by follow one of below modes.

System View mode#

The SEGGER System View provides 3 modes:

  • Real-time (continuous) recording: this mode streams the system view events through a debugger to an application to visualize data in real-time. A debugger must be attached to the target.

  • Single-shot recording: this mode is started manually by calling SEGGER_SYSVIEW_Start(), then events are recorded until the System View buffer is filled or SEGGER_SYSVIEW_Stop() is called. Debugger is not needed while recording. Any debugger can e used to download recorded data into System View data file.

  • Postmortem recording: this mode is started manually by calling SEGGER_SYSVIEW_Start(), then events are recorded SEGGER_SYSVIEW_Stop() is called. Older events are overwritten when the System View buffer is filled. Debugger is not needed while recording. Any debugger can e used to download recorded data into System View data file.

System View recording modes

Real-time mode#

Run SEGGER System Viewer and connect a J-Link debugger to the target.

If you pause the recording, and trace the Task 2, you will notice that the second log in the _write() function of Task 2 prints out the content of Task 1’s message.

Refer to the Reentrant Debug section to understand how issue happens.

Continuously record data

Single-shot#

We need to investigate the saved System View data in memory. In single-shot mode, we call to SEGGER_SYSVIEW_Start() after the call to SEGGER_SYSVIEW_Config().


Find the address of UP BUFFER

Get the address of RTT Buffers

Dump System View buffer

Dump memory to raw binary file

Load saved System View single-shot data

Loaded System View data

The number of events recorded is not much, but they are enough to see the problem in the Task 2 as discussed above.

Postmortem#

This mode is similar to the Single-shot mode.

To enable this mode, set the below definition:

#define SEGGER_SYSVIEW_POST_MORTEM_MODE     1

And doing the same steps as Single-shot mode to dump System View data and open it.

Comments