本文由嵌入式企鵝圈原創團隊成員朱衡德(Hunter_Zhu)供稿.
近幾年來,FreeRTOS在嵌入式操作系統排行榜中一直位居前列,作為開源的嵌入式操作系統之一,它支持許多不同架構的處理器以及多種編譯工具鏈,具有輕量級、容易移植和使用的特點。本篇文章將會對FreeRTOS提供的幾種內存分配策略進行介紹,FreeRTOS允許開發者根據自己的項目實際需要選擇不同的內存分配策略或者自定義分配內存策略。
一、FreeRTOS內存分配源碼
FreeRTOS在創建任務、隊列、互斥量、信號量、軟件定時以及事件組的時候需要從RAM中分配內存,源碼目錄:FreeRTOSv9.0.0\FreeRTOS\Source\portable\MemMang下提供了5中內存分配機制的實現,本文將會講解heap1.c, heap2.c, heap4.c三種。
二、配置FreeRTOS內存大小
在FreeRTOSConfig.h頭文件中宏configTOTAL_HEAP_SIZE用於配置內核可用的RAM大小:
在heap1.c, heap2.c, heap3.c源文件中,分配的內存實際上是用一個靜態數組ucHeap來表示:
在MDK編譯后生成的.map文件里面可以查看ucHeap符號信息:
ucHeap屬於RW數據,在RAM中運行時的地址是0x20002788,大小是前面分配的20*1024字節。
三、heap1.c內存分配機制
heap1.c是FreeRTOS提供的多種內存分配策略中最簡單的一種,其使用一個全局靜態變量xNextFreeByte來記錄未分配使用的內存空間的位置,每分配一次就會往后進行偏移。另外,在這種方式中,已經分配的內存不會再釋放。
3.1void *pvPortMalloc(size_t xWantedSize)
應用程序調用此函數請求分配內存,需要注意的是函數中有兩個地方為滿足字節對齊的要求進行調整(cortex-m3為例,8字節對齊):
1)為確保從靜態數組ucHeap中分配給應用程序的內存塊是8字節對齊,函數會判斷xWantedSize是否為8的倍數,如果不是,就會添補字節,因此有時候分配到的內存比實際請求的內存還要多;
2)確保從靜態數組ucHeap中第一個8字節對齊的地方開始進行內存分配,用靜態變量pucAlignedHeap記錄首次對齊的地址作為有效空間的首地址;
內存分配示意圖:
上圖中可以看到ucHeap前面和后面都有因字節對齊而丟棄的空間,所丟棄的空間大小要求的字節對齊數,對於cortex-m3系列是8,實際有效的分配空間為:
即ucHeap數組實際大小減去字節對齊數。
3.2void vPortFree( void *pv )
在這種分配策略中,對於已經分配的內存不進行釋放。
前面主要主要介紹了heap1.c中內存分配的策略,也提到了內存分配過程中字節對齊,在heap2.c和heap4.c中字節對齊的操作和heap1.c中一樣。對於heap2.c和heap4.c的內存分配原理會在下篇”輕量級操作系統FreeRTOS的內存管理機制(二)”中進行講解。