Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Segger SystemView: Realtime Analysis and Visualization for FreeRTOS

DZone's Guide to

Segger SystemView: Realtime Analysis and Visualization for FreeRTOS

Go beyond what traditional debuggers can provide with Segger's analysis tools.

· Performance Zone
Free Resource

One of the most important aspects for developing complex realtime applications is get insights into what is going on the target. Segger just has released a free tool which gives an incredible useful insight view and visualization:

Segger System View for FreeRTOS

Segger System View for FreeRTOS

Segger has announced the tool last week (see https://www.segger.com/systemview.html). It works both bare-metal (no RTOS) and with using an RTOS. The V2.10 release on the web page includes support for the Segger embOS. When I contacted Segger about the possibility to use it with FreeRTOS, they provided me with their first FreeRTOS port (V2.11) (MANY THANKS!!!!), and I was able to get it quickly up and running and integrated both with Processor Expert and Kinetis SDK :-).

The Segger SystemViewer is based on Segger RTT (see “Using Segger Real Time Terminal (RTT) with Eclipse“): all what it needs is a few functions on the target which communicate to the host over the Segger J-Link debug connection. It is super fast and provides the ability to collect almost unlimited trace data.

Tutorial

To make usage of RTT and SystemView very easy for any Kinetis devices, I have created special Processor Expert components: one for RTT and one for the SystemView.

:idea: I have it working well on ARM Cortex-M4(F). The implementation for ARM Cortex-M0+ is still experimental!

  1. Download the Segger SystemView files from Segger: https://www.segger.com/systemview.html
  2. Download and install the latest McuOnEclipse components from https://sourceforge.net/projects/mcuoneclipse/files/PEx%20Components/ and have them installed (see “McuOnEclipse Releases on SourceForge“)
  3. The easiest way is to use it with a Processor Expert project (with or without the Kinetis SDK). You can enable/disable SystemView for an existing project as well.
  4. Add the SeggerSystemView component to the project: it will add/ask for the SeggerRTT component too: Segger RTT and SystemView Components Segger RTT and SystemView Components
  5. In my applications I’m using the RTT channel 0 for console/shell/terminal communication. Therefore I’m having two up/down channels: channel 0 for the terminal, and channel 1 for SystemView: Segger RTT Configuration Segger RTT Configuration
  6. In the SeggerSystemView component I specify the channel I would like to use (channel 1 in the example below, as I’m using channel 0 for the terminal). I can specify an application name and device identification string. The RAM Base setting specifies the lowest RAM address: Segger SystemView Settings Segger SystemView Settings
  7. Finally, in the FreeRTOS component I enable the Segger System Viewer trace. This will add the necessary trace macros to the Kernel to write all the trace data information. Segger System View Trace Setting in FreeRTOS Segger System View Trace Setting in FreeRTOS

That’s it :-). Generate code and download it to the target as usual. To record the trace, launch the Segger System Viewer application and press ‘record’:

Recording Segger SystemView Trace Data

Recording Segger SystemView Trace Data

FreeRTOS

The Segger SystemView does not need (well: want) any information about the FreeRTOS IDLE task: any time where there is no task activity, this is marked automatically as ‘idle’. It is best if xTaskGetIdleTaskHandle() is enabled:

xTaskGetIdleTaskHandle

xTaskGetIdleTaskHandle

If not using Processor Expert, make sure that

INCLUDE_xTaskGetIdleTaskHandle

is set to 1 in FreeRTOSConfig.h.

Additionally, for better task information, FreeRTOS trace macros have been extended by

tracePOST_MOVED_TASK_TO_READY_STATE
#define prvAddTaskToReadyList( pxTCB )                                                                \
    traceMOVED_TASK_TO_READY_STATE( pxTCB );                                                        \
    taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority );                                                \
    vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) ); \
    tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB )

Segger System Viewer Application

The SEGGER SystemViewer has several views which give me insights what is going on.

In the ‘Events’ all the target events with the details are listed:

Events View

Events View

In the Timeline view I see the different task running over time:

Timeline view

Timeline view

In the CPU load view I see the CPU load in a realtime way:

CPU Load View

CPU Load View

And the Contexts view gives me timing/profiling information:

Contexts View

Contexts View

Example

To give you an example how useful that data is: below is an application which has been stalled after a while because it was blocked by the USB stack: after getting that information, I was able to implement a fix :-)

Problem with USB CDC

Problem with USB CDC

The problem was that the USB SendDataBlock() method was waiting without a timeout as long as a transaction is going on. In the case of a USB communication problem, this results in a very long blocking time.

The solution was to enable a timeout for the send operation:

SendDataBlock USB Stack Timeout

SendDataBlock USB Stack Timeout

With this, the SendDataBlock() would gracefully return for the case a transaction does not finish for whatever reason:

uint8_t CDC1_SendDataBlock(uint8_t *data, uint16_t dataSize)
{
  TMOUT1_CounterHandle timeout;
  uint8_t res = ERR_OK;

  transactionOngoing = TRUE;
  if (USB_Class_CDC_Interface_DIC_Send_Data(CONTROLLER_ID, data, dataSize)!=USB_OK) {
    transactionOngoing = FALSE;
    return ERR_FAULT;
  }
  /* wait for transaction finish */
  timeout = TMOUT1_GetCounter(50/TMOUT1_TICK_PERIOD_MS); /* set up timeout counter */
  while(transactionOngoing) { /* wait until transaction is finished */
    CDC1_RunUsbEngine();
    if (TMOUT1_CounterExpired(timeout)) {
      res = ERR_FAILED;
      break;
    }
    WAIT1_WaitOSms(5); /* wait some time */
  }
  TMOUT1_LeaveCounter(timeout); /* return timeout counter */
  return res;
}

Summary

Wow, I’m really impressed! The Segger SystemView is a true treasure for any embedded developer: it collects incredible useful data from a running system, free of charge. All what I need is a Segger J-Link or a J-Link enabled board.

I plan to release the updated Segger RTT and Segger SystemView support with the next McuOnEclipse component release. If you would like to receive the components in the current experimental state, drop me an email (see About) and I’ll help you out. Otherwise simply clone my repostory on GitHub.

Happy Viewing :-)

PS: I would like to thank the company Segger for their support last week to get the Segger SystemViewer running with FreeRTOS!

LINKS

Topics:
kinetis ,analysis

Published at DZone with permission of Erich Styger, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}