freeRTOS源碼中提供了五種內(nèi)存管理的方案,可以說(shuō)是很方便了。實(shí)際需要使用哪一種,可以根據(jù)自己項(xiàng)目的需要進(jìn)行選擇,都是可以的。
那這五種不同的內(nèi)存管理方式都有哪些差異呢?按照官方給出的說(shuō)明,這五種內(nèi)存管理的特點(diǎn)分別如下:
1、內(nèi)存管理方式 1(heap_1.c)
heap_1 動(dòng)態(tài)內(nèi)存管理方式是五種動(dòng)態(tài)內(nèi)存管理方式中最簡(jiǎn)單的,這種方式的動(dòng)態(tài)內(nèi)存管理一旦申請(qǐng) 了相應(yīng)內(nèi)存后,是不允許被釋放的。
盡管如此,這種方式的動(dòng)態(tài)內(nèi)存管理還是可以滿足許多的嵌入式項(xiàng)目的, 因?yàn)橛行┣度胧疆a(chǎn)品在系統(tǒng)啟動(dòng)階段就明確了任務(wù)創(chuàng)建、事件標(biāo)志組、信號(hào)量、消息隊(duì)列等資源的使用情況, 而且這些資源是整個(gè)運(yùn)行過(guò)程中都要一直使用的,并不打算釋放或者丟棄,所以也就不需要釋放內(nèi)存。
FreeRTOS 的 動(dòng)態(tài)內(nèi)存可以申請(qǐng)的大小范圍可以在 FreeRTOSConfig.h 文件中進(jìn)行了定義:
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 30 * 1024 ) ) //單位字節(jié)
這個(gè)宏其實(shí)是規(guī)定了操作系統(tǒng)的堆棧空間的總大小,動(dòng)態(tài)申請(qǐng)的內(nèi)存大小是不能操作這個(gè)這個(gè)值的。
我們可以通過(guò)函數(shù) xPortGetFreeHeapSize 就能獲得 FreeRTOS 動(dòng)態(tài)內(nèi)存的剩余情況,進(jìn)而可以根據(jù)剩余情況優(yōu)化 動(dòng)態(tài)內(nèi)存的大小。
heap_1 方式的動(dòng)態(tài)內(nèi)存管理有以下特點(diǎn):
1)項(xiàng)目不需要?jiǎng)h除任務(wù)、信號(hào)量、消息隊(duì)列等已經(jīng)創(chuàng)建的資源。
2)所申請(qǐng)的動(dòng)態(tài)內(nèi)存的時(shí)間是固定的,并且不會(huì)產(chǎn)生內(nèi)存碎片。
3)是一種靜態(tài)內(nèi)存分配方案,因?yàn)樯暾?qǐng)的內(nèi)存是不會(huì)被釋放掉。
2、內(nèi)存管理方式 2(heap_2.c)
heap_2 動(dòng)態(tài)內(nèi)存管理利用了自適應(yīng)算法,并且支持內(nèi)存釋放, 但是不支持內(nèi)存碎片整理。
FreeRTOS 的 動(dòng)態(tài)內(nèi)存可以申請(qǐng)的大小范圍可以在 FreeRTOSConfig.h 文件中進(jìn)行了定義:
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 30 * 1024 ) ) //單位字節(jié)
通過(guò)函數(shù) xPortGetFreeHeapSize 能獲得 FreeRTOS 動(dòng)態(tài)內(nèi)存的剩余,可以根據(jù)剩余情況優(yōu)化動(dòng)態(tài)內(nèi)存的大小。
heap_2 方 式的內(nèi)存管理有以下特點(diǎn):
1)在不考慮內(nèi)存碎片的情況下,這種方式支持重復(fù)的任務(wù)、信號(hào)量、事件標(biāo)志組、軟件定時(shí)器等內(nèi)部資源 的創(chuàng)建和刪除。因?yàn)椴皇褂玫馁Y源是支持釋放的,所以可以讓內(nèi)存資源得到反復(fù)的使用!
2)如果申請(qǐng)和釋放的動(dòng)態(tài)內(nèi)存大小是隨機(jī)的,不建議采用這種動(dòng)態(tài)內(nèi)存管理方式。
3)項(xiàng)目中需要重復(fù)的創(chuàng)建和刪除任務(wù),如果每次創(chuàng)建需要?jiǎng)討B(tài)內(nèi)存大小相同,那么 heap_2 比 較適合,但每次創(chuàng)建需要?jiǎng)討B(tài)內(nèi)存大小不同,那么方式 heap_2 就不合適了,因?yàn)槿菀桩a(chǎn)生內(nèi)存 碎片,內(nèi)存碎片過(guò)多的話會(huì)導(dǎo)致無(wú)法申請(qǐng)出一個(gè)大的內(nèi)存塊出來(lái)。
4)項(xiàng)目中需要重復(fù)的創(chuàng)建和刪除消息隊(duì)列,也會(huì)出現(xiàn)類似上面的情況。
5)直接的調(diào)用函數(shù) pvPortMalloc() 和 vPortFree() 也容易出現(xiàn)內(nèi)存碎片。如果按一定順序的申請(qǐng)和釋放,基本沒有內(nèi)存碎片的,而不按順序的隨機(jī)申請(qǐng)和釋放容易產(chǎn)生內(nèi)存碎片。
6)如果隨機(jī)的創(chuàng)建和刪除任務(wù)、消息隊(duì)列、事件標(biāo)志組、信號(hào)量等內(nèi)部資源也容易出現(xiàn)內(nèi)存碎片。
3、 內(nèi)存管理方式 3(heap_3.c)
這種方式實(shí)現(xiàn)的內(nèi)存管理是對(duì)編譯器提供的 malloc 和 free 函數(shù)進(jìn)行了封裝,保證是線程安全的。
FreeRTOS 的動(dòng)態(tài)內(nèi)存大小在 FreeRTOSConfig.h 文件中進(jìn)行了定義:
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 30 * 1024 ) ) //單位字節(jié)
heap_3 方式的內(nèi)存管理有以下特點(diǎn):
1)需要編譯器提供 malloc 和 free 函數(shù)。
2)不具有時(shí)間確定性,即申請(qǐng)動(dòng)態(tài)內(nèi)存的時(shí)間不是固定的。
3)增加 RTOS 內(nèi)核的代碼量。
另外要特別注意一點(diǎn),這種方式的動(dòng)態(tài)內(nèi)存申請(qǐng)和釋放不是用的 FreeRTOSConfig.h 文件中定義的heap空間大小,而是用的編譯器設(shè)置的heap空間大小。
4、內(nèi)存管理方式 4(heap_4.c)
heap_4 動(dòng)態(tài)內(nèi)存管理利用了最適應(yīng)算法,且支持內(nèi)存碎片的回 收并將其整理為一個(gè)大的內(nèi)存塊。
FreeRTOS 的動(dòng)態(tài)內(nèi)存大小在 FreeRTOSConfig.h 文件中進(jìn)行了定義:
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 30 * 1024 ) ) //單位字節(jié)
heap_4 同時(shí)支持將動(dòng)態(tài)內(nèi)存設(shè)置在指定的 RAM 空間位置。
通過(guò)函數(shù) xPortGetFreeHeapSize 就能獲得 FreeRTOS 動(dòng)態(tài)內(nèi)存的剩余。
使用函數(shù) xPortGetMinimumEverFreeHeapSize 能夠獲取從系統(tǒng)啟 動(dòng)到當(dāng)前時(shí)刻的動(dòng)態(tài)內(nèi)存最小剩余。
heap_4 方式的 內(nèi)存管理有以下特點(diǎn):
1)可以用于需要重復(fù)的創(chuàng)建和刪除任務(wù)、信號(hào)量、事件標(biāo)志組、軟件定時(shí)器等資源的項(xiàng)目中。
2)調(diào)用 pvPortMalloc() 和 vPortFree(),即使每次申請(qǐng)的內(nèi)存大小都不同,也不會(huì)產(chǎn) 生很多的內(nèi)存碎片。
3)申請(qǐng)動(dòng)態(tài)內(nèi)存的時(shí)間不是確定的。
5、 內(nèi)存管理方式 5 (heap_5.c)
如果希望申請(qǐng)的空間可以采用不連續(xù)的內(nèi)存區(qū),比希望可以將內(nèi)存定義在內(nèi)部 SRAM 中的某一部分,或者外部 SRAM 的一部分,就可以采用 heap_5 動(dòng)態(tài)內(nèi)存管理 方式。
heap_5 內(nèi)存管理通過(guò)函數(shù) vPortDefineHeapRegions 進(jìn)行初始化的,即在創(chuàng)建任 務(wù) FreeRTOS 的內(nèi)部資源前要優(yōu)先調(diào)用這個(gè)函數(shù) vPortDefineHeapRegions,否則是無(wú)法通過(guò)函數(shù) pvPortMalloc 申請(qǐng)到動(dòng)態(tài)內(nèi)存的。
6、這五種內(nèi)存申請(qǐng)方式的比較
有關(guān)五種動(dòng)態(tài)內(nèi)存管理方式簡(jiǎn)單總結(jié)如下:
1)heap_1.c:五種方式里面最簡(jiǎn)單的,但是申請(qǐng)的內(nèi)存不允許釋放。
2)heap_2.c:支持動(dòng)態(tài)內(nèi)存的申請(qǐng)和釋放,但是不支持內(nèi)存碎片的處理,無(wú)法將碎片內(nèi)存合并成一個(gè)大的內(nèi)存塊。
3)heap_3.c:將編譯器自帶的 malloc 和 free 函數(shù)進(jìn)行簡(jiǎn)單的封裝,以支持線程安全,即支持多任務(wù)調(diào) 用。
4)heap_4.c:支持動(dòng)態(tài)內(nèi)存的申請(qǐng)和釋放,支持內(nèi)存碎片處理,支持將動(dòng)態(tài)內(nèi)存設(shè)置在個(gè)固定的地址(內(nèi)部或者外部 RAM)。
5)heap_5.c:在 heap_4.c 的基礎(chǔ)上支持將動(dòng)態(tài)內(nèi)存設(shè)置在不連續(xù)的區(qū)域上。
其實(shí)大多數(shù)項(xiàng)目中使用的都是 heap_4.c 這種內(nèi)存的管理方式,這種方式支持動(dòng)態(tài)內(nèi)存的申請(qǐng)和釋放,支持內(nèi)存碎片處理,還支持將動(dòng)態(tài)內(nèi)存設(shè)置在個(gè)固定的地址,對(duì)大多數(shù)的項(xiàng)目都有很高的滿足性,基本上都能夠適配上了!
五種方式不分優(yōu)劣吧,看自己的項(xiàng)目的需求,合適才是最好的?。?!
-
源碼
+關(guān)注
關(guān)注
8文章
671瀏覽量
30291 -
FreeRTOS
+關(guān)注
關(guān)注
12文章
492瀏覽量
64214 -
內(nèi)存管理
+關(guān)注
關(guān)注
0文章
168瀏覽量
14542
發(fā)布評(píng)論請(qǐng)先 登錄
freeRTOS 源碼
第28章 FreeRTOS動(dòng)態(tài)內(nèi)存管理
FreeRTOS內(nèi)存管理的算法解析?
闡述FreeRTOS系統(tǒng)中的機(jī)制及在應(yīng)用中的優(yōu)缺點(diǎn)
Freertos關(guān)于堆內(nèi)存管理的相關(guān)資料分享
FreeRTOS源碼介紹
FreeRTOS代碼剖析之1:內(nèi)存管理Heap

FreeRTOS代碼剖析之3:內(nèi)存管理Heap
基于FreeRTOS的嵌入式實(shí)時(shí)操作系統(tǒng)的原理和實(shí)現(xiàn)
FreeRTOS高級(jí)篇7---FreeRTOS內(nèi)存管理分析

FreeRTOS系列第8篇---FreeRTOS內(nèi)存管理

FreeRTOS內(nèi)存管理簡(jiǎn)介
FreeRTOS內(nèi)存管理實(shí)現(xiàn)

評(píng)論