溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

FreeRTOS動態(tài)內(nèi)存分配怎么管理heap5

發(fā)布時間:2022-04-08 09:24:24 來源:億速云 閱讀:209 作者:iii 欄目:開發(fā)技術(shù)

今天小編給大家分享一下FreeRTOS動態(tài)內(nèi)存分配怎么管理heap5的相關(guān)知識點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

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)存分配怎么管理heap5”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學(xué)習(xí)更多的知識,請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI