Complete the code to select the simplest FreeRTOS heap implementation that does not allow memory to be freed.
void *pvPortMalloc( size_t xSize ) {
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
static size_t xNextFreeByte = 0;
if( ( xNextFreeByte + xSize ) < configTOTAL_HEAP_SIZE ) {
void *pvReturn = &ucHeap[ xNextFreeByte ];
xNextFreeByte += [1];
return pvReturn;
}
return NULL;
}The heap_1 implementation simply moves a pointer forward by the requested size xSize to allocate memory. It does not support freeing memory.
Complete the code to implement a FreeRTOS heap that supports memory freeing by using a linked list of free blocks.
typedef struct A_BLOCK_LINK {
struct A_BLOCK_LINK *pxNextFreeBlock;
size_t xBlockSize;
} BlockLink_t;
static BlockLink_t xStart, *pxEnd = NULL;
void vPortFree( void *pv ) {
BlockLink_t *pxLink = ( BlockLink_t * ) pv - 1;
pxLink->pxNextFreeBlock = xStart.pxNextFreeBlock;
xStart.pxNextFreeBlock = [1];
}When freeing memory, the block being freed (pxLink) is added back to the start of the free list by updating xStart.pxNextFreeBlock to point to it.
Fix the error in the heap_3 implementation where the allocation function does not correctly align the block size.
size_t xWantedSize = xSize + sizeof( BlockLink_t ); /* Align the size to the nearest multiple of [1]. */ xWantedSize = ( xWantedSize + ( [2] - 1 ) ) & ~ ( [3] - 1 );
Heap_3 aligns the block size to the nearest multiple of the pointer size (sizeof(void *)) to ensure proper memory alignment on all platforms.
Fill both blanks to complete the heap_4 allocation function that uses a best-fit algorithm to find a free block.
BlockLink_t *pxBlock = xStart.pxNextFreeBlock; BlockLink_t *pxBestBlock = NULL; size_t xBestSize = ( size_t ) -1; while( pxBlock != pxEnd ) { if( pxBlock->xBlockSize >= [1] ) { if( pxBlock->xBlockSize < xBestSize ) { pxBestBlock = pxBlock; xBestSize = pxBlock->xBlockSize; } } pxBlock = pxBlock->pxNextFreeBlock; } if( pxBestBlock != NULL ) { /* Allocate from pxBestBlock */ /* ... */ }
The best-fit algorithm looks for a free block with size at least xWantedSize and chooses the smallest such block.
Fill all three blanks to complete the heap_5 allocation function that uses a first-fit algorithm and coalesces adjacent free blocks.
BlockLink_t *pxPreviousBlock = &xStart; BlockLink_t *pxBlock = xStart.pxNextFreeBlock; while( pxBlock != pxEnd ) { if( pxBlock->xBlockSize >= [1] ) { /* Remove block from free list */ pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; /* Split block if large enough */ if( pxBlock->xBlockSize - [2] > [3] ) { /* Create new free block with remaining size */ /* ... */ } return ( void * )( pxBlock + 1 ); } pxPreviousBlock = pxBlock; pxBlock = pxBlock->pxNextFreeBlock; }
The first-fit algorithm allocates from the first free block large enough (xWantedSize). It splits the block if the leftover size is bigger than the size of the block header (sizeof(BlockLink_t)).