There is a new feature in the SEGGER SystemView: the ability to plot any data provided by the application, for example sensor data or any other useful data:

Outline
The SEGGER SystemView is a real-time recording and visualization tool for embedded systems. The application gets instrumented and sends messages to the host. SystemView on the host then visualizes the data, generating deep insights into timing and application behavior. SystemView is free-of-charge for non-commercial or educational usage.
Back in April 2023, I explored using SystemView to track FreeRTOS memory allocation. See Added Heap Memory Monitoring and Tracking to FreeRTOS V10.5 for details. At that time I submitted to SEGGER a wish: a way to send and show data in SystemView. For example the available amount of dynamic memory available in the system. Another use case is a power measurement probe and hardware: why not send the sensor data to SystemView?
It was with the announcement of SystemView 3.56, when I saw this:
New Features SystemView: Data Plot Window added. Target source: Added support for data sampling events.
There is no real documentation about it. This article describes how to use it. And example and a McuLib implementation is provided on GitHub (see links at the end of this article).
SystemView 3.56 API
First, you have to upgrade the SystemView application code to version 3.56 or later. The McuLib already has included it.
The new version adds a new message ID:
#define SYSVIEW_EVTID_DATA_SAMPLE 23 The API includes a function to register a data type:
void SEGGER_SYSVIEW_RegisterData (SEGGER_SYSVIEW_DATA_REGISTER* pInfo); Finally, a function to send data:
void SEGGER_SYSVIEW_SampleData (const SEGGER_SYSVIEW_DATA_SAMPLE *pInfo); SystemView 3.56 GUI
The new SystemView includes a view for the ‘Data Plot’ plus shows the message ‘Data Sample’ in the timeline:

Multiple data items can be displayed an configured with Y-Offset and Scaling Factor:

Data Sampling Example
In the next sections I go through the steps how to use it. I’m using the Eclipse based MCUXpresso IDE with the NXP FRDM-K64F board. It works the same for any IDE or board. You can find the example on GitHub, sending the accelerometer x, y and z sensor values.

Configuration Callback
SystemView gets configured by a callback, executed at connection time. In the callback we tell which OS is used, plus what data values we are going to send.
First, we enable the application configuration callback with a define:
#define McuSystemView_CONFIG_SYSVIEW_CONFIG_CALLBACK App_SysView_ConfigCallback This tells SystemView that it shall call the function App_SysView_ConfigCallback() to configure it.
Configuration and Register Data
Below is an example configuration: It tells SystemView the application name, the OS we are using plus the device on the board, plus that Interrupt #15 is the SysTick:
void App_SysView_ConfigCallback(void) { /* configured with McuSystemView_CONFIG_SYSVIEW_CONFIG_CALLBACK */ SEGGER_SYSVIEW_SendSysDesc("N="SYSVIEW_APP_NAME",O="SYSVIEW_OS_NAME",D="SYSVIEW_DEVICE_NAME); SEGGER_SYSVIEW_SendSysDesc("I#15=SysTick"); SEGGER_SYSVIEW_RegisterData((SEGGER_SYSVIEW_DATA_REGISTER*)®dataX); SEGGER_SYSVIEW_RegisterData((SEGGER_SYSVIEW_DATA_REGISTER*)®dataY); SEGGER_SYSVIEW_RegisterData((SEGGER_SYSVIEW_DATA_REGISTER*)®dataZ); } One can see the effect of this in the SystemView timeline:

The calls to SEGGER_SYSVIEW_RegisterData() tell SystemView that we are going to use three data items: one for X, one for Y and one for Z.
RegisterData Descriptor
To SEGGER_SYSVIEW_RegisterData() a pointer to a data descriptor gets passed, which looks like this:
#define SEGGER_SYSVIEW_DATA_ID_ACCEL_X (0) static const SEGGER_SYSVIEW_DATA_REGISTER regdataX = { .ID = SEGGER_SYSVIEW_DATA_ID_ACCEL_X, .DataType = SEGGER_SYSVIEW_TYPE_I32, .Offset = 0, .RangeMin = 0, .RangeMax = 0, .ScalingFactor = 1.0f, /* important: set to non-zero! */ .sName = "Accel X", .sUnit = "mg" }; Each data has a identification number (ID) and a data type (float, uint32 or int32), offset, range and scaling factor.
💡 Scaling factor has to be larger than zero!
Additionally each data can have a name and unit. The data properties are shown in SystemView with name, unit scaling factor and offset:

Data Item Descriptor
To send data items, one has to configure a descriptor. It has the ID plus a pointer to the data:
I32 accelX = 0; const SEGGER_SYSVIEW_DATA_SAMPLE accelXdata = { .ID = SEGGER_SYSVIEW_DATA_ID_ACCEL_X, .pI32_Value= &accelX, }; Sending Data
Finally, this is how to send data, with the example of the X, Y and Z accelerometer values:
for(;;) { ACCEL_GetValues(&x, &y, &z); /* get sensor values (int16_t) */ /* convert to 32bit (I32): */ accelX = x; accelY = y; accelZ = z; /* send data */ SEGGER_SYSVIEW_SampleData(&accelXdata); SEGGER_SYSVIEW_SampleData(&accelYdata); SEGGER_SYSVIEW_SampleData(&accelZdata); vTaskDelay(pdMS_TO_TICKS(5)); } 💡 As the sensor returns 16bit values, I have to assign and convert them to 32bit.
Data In SystemView
Finally, connect with SystemView to the running application. Now you should see the Data Sample messages plus the Data Plot with the values:

Congratulations, you are using a brand new feature! 🙂
Summary
SystemView is a very useful application to trace and monitor real-time applications. I can now send any arbitrary data. With the addition of Data Sample messages and the Data Plot view, I can visualize it in SystemView. There are other ways to visualize data (for example check out FreeMASTER). As I’m using SystemView with all my RTOS applications. The addition of data logging and visualization to SystemView makes it very easy to use. There is no other overhead except for sending the data elements.
Happy plotting 🙂
Links
- Segger SystemView: https://www.segger.com/downloads/systemview/
- Example project on GitHub: https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/MCUXpresso/FRDM-K64F/FRDM-K64F_McuOnEclipseLib
- McuLib on GitHub: https://github.com/ErichStyger/McuOnEclipseLibrary

Thanks, Erich for checking it out!
Your feedback is also very valuable and we will incorporate this in the upcoming version, so we will also support integer / unsigned values, so that a conversion is no longer necessary.
We are in fact also using it with our Flashers / J-Links to monitor voltage and current, and it does indeed proof quite useful.
Especially where Systemview is already in use, the additional overhead is minimal.
Happy sampling!
LikeLike
Hi Rolf,
So far it really works well, and has been useful with multiple sensor values for me.
LikeLike
Hi Erich, your posts are very interesting as always.
Is there a plugin in Eclipse to see SystemView data in debug perspective?
Thanks a lot
Roberto
LikeLike
Hi Roberto,
thanks :-). I only checked out ‘impulse’years ago, but was never able to get it fully working, see https://mcuoneclipse.com/2016/07/31/impulse-segger-systemview-in-eclipse/
I’m not aware of any other solution inside an IDE.
I hope this helps?
LikeLike