======Malloc implementation in FreeRTOS===
Three source files under Source/portable/MemMang, //heap_1.c//, //heap_2.c// and //heap_3.c// provide three different malloc/free implementations.
The simplest is the one in //heap_1.c// which lets you allocate blocks, without being able to deallocate them. Let's examine the code in //heap_1.c//:
static struct xRTOS_HEAP
{
unsigned portLONG ulDummy;
unsigned portCHAR ucHeap[ configTOTAL_HEAP_SIZE ];
} xHeap;
static size_t xNextFreeByte = ( size_t ) 0;
The //portLONG// and //portCHAR// macro's are declared in Source/portable/GCC/ARM_CM3/portmacro.h (as //char// and //long//). //configTOTAL_HEAP_SIZE// is defined in Demo/CORTEX_STM32F103_Primer_GCC/FreeRTOSConfig.h.
The compiler generates assembler directives to align //xHeap// on a 4 byte boundary; this provides the required alignment for //ucHeap//.
Here is the actual allocation routine:
void *pvPortMalloc( size_t xWantedSize )
{
void *pvReturn = NULL;
/* Ensure that blocks are always aligned to the required number of bytes. */
#if portBYTE_ALIGNMENT != 1
if( xWantedSize & heapBYTE_ALIGNMENT_MASK )
{
/* Byte alignment required. */
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & heapBYTE_ALIGNMENT_MASK ) );
}
#endif
vTaskSuspendAll();
{
/* Check there is enough room left for the allocation. */
if( ( ( xNextFreeByte + xWantedSize ) < configTOTAL_HEAP_SIZE ) &&
( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */
{
/* Return the next free byte then increment the index past this
block. */
pvReturn = &( xHeap.ucHeap[ xNextFreeByte ] );
xNextFreeByte += xWantedSize;
}
}
xTaskResumeAll();
return pvReturn;
}
In the case of ARM Cortex-M3 processors, portBYTE_ALIGNMENT is defined to be 4 (in the file Source/portable/GCC/ARM_CM3/portmacro.h). To ensure that the next block also is properly aligned, block sizes requested (//xWantedSize//) have to be multiples of 4.
The portion of the array //ucHeap// from the position indexed by xNextFreeByte to the position indexed by (xNextFreeByte + xWantedSize - 1) is the actual //allocated// block.