FreeRTOS動(dòng)態(tài)內(nèi)存分配管理heap_1示例
動(dòng)態(tài)內(nèi)存管理
FreeRTOS提供5種動(dòng)態(tài)內(nèi)存管理策略,分別為heap_1到heap_5,源碼在FreeRTOS/Source/portable/MemMang下,本質(zhì)是對(duì)一個(gè)或者多個(gè)大數(shù)組進(jìn)行操作來對(duì)系統(tǒng)提供內(nèi)存的申請(qǐng)、釋放(有的策略沒有)功能。下面先看看heap_1是怎么做的。
heap_1.c 內(nèi)存堆管理
大數(shù)組在哪里
/* Allocate the memory for the heap. */ #if( configAPPLICATION_ALLOCATED_HEAP == 1 ) //這種情況是可以把待管理的數(shù)組分配在外部SRAM、SDRAM中 extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; #else //這種情況是把待管理的數(shù)組分配在內(nèi)部RAM,由編譯器決定地址 static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; #endif /* configAPPLICATION_ALLOCATED_HEAP */
可以看到這個(gè)局部靜態(tài)全局大數(shù)組名字是ucHeap,大小是configTOTAL_HEAP_SIZE,這個(gè)宏在FreeRTOSConfig.h中定義
實(shí)際可用數(shù)組字節(jié)數(shù)
//因?yàn)樾枰止?jié)對(duì)齊,所以實(shí)際能使用的內(nèi)存字節(jié)數(shù)要減去portBYTE_ALIGNMENT /* A few bytes might be lost to byte aligning the heap start address. */ #define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )
portBYTE_ALIGNMENT 在portmacro.h中定義
#define portBYTE_ALIGNMENT8
已分配字節(jié)數(shù)
//已經(jīng)分配了的字節(jié)數(shù),也就是下一個(gè)空閑內(nèi)存相對(duì)于首址(pucAlignedHeap)的偏移量 static size_t xNextFreeByte = ( size_t ) 0;
分配
void *pvPortMalloc( size_t xWantedSize )
{
void *pvReturn = NULL;//待返回給用戶分配地址
static uint8_t *pucAlignedHeap = NULL;//實(shí)際管理的數(shù)組首地址
/* Ensure that blocks are always aligned to the required number of bytes. */
//如果不是1字節(jié)對(duì)齊則先需要portBYTE_ALIGNMENT字節(jié)對(duì)齊
#if( portBYTE_ALIGNMENT != 1 )
{
if( xWantedSize & portBYTE_ALIGNMENT_MASK )
{ /* Byte alignment required. */
//如果用戶申請(qǐng)字節(jié)數(shù)不是portBYTE_ALIGNMENT_MASK字節(jié)對(duì)齊的,先要調(diào)整到portBYTE_ALIGNMENT_MASK字節(jié)對(duì)齊
//比如申請(qǐng)13字節(jié),要求portBYTE_ALIGNMENT = 8,
//則xWantedSize = 13+(8-(13&7))=13+(8-5)=16,
//最終申請(qǐng)16字節(jié)
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
}
}
#endif
//掛起調(diào)度器,防止函數(shù)重入
vTaskSuspendAll();
{
if( pucAlignedHeap == NULL )
//說明是第一次調(diào)用此函數(shù)需要對(duì)對(duì)內(nèi)存堆初始化確保內(nèi)存堆首址也是8字節(jié)對(duì)齊
{
/* Ensure the heap starts on a correctly aligned boundary. */
//假設(shè)&ucHeap是0x20000C64,
//則&ucHeap[ portBYTE_ALIGNMENT ]是 0x20000C64+7=0x20000C6B
//pucAlignedHeap = 0x20000C6B & (~0x00000007) = 0x20000C68
//pucAlignedHeap才是實(shí)際操作的堆首址
pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );
}
/* Check there is enough room left for the allocation. */
//已經(jīng)分配的字節(jié)數(shù)xNextFreeByte + 將要分配的字節(jié)數(shù)xWantedSize
//要小于總共有的字節(jié)數(shù)configADJUSTED_HEAP_SIZE
if( ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) &&
//此條件是防止溢出,因?yàn)閮?nèi)存是地址是單調(diào)增長(zhǎng)
( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */
{
/* Return the next free byte then increment the index past this
block. */
//返回地址給用戶
pvReturn = pucAlignedHeap + xNextFreeByte;
//更新已經(jīng)分配了的內(nèi)存字節(jié)數(shù)
xNextFreeByte += xWantedSize;
}
traceMALLOC( pvReturn, xWantedSize );
}
( void ) xTaskResumeAll();
//解掛調(diào)度器
//如果使能的內(nèi)存申請(qǐng)失敗的鉤子函數(shù)當(dāng)申請(qǐng)失敗時(shí)會(huì)執(zhí)行申請(qǐng)失敗鉤子函數(shù)
#if( configUSE_MALLOC_FAILED_HOOK == 1 )
{
if( pvReturn == NULL )
{
extern void vApplicationMallocFailedHook( void );
vApplicationMallocFailedHook();
}
}
#endif
return pvReturn;
}
其中portBYTE_ALIGNMENT_MASK是根據(jù)portBYTE_ALIGNMENT定義,在portable.h中
#if portBYTE_ALIGNMENT == 8 #define portBYTE_ALIGNMENT_MASK ( 0x0007 ) #endif
釋放
可以看到heap_1是沒有提供釋放,是無法釋放的
void vPortFree( void *pv )
{
/* Memory cannot be freed using this scheme. See heap_2.c, heap_3.c and
heap_4.c for alternative implementations, and the memory management pages of
http://www.FreeRTOS.org for more information. */
( void ) pv;
/* Force an assert as it is invalid to call this function. */
configASSERT( pv == NULL );
}
還??臻e字節(jié)數(shù)
size_t xPortGetFreeHeapSize( void )
{
return ( configADJUSTED_HEAP_SIZE - xNextFreeByte );
}
適用范圍、特點(diǎn)
適用于只需分配,不需釋放場(chǎng)合,執(zhí)行時(shí)間確定,不會(huì)產(chǎn)生碎片,但是內(nèi)存利用率不高
以上就是FreeRTOS動(dòng)態(tài)內(nèi)存分配管理heap_1示例的詳細(xì)內(nèi)容,更多關(guān)于FreeRTOS動(dòng)態(tài)內(nèi)存分配管理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
FreeRTOS進(jìn)階信號(hào)量示例的完全解析
這篇文章主要為大家介紹了FreeRTOS進(jìn)階信號(hào)量示例操作的完全解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04
FreeRTOS進(jìn)階系統(tǒng)節(jié)拍時(shí)鐘示例的完全解析
這篇文章主要為大家介紹了FreeRTOS進(jìn)階系統(tǒng)節(jié)拍時(shí)鐘示例的完全解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04
FreeRTOS軟件定時(shí)器apollo中斷狀態(tài)判斷
這篇文章主要為大家介紹了FreeRTOS軟件定時(shí)器apollo中斷狀態(tài)的判斷,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04
FreeRTOS使用任務(wù)通知實(shí)現(xiàn)命令行解釋器
這篇文章主要為大家介紹了FreeRTOS使用任務(wù)通知實(shí)現(xiàn)命令行解釋器,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04
FreeRTOS實(shí)時(shí)操作系統(tǒng)內(nèi)核配置說明
這篇文章主要為大家介紹了FreeRTOS實(shí)時(shí)操作系統(tǒng)內(nèi)核配置及說明,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04
FreeRTOS動(dòng)態(tài)內(nèi)存分配管理heap_2示例
這篇文章主要介紹了FreeRTOS動(dòng)態(tài)內(nèi)存分配管理heap_2示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04
FreeRTOS進(jìn)階之空閑任務(wù)示例完全解析
這篇文章主要為大家介紹了FreeRTOS進(jìn)階之空閑任務(wù)示例的完全解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04
FreeRTOS實(shí)時(shí)操作系統(tǒng)特點(diǎn)介紹
這篇文章主要為大家介紹了FreeRTOS實(shí)時(shí)操作系統(tǒng)特點(diǎn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04
FreeRTOS進(jìn)階列表和列表項(xiàng)示例分析
這篇文章主要為大家介紹了FreeRTOS進(jìn)階系列之列表和列表項(xiàng)示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04
FreeRTOS實(shí)時(shí)操作系統(tǒng)之可視化追蹤調(diào)試
這篇文章主要為大家介紹了FreeRTOS實(shí)時(shí)操作系統(tǒng)之可視化追蹤調(diào)試的示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04

