您的位置:首页 > 其它

freertos 内存分配 源码分析

2014-06-16 00:00 316 查看
摘要: freertos 内存分配 源码分析

xBlockLink

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;


堆栈初始化

static xBlockLink xStart, xEnd;

static union xRTOS_HEAP

{

#if portBYTE_ALIGNMENT == 8 //这里为 8

volatile portDOUBLE dDummy;

#else

volatile unsigned long ulDummy;

#endif

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字节
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息