#include <stdlib.h>
#include "FreeRTOS.h"
#include "task.h"
Go to the source code of this file.
Data Structures | |
struct | A_BLOCK_LINK |
union | xRTOS_HEAP |
Defines | |
#define | heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) ) |
#define | MPU_WRAPPERS_INCLUDED_FROM_API_FILE |
#define | prvHeapInit() |
#define | prvInsertBlockIntoFreeList(pxBlockToInsert) |
Typedefs | |
typedef struct A_BLOCK_LINK | xBlockLink |
Functions | |
void * | pvPortMalloc (size_t xWantedSize) |
void | vPortFree (void *pv) |
void | vPortInitialiseBlocks (void) |
size_t | xPortGetFreeHeapSize (void) |
Variables | |
static const unsigned short | heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + portBYTE_ALIGNMENT - ( sizeof( xBlockLink ) % portBYTE_ALIGNMENT ) ) |
static xBlockLink | xEnd |
static size_t | xFreeBytesRemaining |
static union xRTOS_HEAP | xHeap |
static xBlockLink | xStart |
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) ) |
#define prvHeapInit | ( | ) |
Value:
{ \ xBlockLink *pxFirstFreeBlock; \ \ /* xStart is used to hold a pointer to the first item in the list of free */ \ /* blocks. The void cast is used to prevent compiler warnings. */ \ xStart.pxNextFreeBlock = ( void * ) xHeap.ucHeap; \ xStart.xBlockSize = ( size_t ) 0; \ \ /* xEnd is used to mark the end of the list of free blocks. */ \ xEnd.xBlockSize = configTOTAL_HEAP_SIZE; \ xEnd.pxNextFreeBlock = NULL; \ \ /* To start with there is a single free block that is sized to take up the \ entire heap space. */ \ pxFirstFreeBlock = ( void * ) xHeap.ucHeap; \ pxFirstFreeBlock->xBlockSize = configTOTAL_HEAP_SIZE; \ pxFirstFreeBlock->pxNextFreeBlock = &xEnd; \ \ xFreeBytesRemaining = configTOTAL_HEAP_SIZE; \ }
Definition at line 133 of file heap_2.c.
Referenced by pvPortMalloc().
#define prvInsertBlockIntoFreeList | ( | pxBlockToInsert | ) |
Value:
{ \ xBlockLink *pxIterator; \ size_t xBlockSize; \ \ xBlockSize = pxBlockToInsert->xBlockSize; \ \ /* Iterate through the list until a block is found that has a larger size */ \ /* than the block we are inserting. */ \ for( pxIterator = &xStart; pxIterator->pxNextFreeBlock->xBlockSize < xBlockSize; pxIterator = pxIterator->pxNextFreeBlock ) \ { \ /* There is nothing to do here - just iterate to the correct position. */ \ } \ \ /* Update the list to include the block being inserted in the correct */ \ /* position. */ \ pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; \ pxIterator->pxNextFreeBlock = pxBlockToInsert; \ }
Definition at line 112 of file heap_2.c.
Referenced by pvPortMalloc(), and vPortFree().
typedef struct A_BLOCK_LINK xBlockLink |
void* pvPortMalloc | ( | size_t | xWantedSize | ) |
Definition at line 155 of file heap_2.c.
References configTOTAL_HEAP_SIZE, heapMINIMUM_BLOCK_SIZE, heapSTRUCT_SIZE, pdFALSE, pdTRUE, portBASE_TYPE, portBYTE_ALIGNMENT, prvHeapInit, prvInsertBlockIntoFreeList, A_BLOCK_LINK::pxNextFreeBlock, vTaskSuspendAll(), A_BLOCK_LINK::xBlockSize, and xTaskResumeAll().
00157 { 00158 xBlockLink *pxBlock, *pxPreviousBlock, *pxNewBlockLink; 00159 static portBASE_TYPE xHeapHasBeenInitialised = pdFALSE; 00160 void *pvReturn = NULL; 00161 00162 vTaskSuspendAll(); 00163 { 00164 /* If this is the first call to malloc then the heap will require 00165 initialisation to setup the list of free blocks. */ 00166 if( xHeapHasBeenInitialised == pdFALSE ) 00167 { 00168 prvHeapInit(); 00169 xHeapHasBeenInitialised = pdTRUE; 00170 } 00171 00172 /* The wanted size is increased so it can contain a xBlockLink 00173 structure in addition to the requested amount of bytes. */ 00174 if( xWantedSize > 0 ) 00175 { 00176 xWantedSize += heapSTRUCT_SIZE; 00177 00178 /* Ensure that blocks are always aligned to the required number of bytes. */ 00179 if( xWantedSize & portBYTE_ALIGNMENT_MASK ) 00180 { 00181 /* Byte alignment required. */ 00182 xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); 00183 } 00184 } 00185 00186 if( ( xWantedSize > 0 ) && ( xWantedSize < configTOTAL_HEAP_SIZE ) ) 00187 { 00188 /* Blocks are stored in byte order - traverse the list from the start 00189 (smallest) block until one of adequate size is found. */ 00190 pxPreviousBlock = &xStart; 00191 pxBlock = xStart.pxNextFreeBlock; 00192 while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock ) ) 00193 { 00194 pxPreviousBlock = pxBlock; 00195 pxBlock = pxBlock->pxNextFreeBlock; 00196 } 00197 00198 /* If we found the end marker then a block of adequate size was not found. */ 00199 if( pxBlock != &xEnd ) 00200 { 00201 /* Return the memory space - jumping over the xBlockLink structure 00202 at its start. */ 00203 pvReturn = ( void * ) ( ( ( unsigned char * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE ); 00204 00205 /* This block is being returned for use so must be taken our of the 00206 list of free blocks. */ 00207 pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; 00208 00209 /* If the block is larger than required it can be split into two. */ 00210 if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) 00211 { 00212 /* This block is to be split into two. Create a new block 00213 following the number of bytes requested. The void cast is 00214 used to prevent byte alignment warnings from the compiler. */ 00215 pxNewBlockLink = ( void * ) ( ( ( unsigned char * ) pxBlock ) + xWantedSize ); 00216 00217 /* Calculate the sizes of two blocks split from the single 00218 block. */ 00219 pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; 00220 pxBlock->xBlockSize = xWantedSize; 00221 00222 /* Insert the new block into the list of free blocks. */ 00223 prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); 00224 } 00225 00226 xFreeBytesRemaining -= xWantedSize; 00227 } 00228 } 00229 } 00230 xTaskResumeAll(); 00231 00232 #if( configUSE_MALLOC_FAILED_HOOK == 1 ) 00233 { 00234 if( pvReturn == NULL ) 00235 { 00236 extern void vApplicationMallocFailedHook( void ); 00237 vApplicationMallocFailedHook(); 00238 } 00239 } 00240 #endif 00241 00242 return pvReturn;
void vPortFree | ( | void * | pv | ) |
Definition at line 245 of file heap_2.c.
References heapSTRUCT_SIZE, prvInsertBlockIntoFreeList, vTaskSuspendAll(), A_BLOCK_LINK::xBlockSize, and xTaskResumeAll().
00247 { 00248 unsigned char *puc = ( unsigned char * ) pv; 00249 xBlockLink *pxLink; 00250 00251 if( pv ) 00252 { 00253 /* The memory being freed will have an xBlockLink structure immediately 00254 before it. */ 00255 puc -= heapSTRUCT_SIZE; 00256 00257 /* This casting is to keep the compiler from issuing warnings. */ 00258 pxLink = ( void * ) puc; 00259 00260 vTaskSuspendAll(); 00261 { 00262 /* Add this block to the list of free blocks. */ 00263 prvInsertBlockIntoFreeList( ( ( xBlockLink * ) pxLink ) ); 00264 xFreeBytesRemaining += pxLink->xBlockSize; 00265 } 00266 xTaskResumeAll(); 00267 }
void vPortInitialiseBlocks | ( | void | ) |
size_t xPortGetFreeHeapSize | ( | void | ) |
const unsigned short heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + portBYTE_ALIGNMENT - ( sizeof( xBlockLink ) % portBYTE_ALIGNMENT ) ) [static] |
xBlockLink xEnd [static] |
size_t xFreeBytesRemaining [static] |
union xRTOS_HEAP xHeap [static] |
xBlockLink xStart [static] |