How to use SystemView Heap Monitoring

From SEGGER Wiki
Jump to: navigation, search

Intro

This document explains how to use the SystemView heap functionality by adapting the existing code in the least intrusive way. A downloadable Embedded Studio project illustrating these techniques is provided too. Although reading the SystemView manual is not a prerequisite for understanding this tutorial, it is highly recommended to consult it (and the SEGGER Linker manual) for a deeper understanding of the topic, and especially the SEGGER_SYSVIEW_Heap* APIs.

Initializing SystemView

The SEGGER_SYSVIEW_Init function must be called on the target before SystemView is connected to it and before any other SystemView APIs are executed. In our case, it is called by the SEGGER_SYSVIEW_Conf function, which is part of the HW initialization functionality defined in the OS_InitHW function. Please refer to the SystemView manual and the attached example for getting more details.

SystemView Heap APIs

To provide the heap usage data to SystemView, the following APIs must be used:

SEGGER_SYSVIEW_HeapDefine
Describes the internal heap organization. The heap memory can be organized in many different ways on embedded systems, therefore the specifics of the one used in the concrete case must be provided by using this function. Taking a look into the linker script file and using some of the symbols it defines will most likely be needed too (e.g. __heap_start__ and __heap_size__ in the example project). This function must be called prior to using any SystemView heap APIs, therefore it is called as part of the callback argument of the SEGGER_SYSVIEW_Init function. Please consult the SystemView manual and the attached example for getting more details. Here are some of the metadata sizes for different SEGGER heap libraries:
Basic Heap Library
sizeof(size_t) + sizeof(void*)
Real-Time Heap Library
sizeof(size_t) + 3 * sizeof(void*)
Minimal Heap Library
0 (NOTE: the minimal heap library is not a complete heap manager because no freeing is possible)
SEGGER_SYSVIEW_HeapAlloc
Should be called each time an allocation has been done. Keep in mind to provide the real internally allocated chunk, which is usually bigger than the one requested by the user.
SEGGER_SYSVIEW_HeapFree
Should be called each time memory has been freed.

So, these APIs must accompany the calls to their respective heap management counterparts. In this article we will cover the case of C standard library heap functions malloc, realloc, and free (the calloc function is left out because it is just a variant of malloc, and it would be trivial to implement it by following the malloc example), and the question arises: how to do this most efficiently in case of existing projects (i.e. not the ones created from scratch with this information in mind)?

Linker Wrapping of Heap Functions

Existing projects might already reference C standard library functions in many places in the code. Using conventional programming methods, to enable calling the counterpart SystemView APIs too, a user would then be forced to substantially change the existing code by introducing wrapper functionality for these calls and substitute all references to the stdlib heap functions in the code with it. Luckily, the SEGGER linker provides a generic wrapping functionality for any linker symbol. By issuing --wrap <function_name> (a linker command-line example), the linker will rename the existing definition to __real_<function_name>, and resolve any calls to the function <funtion_name> to __wrap_<function_name>. A user would then define the __wrap_malloc, __wrap_realloc and __wrap_free functions which will most likely call the __real_malloc, __real_realloc and __real_free (or an own custom heap management functionality, see this article on the custom heap case), accompanied by the corresponding calls to SEGGER_SYSVIEW_HeapAlloc and SEGGER_SYSVIEW_HeapFree.

This linker wrapping functionality can be comfortably invoked through Embedded Studio by adding the following lines in the Project Options/Linker/Additional Linker Options dialog:

es additional linker options2.png

Example Code

The example Embedded Studio project code (SystemView_malloc_example.7z) uses embOS as an underlying real-time OS. Three tasks are created which do some somewhat random allocations and corresponding deallocations, by using the standard C heap functionality. Because of the linker wrapping functionality described above, these calls will yield calling the SystemView heap APIs too, which will dispatch the necessary information to the SystemView app.

A sample saved SystemView session with the heap messages is available here for offline (i.e. without a target HW) usage: embOS_Heap.SVData.