freeRTOS源碼中提供了五種內(nèi)存管理的方案,可以說是很方便了。實(shí)際需要使用哪一種,可以根據(jù)自己項(xiàng)目的需要進(jìn)行選擇,都是可以的。
那這五種不同的內(nèi)存管理方式都有哪些差異呢?按照官方給出的說明,這五種內(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)存管理方式中最簡單的,這種方式的動(dòng)態(tài)內(nèi)存管理一旦申請 了相應(yīng)內(nèi)存后,是不允許被釋放的。
盡管如此,這種方式的動(dòng)態(tài)內(nèi)存管理還是可以滿足許多的嵌入式項(xiàng)目的, 因?yàn)橛行┣度胧?a target="_blank">產(chǎn)品在系統(tǒng)啟動(dòng)階段就明確了任務(wù)創(chuàng)建、事件標(biāo)志組、信號(hào)量、消息隊(duì)列等資源的使用情況, 而且這些資源是整個(gè)運(yùn)行過程中都要一直使用的,并不打算釋放或者丟棄,所以也就不需要釋放內(nèi)存。
FreeRTOS 的 動(dòng)態(tài)內(nèi)存可以申請的大小范圍可以在 FreeRTOSConfig.h 文件中進(jìn)行了定義:
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 30 * 1024 ) ) //單位字節(jié)
這個(gè)宏其實(shí)是規(guī)定了操作系統(tǒng)的堆棧空間的總大小,動(dòng)態(tài)申請的內(nèi)存大小是不能操作這個(gè)這個(gè)值的。
我們可以通過函數(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)所申請的動(dòng)態(tài)內(nèi)存的時(shí)間是固定的,并且不會(huì)產(chǎn)生內(nèi)存碎片。
3)是一種靜態(tài)內(nèi)存分配方案,因?yàn)樯暾埖膬?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)存可以申請的大小范圍可以在 FreeRTOSConfig.h 文件中進(jìn)行了定義:
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 30 * 1024 ) ) //單位字節(jié)
通過函數(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)如果申請和釋放的動(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)存碎片過多的話會(huì)導(dǎo)致無法申請出一個(gè)大的內(nèi)存塊出來。
4)項(xiàng)目中需要重復(fù)的創(chuàng)建和刪除消息隊(duì)列,也會(huì)出現(xiàn)類似上面的情況。
5)直接的調(diào)用函數(shù) pvPortMalloc() 和 vPortFree() 也容易出現(xiàn)內(nèi)存碎片。如果按一定順序的申請和釋放,基本沒有內(nèi)存碎片的,而不按順序的隨機(jī)申請和釋放容易產(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)存管理是對編譯器提供的 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í)間確定性,即申請動(dòng)態(tài)內(nèi)存的時(shí)間不是固定的。
3)增加 RTOS 內(nèi)核的代碼量。
另外要特別注意一點(diǎn),這種方式的動(dòng)態(tài)內(nèi)存申請和釋放不是用的 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 空間位置。
通過函數(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(),即使每次申請的內(nèi)存大小都不同,也不會(huì)產(chǎn) 生很多的內(nèi)存碎片。
3)申請動(dòng)態(tài)內(nèi)存的時(shí)間不是確定的。
5、 內(nèi)存管理方式 5 (heap_5.c)
如果希望申請的空間可以采用不連續(xù)的內(nèi)存區(qū),比希望可以將內(nèi)存定義在內(nèi)部 SRAM 中的某一部分,或者外部 SRAM 的一部分,就可以采用 heap_5 動(dòng)態(tài)內(nèi)存管理 方式。
heap_5 內(nèi)存管理通過函數(shù) vPortDefineHeapRegions 進(jìn)行初始化的,即在創(chuàng)建任 務(wù) FreeRTOS 的內(nèi)部資源前要優(yōu)先調(diào)用這個(gè)函數(shù) vPortDefineHeapRegions,否則是無法通過函數(shù) pvPortMalloc 申請到動(dòng)態(tài)內(nèi)存的。
6、這五種內(nèi)存申請方式的比較
有關(guān)五種動(dòng)態(tài)內(nèi)存管理方式簡單總結(jié)如下:
1)heap_1.c:五種方式里面最簡單的,但是申請的內(nèi)存不允許釋放。
2)heap_2.c:支持動(dòng)態(tài)內(nèi)存的申請和釋放,但是不支持內(nèi)存碎片的處理,無法將碎片內(nèi)存合并成一個(gè)大的內(nèi)存塊。
3)heap_3.c:將編譯器自帶的 malloc 和 free 函數(shù)進(jìn)行簡單的封裝,以支持線程安全,即支持多任務(wù)調(diào) 用。
4)heap_4.c:支持動(dòng)態(tài)內(nèi)存的申請和釋放,支持內(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)存的申請和釋放,支持內(nèi)存碎片處理,還支持將動(dòng)態(tài)內(nèi)存設(shè)置在個(gè)固定的地址,對大多數(shù)的項(xiàng)目都有很高的滿足性,基本上都能夠適配上了!
五種方式不分優(yōu)劣吧,看自己的項(xiàng)目的需求,合適才是最好的?。?!
-
源碼
+關(guān)注
關(guān)注
8文章
632瀏覽量
29110 -
FreeRTOS
+關(guān)注
關(guān)注
12文章
483瀏覽量
61916 -
內(nèi)存管理
+關(guān)注
關(guān)注
0文章
168瀏覽量
14117
發(fā)布評論請先 登錄
相關(guān)推薦
評論