FreeRTOS動態(tài)內(nèi)存分配管理heap_5示例
heap_5.c
heap5與heap4分配釋放算法完全相同,只是heap5支持管理多塊不連續(xù)的內(nèi)存,本質(zhì)是將多塊不連續(xù)內(nèi)存用鏈表串成一整塊內(nèi)存,再用heap4算法來分配釋放。若使用heap5則在涉及到分配釋放的函數(shù)調(diào)用時要先調(diào)用vPortDefineHeapRegions
把多塊不連續(xù)內(nèi)存串成一塊初始化。
vPortDefineHeapRegions
此函數(shù)原型
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ),
參數(shù)在portable.h
中定義,如下
/* Used by heap_5.c. */ typedef struct HeapRegion { uint8_t *pucStartAddress;//指向內(nèi)存塊首地址 size_t xSizeInBytes;//此內(nèi)存塊大小 } HeapRegion_t;
比如有2塊內(nèi)存要用heap5管理,地址0x80000000,大小0x10000,地址0x90000000,大小0xa0000
,則如下定義該結(jié)構(gòu)體數(shù)組
HeapRegion_t xHeapRegions[] = { { ( uint8_t * ) 0x80000000UL, 0x10000 }, { ( uint8_t * ) 0x90000000UL, 0xa0000 }, { NULL, 0 } };
注意地址順序要從小到大,最后要以{NULL,0}結(jié)尾(源碼是以0做判斷結(jié)束循環(huán))
下面看初始化源碼
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; /* Can only call once! */ configASSERT( pxEnd == NULL ); pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] ); while( pxHeapRegion->xSizeInBytes > 0 ) { xTotalRegionSize = pxHeapRegion->xSizeInBytes; /* Ensure the heap region starts on a correctly aligned boundary. */ xAddress = ( size_t ) pxHeapRegion->pucStartAddress; if( ( xAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) { xAddress += ( portBYTE_ALIGNMENT - 1 ); xAddress &= ~portBYTE_ALIGNMENT_MASK; /* Adjust the size for the bytes lost to alignment. */ xTotalRegionSize -= xAddress - ( size_t ) pxHeapRegion->pucStartAddress; } xAlignedHeap = xAddress; /* Set xStart if it has not already been set. */ if( xDefinedRegions == 0 ) { /* 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 = ( BlockLink_t * ) xAlignedHeap; xStart.xBlockSize = ( size_t ) 0; } else { /* Should only get here if one region has already been added to the heap. */ configASSERT( pxEnd != NULL ); /* Check blocks are passed in with increasing start addresses. */ configASSERT( xAddress > ( size_t ) pxEnd ); } /* Remember the location of the end marker in the previous region, if any. */ pxPreviousFreeBlock = pxEnd; /* pxEnd is used to mark the end of the list of free blocks and is inserted at the end of the region space. */ xAddress = xAlignedHeap + xTotalRegionSize; xAddress -= xHeapStructSize; xAddress &= ~portBYTE_ALIGNMENT_MASK; pxEnd = ( BlockLink_t * ) xAddress; pxEnd->xBlockSize = 0; pxEnd->pxNextFreeBlock = NULL; /* To start with there is a single free block in this region that is sized to take up the entire heap region minus the space taken by the free block structure. */ pxFirstFreeBlockInRegion = ( BlockLink_t * ) xAlignedHeap; pxFirstFreeBlockInRegion->xBlockSize = xAddress - ( size_t ) pxFirstFreeBlockInRegion; pxFirstFreeBlockInRegion->pxNextFreeBlock = pxEnd; /* If this is not the first region that makes up the entire heap space then link the previous region to this region. */ if( pxPreviousFreeBlock != NULL ) { pxPreviousFreeBlock->pxNextFreeBlock = pxFirstFreeBlockInRegion; } xTotalHeapSize += pxFirstFreeBlockInRegion->xBlockSize; /* Move onto the next HeapRegion_t structure. */ //下一塊 xDefinedRegions++; pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] ); } xMinimumEverFreeBytesRemaining = xTotalHeapSize; xFreeBytesRemaining = xTotalHeapSize; /* Check something was actually defined before it is accessed. */ configASSERT( xTotalHeapSize ); /* Work out the position of the top bit in a size_t variable. */ xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ); }
常見問題
比如有多塊內(nèi)存,一塊是內(nèi)部ram,其他是外部ram,外部的地址能寫死確定,但是內(nèi)部的會隨著程序開發(fā)不停改變,怎么確定呢,下面是官網(wǎng)給的例子
/* Define the start address and size of the two RAM regions not used by the linker. */ #define RAM2_START_ADDRESS ( ( uint8_t * ) 0x00020000 ) #define RAM2_SIZE ( 32 * 1024 ) #define RAM3_START_ADDRESS ( ( uint8_t * ) 0x00030000 ) #define RAM3_SIZE ( 32 * 1024 ) /* Declare an array that will be part of the heap used by heap_5. The array will be placed in RAM1 by the linker. */ #define RAM1_HEAP_SIZE ( 30 * 1024 ) static uint8_t ucHeap[ RAM1_HEAP_SIZE ]; /* Create an array of HeapRegion_t definitions. Whereas in Listing 6 the first entry described all of RAM1, so heap_5 will have used all of RAM1, this time the first entry only describes the ucHeap array, so heap_5 will only use the part of RAM1 that contains the ucHeap array. The HeapRegion_t structures must still appear in start address order, with the structure that contains the lowest start address appearing first. */ const HeapRegion_t xHeapRegions[] = { { ucHeap, RAM1_HEAP_SIZE }, { RAM2_START_ADDRESS, RAM2_SIZE }, { RAM3_START_ADDRESS, RAM3_SIZE }, { NULL, 0 } /* Marks the end of the array. */ };
這樣就不用老是修改第一塊的起始地址。
以上就是FreeRTOS動態(tài)內(nèi)存分配管理heap_5示例的詳細(xì)內(nèi)容,更多關(guān)于FreeRTOS動態(tài)內(nèi)存分配管理的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
FreeRTOS實(shí)時操作系統(tǒng)多任務(wù)管理基礎(chǔ)知識
這篇文章主要為大家介紹了FreeRTOS實(shí)時操作系統(tǒng)多任務(wù)管理的基礎(chǔ)知識,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS使用任務(wù)通知實(shí)現(xiàn)命令行解釋器
這篇文章主要為大家介紹了FreeRTOS使用任務(wù)通知實(shí)現(xiàn)命令行解釋器,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS實(shí)時操作系統(tǒng)結(jié)構(gòu)示例
這篇文章主要介紹了FreeRTOS實(shí)時操作系統(tǒng)結(jié)構(gòu)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS實(shí)時操作系統(tǒng)的任務(wù)應(yīng)用函數(shù)詳解
這篇文章主要為大家介紹了FreeRTOS實(shí)時操作系統(tǒng)的任務(wù)應(yīng)用函數(shù)的解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS動態(tài)內(nèi)存分配管理heap_1示例
這篇文章主要為大家介紹了FreeRTOS動態(tài)內(nèi)存分配管理heap_1的示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS進(jìn)階系統(tǒng)節(jié)拍時鐘示例的完全解析
這篇文章主要為大家介紹了FreeRTOS進(jìn)階系統(tǒng)節(jié)拍時鐘示例的完全解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS實(shí)時操作系統(tǒng)在Cortex-M3上的移植過程
這篇文章主要為大家介紹了FreeRTOS實(shí)時操作系統(tǒng)在Cortex-M3上的移植過程的示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS編碼標(biāo)準(zhǔn)及風(fēng)格指南
這篇文章主要為大家介紹了FreeRTOS編碼標(biāo)準(zhǔn)及風(fēng)格指南,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS實(shí)時操作系統(tǒng)的多優(yōu)先級實(shí)現(xiàn)
這篇文章主要為大家介紹了FreeRTOS實(shí)時操作系統(tǒng)的多優(yōu)先級實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04