FreeRTOS代碼剖析之2:內(nèi)存管理Heap_第1頁(yè)
FreeRTOS代碼剖析之2:內(nèi)存管理Heap_第2頁(yè)
FreeRTOS代碼剖析之2:內(nèi)存管理Heap_第3頁(yè)
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

FreeRTOS代碼剖析之2:內(nèi)存管理Heap在FreeRTOS8.0.1這個(gè)版本中,一共有四個(gè)內(nèi)存堆模型。這一次講的就是第二個(gè)模型Heap_2.c。從一開(kāi)始就可以看到注釋中對(duì)Heap_2的模型解釋:這是對(duì)pvPortMalloc()和vPortFree()的簡(jiǎn)單實(shí)現(xiàn),除了可以分配內(nèi)存之外,還可以對(duì)已分配的內(nèi)存進(jìn)行回收,但相鄰空閑塊不會(huì)進(jìn)行合并,因此會(huì)造成一定的內(nèi)存碎片。(AsampleimplementationofpvPortMalloc()andvPortFree()thatpermitsallocatedblockstobefreed,butdoesnotcombineadjacentfreeblocksintoasinglelargerblock(andsowillfragmentmemory).)在Heap_2中,由于開(kāi)始支持對(duì)內(nèi)存進(jìn)行回收,因此FreeRTOS以空閑塊對(duì)內(nèi)存堆進(jìn)行管理,并且使用了最佳適配算法(bestfitalgorithm)去進(jìn)行內(nèi)存的分配。首先,還是由內(nèi)存中開(kāi)辟一個(gè)靜態(tài)數(shù)組ucHeap[configTOTAL_HEAP_SIZE]作為FreeRTOS的內(nèi)存堆。同樣也會(huì)因?yàn)閷?duì)齊的原因FreeRTOS對(duì)內(nèi)存堆的可用空間進(jìn)行了調(diào)整,并定義了常量configADJUSTED_HEAP_SIZE。(具體已在上一篇《內(nèi)存管理Heap_1.c》中介紹)接下來(lái)可以留意Heap_2.c中最重要的結(jié)構(gòu)structA_BLOCK_LINK。由于FreeRTOS用空閑塊對(duì)內(nèi)存堆進(jìn)行管理,于是用這一個(gè)結(jié)構(gòu)來(lái)形成一條空閑塊鏈表對(duì)空閑塊進(jìn)行組織和管理。

/*Definethelinkedliststructure.Thisisusedtolinkfreeblocksinorderoftheirsize.*/

typedefstructA_BLOCK_LINK

{

structA_BLOCK_LINK*pxNextFreeBlock;/*<<Thenextfreeblockinthelist.*/

size_txBlockSize;/*<<Thesizeofthefreeblock.*/

}BlockLink_t;這個(gè)結(jié)構(gòu)有兩個(gè)成員,第一個(gè)是節(jié)點(diǎn)Next指針pxNextFreeBlock,第二個(gè)是空閑塊大小。一個(gè)空閑塊就用這樣的一個(gè)結(jié)構(gòu)節(jié)點(diǎn)表示,所有節(jié)點(diǎn)通過(guò)Next指針形成一條空閑塊鏈表。FreeRTOS還定義了這個(gè)鏈表的頭xStart和尾xEnd。

/*Createacoupleoflistlinkstomarkthestartandendofthelist.*/

staticBlockLink_txStart,xEnd;與Heap_1不同,在Heap_2中會(huì)有一個(gè)堆初始化的過(guò)程prvHeapInit()。這一個(gè)過(guò)程被pvPortMalloc()調(diào)用,但只被調(diào)用一次。主要還是對(duì)內(nèi)存堆進(jìn)行對(duì)齊還有對(duì)空閑塊表進(jìn)行初始化工作。下面是它的工作流程。首先,初始化流程對(duì)整個(gè)內(nèi)存堆進(jìn)行地址對(duì)齊工作。對(duì)齊的原因的原理與Heap_1一樣。

/*Ensuretheheapstartsonacorrectlyalignedboundary.*/

pucAlignedHeap=(uint8_t*)(((portPOINTER_SIZE_TYPE)&ucHeap[portBYTE_ALIGNMENT])&((portPOINTER_SIZE_TYPE)~portBYTE_ALIGNMENT_MASK));在獲取到地址對(duì)齊后的內(nèi)存堆首地址之后,就要對(duì)空閑塊鏈表進(jìn)行初始化。留意,xStart是鏈表頭,并不表示一個(gè)空閑塊,xEnd是鏈表尾,也不表示一個(gè)空閑塊,但記錄著整個(gè)堆的大小。其代碼如下:

/*xStartisusedtoholdapointertothefirstiteminthelistoffree

blocks.Thevoidcastisusedtopreventcompilerwarnings.*/

xStart.pxNextFreeBlock=(void*)pucAlignedHeap;

xStart.xBlockSize=(size_t)0;/*xEndisusedtomarktheendofthelistoffreeblocks.*/

xEnd.xBlockSize=configADJUSTED_HEAP_SIZE;

xEnd.pxNextFreeBlock=NULL;/*Tostartwiththereisasinglefreeblockthatissizedtotakeupthe

entireheapspace.*/

pxFirstFreeBlock=(void*)pucAlignedHeap;

pxFirstFreeBlock->xBlockSize=configADJUSTED_HEAP_SIZE;

pxFirstFreeBlock->pxNextFreeBlock=&xEnd;經(jīng)過(guò)上面的初始化流程后,整個(gè)鏈表如下圖所示。注意,xStart和xEnd是存在于靜態(tài)存儲(chǔ)區(qū)中,并不在FreeRTOS申請(qǐng)的內(nèi)存堆數(shù)組中,但初始時(shí)第一個(gè)節(jié)點(diǎn)卻在內(nèi)存堆數(shù)組中。我用的編譯器是KeilMDK5.11,并且將FreeRTOS移植到STM32上,因此一個(gè)A_BLOCK_LINK的大小為8個(gè)字節(jié)。整個(gè)初始化的流程就完成了。接下來(lái)看看pvPortMalloc()分配內(nèi)存的流程。如Heap_1一樣,在真正開(kāi)始分配內(nèi)存時(shí),用vTaskSuspendAll()掛起所有任務(wù),防止分配內(nèi)存的過(guò)程被中斷,確保操作的原子性。緊接著,如果是第一次調(diào)用pvPortMalloc(),則調(diào)用prvHeapInit()對(duì)內(nèi)存堆和空閑塊鏈表進(jìn)行初始化。由于在Heap_2中將內(nèi)存堆用空閑塊處理,因此用戶每申請(qǐng)一次內(nèi)存,F(xiàn)reeRTOS都會(huì)在申請(qǐng)的空間前加上空閑塊頭部BlockLink_t,用于記錄分配出去的空間的大小。因此,真正要分配的內(nèi)存空間大小就等于用戶申請(qǐng)的內(nèi)存空間大小加上空閑塊頭部的大小。加上頭部之后,還要對(duì)整個(gè)大小進(jìn)行對(duì)齊。因此,在真正分配空間之前,F(xiàn)reeRTOS都對(duì)用戶申請(qǐng)的空間大小進(jìn)行了調(diào)整。如下面的代碼所示。

/*Thewantedsizeisincrease

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論