Embedded Studio Library Heap Locking

From SEGGER Wiki
Jump to: navigation, search

Using the heap has become common in modern embedded applications. Even if malloc() and free() are not directly called, heap might be required with C++ new operator.

Embedded applications usually implement one heap, which is used by the whole system. When using an RTOS with multi-tasking or interrupt service routines (ISRs) which use the heap, the system needs to make sure that heap operations are not interrupted by another operation which might corrupt the heap.

Library Heap Locking

The Embedded Studio Runtime Library implements hooks to do heap locking and provides ready-to-use heap-locking mechanisms. The mechanism to be used in a project can easily be selected in the project options at Library -> Library Heap Locking.

Disable Interrupts

Heap operations are locked by disabling global interrupts.

On most systems all IRQs are disabled, only FIQs (where available) are left untouched.

User

Heap operations call user-supplied functions __heap_lock and __heap_unlock. These functions can be defined to implement system-specific heap locking.

The functions to be implemented are:

void __heap_lock(void);
void __heap_unlock(void);

Possible heap locking mechanisms could be:

  • Partially disable interrupts.
  • Lock/unlock a mutex or semaphore.
  • Enter a critical region.

Multi-core systems with shared heap might require further locking, such as a spinlock implemented with atomic operations.

Example: Lock with disable interrupts

When using an RTOS, it might be sufficient to disable only the interrupts which are handled by the OS and leave high-priority interrupts, which must not be blocked and do not use the heap, unblocked.

This example shows locking interrupts with embOS.

 #include <__libc.h>
 #include "RTOS.h"
 
 OS_U32 IntState;
 
 void __heap_lock(void) {
   OS_INT_PreserveAndDisable(&IntState);
 }
 
 void __heap_unlock(void) {
   OS_INT_Restore(&IntState);
 }

Example: Lock with Mutex

Heap locking with a mutex depends on the underlying RTOS. This example shows using a mutex with embOS.

Note: Mutexes might be usable only in tasks. If heap is used in interrupts, another mechanism needs to be implemented.

 #include <__libc.h>
 #include "RTOS.h"
 
 bool IsInitialized;
 OS_MUTEX HeapMutex;
 
 void __heap_lock(void) {
   if (!IsInitialized) {
     OS_TASK_EnterRegion();
     if (!IsInitialized) {
       IsInitialized = true;
       OS_MUTEX_Create(&HeapMutex);
     }
     OS_TASK_LeaveRegion();
   }
   OS_MUTEX_LockBlocked(&HeapMutex);
 }
 
 void __heap_unlock(void) {
   OS_MUTEX_Unlock(&HeapMutex);
 }