中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

FreeRTOS動態內存分配怎么管理heap5

發布時間:2022-04-08 09:24:24 來源:億速云 閱讀:220 作者:iii 欄目:開發技術

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

heap_5.c

heap5與heap4分配釋放算法完全相同,只是heap5支持管理多塊不連續的內存,本質是將多塊不連續內存用鏈表串成一整塊內存,再用heap4算法來分配釋放。若使用heap5則在涉及到分配釋放的函數調用時要先調用vPortDefineHeapRegions把多塊不連續內存串成一塊初始化。

vPortDefineHeapRegions

此函數原型

void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ),

參數在portable.h中定義,如下

/* Used by heap_5.c. */
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;
	/* 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 );
}

常見問題

比如有多塊內存,一塊是內部ram,其他是外部ram,外部的地址能寫死確定,但是內部的會隨著程序開發不停改變,怎么確定呢,下面是官網給的例子

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

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

禹州市| 漾濞| 刚察县| 正安县| 盱眙县| 江津市| 鹤山市| 吉安县| 平原县| 金华市| 轮台县| 西城区| 赣榆县| 伊吾县| 济宁市| 开江县| 固阳县| 社旗县| 邮箱| 鱼台县| 长子县| 凤凰县| 恭城| 苏尼特右旗| 星子县| 平顶山市| 六枝特区| 吉安县| 京山县| 原阳县| 偃师市| 莒南县| 广德县| 临泉县| 哈巴河县| 白河县| 昭平县| 浠水县| 友谊县| 车险| 玉溪市|