Heap
In an embedded software program, memory can be dynamically allocated. The heap is available for this, which is a part of RAM specifically reserved for dynamically allocated memory.
The C standard library offers the functions malloc()
and free()
for allocating
and releasing memory on the heap. Both functions treat the heap as a byte pool, which
means there is always a fragmentation risk present. The fragmentation eventually
leads to a situation where memory can no longer be allocated, resulting in lost
functionality or a crash of the software program in the worst case.
This fragmentation risk is therefore unacceptable and another solution needs to be found for handling dynamic allocation. The solution is two-fold:
- Use static memory preallocation. This entails performing the memory allocation once during software program initialization and never releasing (free-ing) the allocated memory. This means that the lifetime of the allocated data spans the run-time of the entire software program.
- Use memory pools. With a memory pool, memory is allocated as fixed-size memory blocks (partitions). The benefit of dynamic memory allocation using memory pools is that the memory can be released again without the before mentioned fragmentation risk. It is perfect in situations when temporary data storage is needed, and the lifetime of the data is longer than just one function.
MicroTBX offers software components for both solutions. The heap software component described in this section covers solution (1) with static memory preallocation. The memory pools software component covers solution (2).
Usage
The heap software component offers the function TbxHeapAllocate()
for performing
memory allocation on the heap. Because it is meant for static memory preallocation
only, there is no function for free-ing the allocated memory. The idea is that
function TbxHeapAllocate()
is only called during the initialization of the
software program, so before the infinite program loop is entered. It is basically
its own implementation of malloc()
, without free()
.
To find out how many bytes of memory are still available on the heap, function
TbxHeapGetFree()
can be called.
If a software program has a need to allocate and release memory during the infinite program loop, the memory allocation should be performed with the functionality present in the memory pools software component.
Examples
The following example demonstrates how to call the functions of the heap software component. Memory for a FIFO buffer is preallocated during the software program initialization.
/* A first-in first-out buffer of 32-bit values. */
uint32_t * fifoBuffer = NULL;
uint32_t const fifoMaxSize = 32;
uint8_t fifoIdx;
/* Make sure there is enough space on the heap for the FIFO buffer. */
if (TbxHeapGetFree() < (fifoMaxSize * sizeof(uint32_t)))
{
TBX_ASSERT(TBX_FALSE);
}
/* Perform static preallocation of the FIFO buffer. */
fifoBuffer = TbxHeapAllocate(fifoMaxSize * sizeof(uint32_t));
/* Make sure the allocation was successful. */
TBX_ASSERT(fifoBuffer != NULL);
/* Initialize the FIFO buffer. */
for (fifoIdx = 0; fifoIdx < fifoMaxSize; fifoIdx++)
{
fifoBuffer[fifoIdx] = 0;
}
Configuration
The maximum size of the heap is configured with macro TBX_CONF_HEAP_SIZE
:
/** \brief Configure the size of the heap in bytes. */
#define TBX_CONF_HEAP_SIZE (2048U)