xBlockLinkspa
typedef struct A_BLOCK_LINK { struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ size_t xBlockSize; /*<< The size of the free block. */ } xBlockLink;
堆棧初始化code
static xBlockLink xStart, xEnd;內存
static union xRTOS_HEAPit
{io
#if portBYTE_ALIGNMENT == 8 //這裏爲 8event
volatile portDOUBLE dDummy;ast
#elseclass
volatile unsigned long ulDummy;原理
#endifsed
unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];
} xHeap;
#define prvHeapInit() \ { \ 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; //17*1024 17字節 \ 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; \ }
內存
static const unsigned short heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + portBYTE_ALIGNMENT - ( sizeof( xBlockLink ) % portBYTE_ALIGNMENT ) );
void *pvPortMalloc( size_t xWantedSize ) { xBlockLink *pxBlock, *pxPreviousBlock, *pxNewBlockLink; static portBASE_TYPE xHeapHasBeenInitialised = pdFALSE; void *pvReturn = NULL; vTaskSuspendAll(); { //第一次 if( xHeapHasBeenInitialised == pdFALSE ) { prvHeapInit(); xHeapHasBeenInitialised = pdTRUE; } if( xWantedSize > 0 ) { xWantedSize += heapSTRUCT_SIZE; if( xWantedSize & portBYTE_ALIGNMENT_MASK ) //須要的空間對齊 { xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); } } if( ( xWantedSize > 0 ) && ( xWantedSize < configTOTAL_HEAP_SIZE ) ) { pxPreviousBlock = &xStart; //指向起始地址 pxBlock = xStart.pxNextFreeBlock; // while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock ) ) { pxPreviousBlock = pxBlock; //找到合適大小 pxBlock = pxBlock->pxNextFreeBlock; // } if( pxBlock != &xEnd ) { pvReturn = ( void * ) ( ( ( unsigned char * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE ); //得到分配的須要的空間地址 /* 從空閒的內存鏈表中移除 */ pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; /*若是比須要的大,能夠分爲兩塊*/ if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) { pxNewBlockLink = ( void * ) ( ( ( unsigned char * ) pxBlock ) + xWantedSize ); pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; //新劃分出來的空間塊 pxBlock->xBlockSize = xWantedSize; /* 把新分配的空間塊 添加到 空閒塊鏈表中 */ prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); } xFreeBytesRemaining -= pxBlock->xBlockSize; //空閒塊大小減去剛剛用掉的大小 } } } xTaskResumeAll(); #if( configUSE_MALLOC_FAILED_HOOK == 1 ) { if( pvReturn == NULL ) { extern void vApplicationMallocFailedHook( void ); vApplicationMallocFailedHook(); } } #endif return pvReturn; //返回需求的內存空間地址 }
static const unsigned short heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + portBYTE_ALIGNMENT - ( sizeof( xBlockLink ) % portBYTE_ALIGNMENT ) ); //分配的塊空間對齊
分配內存對齊原理:如size大小15 原理就爲 15+8-(15%8)=16 爲2個8字節