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;										\
}

173320_zl7f_274829.png

内存

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

转载于:https://my.oschina.net/u/274829/blog/280078

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值