雖然現(xiàn)在的單片機(jī)系統(tǒng),CPU的資源并不是那么緊缺了,也有豐富的內(nèi)存空間,但是我們還是要積極地實現(xiàn)內(nèi)存管理,這可以幫我們減少內(nèi)存資源的占用,優(yōu)化程序,提高效率。
而任務(wù)調(diào)度算法,則是幫助我們合理安排實時系統(tǒng)中各個任務(wù)的邏輯順序,保證各個任務(wù)按照某種規(guī)則協(xié)調(diào)有效地進(jìn)行。
1
內(nèi)存管理
- 堆(heap):就是一塊空閑的內(nèi)存,需要提供管理函數(shù)
- 棧(stack):函數(shù)調(diào)用時局部變量保存在棧中,當(dāng)前程序的環(huán)境也是保存在棧中
FreeRTOS 中內(nèi)存管理的接口函數(shù)為:pvPortMalloc 、 vPortFree ,對應(yīng)于 C 庫的 malloc 、 free。
源碼中提供了5種內(nèi)存管理的方法。
1.heap_1
它只實現(xiàn)了pvPortMalloc,沒有實現(xiàn)vPortFree。
它的實現(xiàn)過程就是,先定義一個大數(shù)組(堆)-A,當(dāng)用戶創(chuàng)建任務(wù)時B圖中的藍(lán)色區(qū)域被占用,創(chuàng)建更多任務(wù)時,如圖所示。
2.heap_2
Heap_2 使用 最佳匹配算法 (best fifit) 來分配內(nèi)存,它支持vPortFree釋放內(nèi)存
Heap_2 不會合并相鄰的空閑內(nèi)存,所以 Heap_2 會導(dǎo)致嚴(yán)重的 " 碎片化 " 問題。
但是,如果申請、分配內(nèi)存時大小總是相同的,這類場景下 Heap_2 沒有碎片化的問題。所以它適用于:頻繁地創(chuàng)建、刪除任務(wù),但是任務(wù)的棧大小都是相同的( 創(chuàng)建任務(wù)時,需要分配 TCB 和棧, TCB 總是一樣的) 。
3.heap_3
Heap_3 使用標(biāo)準(zhǔn) C 庫里的 malloc 、 free 函數(shù),所以堆大小由鏈接器的配置決定,配置項confifigTOTAL_HEAP_SIZE 不再起作用。
4.heap_4
Heap_4 使用首次適應(yīng)算法 (fifirst fifit) 來分配內(nèi)存。它還會把相鄰的空閑內(nèi)存合并為一個更大的空閑內(nèi)存, 這有助于較少內(nèi)存的碎片問題。
Heap_4 會把相鄰空閑內(nèi)存合并為一個大的空閑內(nèi)存,可以較少內(nèi)存的碎片化問題。適用于這種場景:頻繁地分配、釋放不同大小的內(nèi)存。
5.heap_5
Heap_5 分配內(nèi)存、釋放內(nèi)存的算法跟 Heap_4 是一樣的。相比于 Heap_4 , Heap_5 并不局限于管理一個大數(shù)組:它可以管理多塊、分隔開的內(nèi)存。
在嵌入式系統(tǒng)中,內(nèi)存的地址可能并不連續(xù),這種場景下可以使用 Heap_5 ,但需要進(jìn)行初始化:確定這些內(nèi)存塊在哪、多大。
內(nèi)存分配失敗時的鉤子函數(shù):
在 FreeRTOSConfifig.h 中,把宏 confifigUSE_MALLOC_FAILED_HOOK 定義為1,可以開啟使用一個鉤子函數(shù)vApplicationMallocFailedHook,當(dāng)pvPortMalloc失敗后,可以在這個鉤子函數(shù)中做一些事情。
void * pvPortMalloc( size_t xWantedSize )vPortDefineHeapRegions
{
......
#if ( configUSE_MALLOC_FAILED_HOOK == 1 )
{
if( pvReturn == NULL )
{
extern void vApplicationMallocFailedHook( void );
vApplicationMallocFailedHook();
}
}
#endif
return pvReturn;
}
2
任務(wù)調(diào)度
所謂調(diào)度算法就是怎么確定哪個就緒態(tài)的任務(wù)可以切換為運行狀態(tài)。
通過配置文件 FreeRTOSConfifig.h 的兩個配置宏來配置調(diào)度算法:confifigUSE_PREEMPTION、confifigUSE_TIME_SLICING 。
- confifigUSE_PREEMPTION:為1時,采用可搶占調(diào)度,高優(yōu)先級的任務(wù)搶先執(zhí)行;為0時,當(dāng)一個任務(wù)正在執(zhí)行時,就算一個更高優(yōu)先級的任務(wù)處于Ready狀態(tài)了也不能打斷該任務(wù)的執(zhí)行,除非這個任務(wù)自己停止。
- confifigUSE_TIME_SLICING:為1時,開啟時間片調(diào)度,同優(yōu)先級的任務(wù)輪流執(zhí)行;為0時,
當(dāng)前任務(wù)會一直執(zhí)行,直到主動放棄、或者被高優(yōu)先級任務(wù)搶占。
3
總結(jié)
關(guān)于內(nèi)存管理及任務(wù)調(diào)度寫這些,后面會進(jìn)行常用的任務(wù)--通訊方式堆棧、隊列等的介紹。
-
FreeRTOS
+關(guān)注
關(guān)注
12文章
484瀏覽量
62138 -
狀態(tài)機(jī)
+關(guān)注
關(guān)注
2文章
492瀏覽量
27528 -
STM32F103
+關(guān)注
關(guān)注
33文章
477瀏覽量
63600 -
內(nèi)存管理
+關(guān)注
關(guān)注
0文章
168瀏覽量
14134
發(fā)布評論請先 登錄
相關(guān)推薦
評論