FreeRtos heap5源码分析

===============================   博客点滴积累,部分话语和知识点来源于网络,感谢网络资源的提供者======

heap5 与heap4 比较相似,也是实现了malloc和free,同时也可以进行碎片合并。有的区别是heap5 可以有多个堆区,static void prvHeapInit( void ) 被换成void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions )这个函数。结构体HeapRegion_t(portable.h)如下:

const HeapRegion_t * const pxHeapRegions   结构体如下定义(portable.h):

/* Used by heap_5.c. */
typedef struct HeapRegion
{
uint8_t *pucStartAddress;
size_t xSizeInBytes;
} HeapRegion_t;

该函数前面有一段注释大概意思是:vPortDefineHeapRegions 一定要在使用pvPortMalloc之前使用,进行初始化栈区。创建任务,信号量,互斥锁,软件定时器,事件组等都调用pvPortMalloc。所以这个需要注意。

vPortDefineHeapRegions 函数的参数是一个结构体数组,数组的地址指针,必须从小到大排序,并且以空指针和0字节结尾

void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions )
{

BlockLink_t *pxFirstFreeBlockInRegion = NULL, *pxPreviousFreeBlock;

uint8_t *pucAlignedHeap;

size_t xTotalRegionSize, xTotalHeapSize = 0;

BaseType_t xDefinedRegions = 0;

uint32_t ulAddress;

const HeapRegion_t *pxHeapRegion;

/* Can only call once! */

configASSERT( pxEnd == NULL );

//取数组的第一个元素

pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] );
while( pxHeapRegion->xSizeInBytes > 0 )
{//xSizeInBytes 以 0 字节结尾
xTotalRegionSize = pxHeapRegion->xSizeInBytes;
/* Ensure the heap region starts on a correctly aligned boundary. */
ulAddress = ( uint32_t ) pxHeapRegion->pucStartAddress;
if( ( ulAddress & portBYTE_ALIGNMENT_MASK ) != 0 )
{
ulAddress += ( portBYTE_ALIGNMENT - 1 );
ulAddress &= ~portBYTE_ALIGNMENT_MASK;
/* 调整字节对齐 */
xTotalRegionSize -= ulAddress - ( uint32_t ) pxHeapRegion->pucStartAddress;
}
pucAlignedHeap = ( uint8_t * ) ulAddress;
/* Set xStart if it has not already been set. */
if( xDefinedRegions == 0 )

{//当是数据的第一个元素,是初始化链表的头指针,注意xStart是个结构体,结构体的pxNextFreeBlock 指针指向了pucAlignedHeap,即堆区的基地址,基地址存了什么呢?pxFirstFreeBlockInRegion 结构体,定义了heap的大小,以及下一个heap的地址


xStart.pxNextFreeBlock = ( BlockLink_t * ) pucAlignedHeap;
xStart.xBlockSize = ( size_t ) 0;
}
else
{
configASSERT( pxEnd != NULL );
configASSERT( ulAddress > ( uint32_t ) pxEnd );
}
pxPreviousFreeBlock = pxEnd;//pxEnd 是个指针。它存在heap地址的最后面
ulAddress = ( ( uint32_t ) pucAlignedHeap ) + xTotalRegionSize;
ulAddress -= uxHeapStructSize;
ulAddress &= ~portBYTE_ALIGNMENT_MASK;
pxEnd = ( BlockLink_t * ) ulAddress;//初始化heap最后的pxEnd 指针

pxEnd->xBlockSize = 0;

pxEnd->pxNextFreeBlock = NULL;

pxFirstFreeBlockInRegion = ( BlockLink_t * ) pucAlignedHeap;
pxFirstFreeBlockInRegion->xBlockSize = ulAddress - ( uint32_t ) pxFirstFreeBlockInRegion;
pxFirstFreeBlockInRegion->pxNextFreeBlock = pxEnd;
if( pxPreviousFreeBlock != NULL )
{//不是第一块,就插入链表
pxPreviousFreeBlock->pxNextFreeBlock = pxFirstFreeBlockInRegion;
}
xTotalHeapSize += pxFirstFreeBlockInRegion->xBlockSize;//统计heap大小
/* 数组下标加1,获取下一个元素 */
xDefinedRegions++;
pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] );
}
xMinimumEverFreeBytesRemaining = xTotalHeapSize;
xFreeBytesRemaining = xTotalHeapSize;
/* Check something was actually defined before it is accessed. */
configASSERT( xTotalHeapSize );
/* xBlockAllocatedBit 标记最高bit位,表示地址是否空闲 */

xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 );

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值