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字节