heap_2.c File Reference

#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 Documentation

#define heapMINIMUM_BLOCK_SIZE   ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) )

Definition at line 96 of file heap_2.c.

Referenced by pvPortMalloc().

#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE

Definition at line 67 of file heap_2.c.

 
#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 Documentation

typedef struct A_BLOCK_LINK xBlockLink


Function Documentation

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   ) 

Definition at line 276 of file heap_2.c.

00278 {
00279     /* This just exists to keep the linker quiet. */

size_t xPortGetFreeHeapSize ( void   ) 

Definition at line 270 of file heap_2.c.

00272 {
00273     return xFreeBytesRemaining;


Variable Documentation

const unsigned short heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + portBYTE_ALIGNMENT - ( sizeof( xBlockLink ) % portBYTE_ALIGNMENT ) ) [static]

Definition at line 95 of file heap_2.c.

Referenced by pvPortMalloc(), and vPortFree().

xBlockLink xEnd [static]

Definition at line 99 of file heap_2.c.

size_t xFreeBytesRemaining [static]

Definition at line 103 of file heap_2.c.

union xRTOS_HEAP xHeap [static]

xBlockLink xStart [static]

Definition at line 99 of file heap_2.c.


Generated on Thu Dec 17 20:02:01 2009 for AVR32 UC3 - FreeRTOS Real Time Kernel by  doxygen 1.5.5