Embedded Studio Library Heap

From SEGGER Wiki
Revision as of 13:09, 16 May 2024 by Simon Buchholz (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Embedded Studio's runtime library, based on emRun, implements different variants of heap allocators to fit the needs of embedded systems.

Library Heap

The allocator variant for the heap can be easily selected in the project options (Code -> Library -> Library Heap)

Basic Allocator

The basic heap allocator is a small and simple variant as found in many libraries for common use cases. It implements a low-overhead best-fit heap where allocation and deallocation have very little internal fragmentation.

Real-Time Allocator

The real-time allocator implements a two-level segregated fit heap model with constant-time (O(1)) performance.

Background story: https://blog.segger.com/c-real-time-allocation-a-chess-engine

Minimal Allocator

The minimal allocator implements an allocate-only heap where deallocation and reallocation are not implemented.


When "None" is selected, Embedded Studio will not provide an allocator implementation. Users can supply their own allocator.

If heap is not used at all, the Library Heap does not need to be set to None. No overhead is produced by any implementation if not called from the application.

Heap Size

The heap size can be set in project options Code -> Runtime Memory Area -> Heap Size and is passed as __HEAPSIZE__ to the linker.

When used with the supplied allocators, heap size must be a multiple of 8 bytes and at least 48 bytes. The heap block must be 8 bytes aligned. The SEGGER Linker scripts in Embedded Studio-generated projects include checks to assert in case of mis-configuration.

Heap Initialization

The heap block and allocator needs to be initialized before any heap operation.

In Embedded studio-generated projects using the SEGGER Linker this is done by the linker-generated initilization code calling __SEGGER_init_heap when heap is used.

initialize by calling __SEGGER_init_heap /* if USES_ALLOC_FUNC */ { block heap };

With the GNU Linker all sections need to be statically initialized in the runtime initialization code (such as in thumb_crt0.s).

#if !defined(__HEAP_SIZE__) || (__HEAP_SIZE__)
  /* Initialize the heap */
  ldr r0, = __heap_start__
  ldr r1, = __heap_end__
  subs r1, r1, r0
  bl __SEGGER_RTL_init_heap

Note: The startup code of projects created with Embedded Studio V5 or earlier might need to be upgraded with $(StudioDir)/source/thumb_crt0.s There must be no manual initialization of the heap.

Wrong (old) code: Replace this with the code above.

  /* Initialize the heap */
  ldr r0, = __heap_start__
  ldr r1, = __heap_end__
  subs r1, r1, r0
  cmp r1, #8
  blt 1f
  movs r2, #0
  str r2, [r0]
  adds r0, r0, #4
  str r1, [r0]