1. 程式人生 > >FreeRTOS筆記(十三)記憶體管理

FreeRTOS筆記(十三)記憶體管理

文章目錄

上一文連結:FreeRTOS筆記(十二)資源管理


01 - 記憶體管理

  回顧一個最開初沒有提問的問題,我們建立任務的時候,會生成一個TCB任務控制塊,它需要在記憶體中佔據一個空間,多工中就會有多個TCB,誰給它們分配好空間?誰負責回收空間?一旦空間不夠怎麼辦?
  任務需要被核心中不同的函式管理,所以肯定是使用全域性變數或者靜態變數,於是一個簡單的回答是使用全域性變數,每建立一個任務就存在一個全域性變數,但是任務的建立是動態的,而全域性變數的定義是靜態的,並不能在系統執行期間再去定義一個全域性變數,所以需要提前準備好一些全域性變數(全域性變數快取池),當需要的時候就分配

,這就是FreeRTOS的記憶體管理,它不是一個硬體,而是一個軟體

Alt
  由於每一個單板的記憶體管理都可以不相同,所以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 - 總結

  • 記憶體動態分配的本質是在全域性變數快取池中取出全域性變數
  • 記憶體碎片越少、使用效率越高,則分配和釋放的速度越慢