今天小编给大家分享一下FreeRTOS动态内存分配怎么管理heap5的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
heap_5.c
heap5与heap4分配释放算法完全相同,只是heap5支持管理多块不连续的内存,本质是将多块不连续内存用链表串成一整块内存,再用heap4算法来分配释放。若使用heap5则在涉及到分配释放的函数调用时要先调用vPortDefineHeapRegions
把多块不连续内存串成一块初始化。
vPortDefineHeapRegions
此函数原型
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ),
参数在portable.h
中定义,如下
typedef struct HeapRegion{uint8_t *pucStartAddress;//指向内存块首地址size_t xSizeInBytes;//此内存块大小} HeapRegion_t;
比如有2块内存要用heap5管理,地址0x80000000,大小0x10000,地址0x90000000,大小0xa0000
,则如下定义该结构体数组
HeapRegion_t xHeapRegions[] = { { ( uint8_t * ) 0x80000000UL, 0x10000 }, { ( uint8_t * ) 0x90000000UL, 0xa0000 }, { NULL, 0 } };
注意地址顺序要从小到大,最后要以{NULL,0}结尾(源码是以0做判断结束循环)
下面看初始化源码
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ){BlockLink_t *pxFirstFreeBlockInRegion = NULL, *pxPreviousFreeBlock;size_t xAlignedHeap;size_t xTotalRegionSize, xTotalHeapSize = 0;BaseType_t xDefinedRegions = 0;size_t xAddress;const HeapRegion_t *pxHeapRegion;configASSERT( pxEnd == NULL );pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] );while( pxHeapRegion->xSizeInBytes > 0 ){xTotalRegionSize = pxHeapRegion->xSizeInBytes;xAddress = ( size_t ) pxHeapRegion->pucStartAddress;if( ( xAddress & portBYTE_ALIGNMENT_MASK ) != 0 ){xAddress += ( portBYTE_ALIGNMENT - 1 );xAddress &= ~portBYTE_ALIGNMENT_MASK;xTotalRegionSize -= xAddress - ( size_t ) pxHeapRegion->pucStartAddress;}xAlignedHeap = xAddress;if( xDefinedRegions == 0 ){xStart.pxNextFreeBlock = ( BlockLink_t * ) xAlignedHeap;xStart.xBlockSize = ( size_t ) 0;}else{configASSERT( pxEnd != NULL );configASSERT( xAddress > ( size_t ) pxEnd );}pxPreviousFreeBlock = pxEnd;xAddress = xAlignedHeap + xTotalRegionSize;xAddress -= xHeapStructSize;xAddress &= ~portBYTE_ALIGNMENT_MASK;pxEnd = ( BlockLink_t * ) xAddress;pxEnd->xBlockSize = 0;pxEnd->pxNextFreeBlock = NULL;pxFirstFreeBlockInRegion = ( BlockLink_t * ) xAlignedHeap;pxFirstFreeBlockInRegion->xBlockSize = xAddress - ( size_t ) pxFirstFreeBlockInRegion;pxFirstFreeBlockInRegion->pxNextFreeBlock = pxEnd;if( pxPreviousFreeBlock != NULL ){pxPreviousFreeBlock->pxNextFreeBlock = pxFirstFreeBlockInRegion;}xTotalHeapSize += pxFirstFreeBlockInRegion->xBlockSize;//下一块xDefinedRegions++;pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] );}xMinimumEverFreeBytesRemaining = xTotalHeapSize;xFreeBytesRemaining = xTotalHeapSize;configASSERT( xTotalHeapSize );xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 );}
常见问题
比如有多块内存,一块是内部ram,其他是外部ram,外部的地址能写死确定,但是内部的会随着程序开发不停改变,怎么确定呢,下面是官网给的例子
#define RAM2_START_ADDRESS ( ( uint8_t * ) 0x00020000 )#define RAM2_SIZE ( 32 * 1024 )#define RAM3_START_ADDRESS ( ( uint8_t * ) 0x00030000 )#define RAM3_SIZE ( 32 * 1024 )#define RAM1_HEAP_SIZE ( 30 * 1024 )static uint8_t ucHeap[ RAM1_HEAP_SIZE ];const HeapRegion_t xHeapRegions[] ={ { ucHeap, RAM1_HEAP_SIZE }, { RAM2_START_ADDRESS, RAM2_SIZE }, { RAM3_START_ADDRESS, RAM3_SIZE }, { NULL, 0 } };
这样就不用老是修改第一块的起始地址。
以上就是“FreeRTOS动态内存分配怎么管理heap5”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网行业资讯频道。