FreeRTOS筆記(十三)記憶體管理
阿新 • • 發佈:2019-01-13
文章目錄
上一文連結:FreeRTOS筆記(十二)資源管理
01 - 記憶體管理
回顧一個最開初沒有提問的問題,我們建立任務的時候,會生成一個TCB任務控制塊,它需要在記憶體中佔據一個空間,多工中就會有多個TCB,誰給它們分配好空間?誰負責回收空間?一旦空間不夠怎麼辦?
任務需要被核心中不同的函式管理,所以肯定是使用全域性變數或者靜態變數,於是一個簡單的回答是使用全域性變數,每建立一個任務就存在一個全域性變數,但是任務的建立是動態的,而全域性變數的定義是靜態的,並不能在系統執行期間再去定義一個全域性變數,所以需要提前準備好一些全域性變數(全域性變數快取池),當需要的時候就分配
由於每一個單板的記憶體管理都可以不相同,所以FreeRTOS把記憶體管理歸屬到可移植層,由實際的情況去編寫,同時FreeRTOS提供了若干個記憶體管理的範例,這些範例是通用的,使用純C語言編寫,與硬體無關,範例中提前準備好的全域性變數是一個全域性靜態陣列static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
,在head_x.c(x是數字)中,作用域只能是heap_x.c檔案內,生存期是程式開始到結束,所以只能使用pvPortMalloc()
返回ucHeap
中某個位置的地址,使用指標間接訪問
#if( configAPPLICATION_ALLOCATED_HEAP == 1 )
extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#else
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
02 - 範例
檢視原始碼就可以知道每一個範例的記憶體管理演算法、管理方式等,小白使用Sv9.0.0版本的FreeRTOS,提供了5個範例,區別如下
FreeRTOS版本:Sv9.0.0
範例 | 演算法 | 分配方式 | 釋放方式 | 優點 | 缺點 | 程式碼量(行) |
---|---|---|---|---|---|---|
head_1.c | 順序分配,首次適應演算法 | 每次都從ucHeap陣列中順序切割 | 無 | 記憶體分配確定,沒有記憶體碎片 | 記憶體不可重用 | 185 |
head_2.c | 順序分配,最佳適應演算法 | 每次從空閒連結串列中找一個大小最合適的記憶體 | 把釋放的記憶體有序地插入一個從小到大排序的空閒連結串列 | 記憶體可重用,分配效率高 | 大塊記憶體得不到分配,相鄰的空閒記憶體不會合並,存在記憶體碎片 | 314 |
head_3.c | stblib庫決定 | 呼叫了malloc() | 呼叫了free() | 記憶體管理由編譯器決定 | 程式碼量可能大大增加,記憶體分配不確定 | 136 |
head_4.c | 順序分配,最佳適應演算法 | 同head_2.c | 同head_2.c,另外合併相鄰的空閒記憶體 | 同head_2.c,另外限制了記憶體碎片,相鄰空閒記憶體得到合併 | 大塊記憶體得不到分配 | 477 |
head_5.c | 離散分配 | head_4.c,但是允許跨越不同的記憶體段 | 同head_4.c | 同head_4.c,另外大塊記憶體得分配 | 分配和釋放速度較慢 | 526 |
03 - 總結
- 記憶體動態分配的本質是在全域性變數快取池中取出全域性變數
- 記憶體碎片越少、使用效率越高,則分配和釋放的速度越慢