網站首頁 編程語言 正文
動態內存管理
FreeRTOS提供5種動態內存管理策略,分別為heap_1到heap_5,源碼在FreeRTOS/Source/portable/MemMang下,本質是對一個或者多個大數組進行操作來對系統提供內存的申請、釋放(有的策略沒有)功能。下面先看看heap_1是怎么做的。
heap_1.c 內存堆管理
大數組在哪里
/* Allocate the memory for the heap. */ #if( configAPPLICATION_ALLOCATED_HEAP == 1 ) //這種情況是可以把待管理的數組分配在外部SRAM、SDRAM中 extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; #else //這種情況是把待管理的數組分配在內部RAM,由編譯器決定地址 static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; #endif /* configAPPLICATION_ALLOCATED_HEAP */
可以看到這個局部靜態全局大數組名字是ucHeap
,大小是configTOTAL_HEAP_SIZE,這個宏在FreeRTOSConfig.h
中定義
實際可用數組字節數
//因為需要字節對齊,所以實際能使用的內存字節數要減去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
已分配字節數
//已經分配了的字節數,也就是下一個空閑內存相對于首址(pucAlignedHeap)的偏移量 static size_t xNextFreeByte = ( size_t ) 0;
分配
void *pvPortMalloc( size_t xWantedSize ) { void *pvReturn = NULL;//待返回給用戶分配地址 static uint8_t *pucAlignedHeap = NULL;//實際管理的數組首地址 /* Ensure that blocks are always aligned to the required number of bytes. */ //如果不是1字節對齊則先需要portBYTE_ALIGNMENT字節對齊 #if( portBYTE_ALIGNMENT != 1 ) { if( xWantedSize & portBYTE_ALIGNMENT_MASK ) { /* Byte alignment required. */ //如果用戶申請字節數不是portBYTE_ALIGNMENT_MASK字節對齊的,先要調整到portBYTE_ALIGNMENT_MASK字節對齊 //比如申請13字節,要求portBYTE_ALIGNMENT = 8, //則xWantedSize = 13+(8-(13&7))=13+(8-5)=16, //最終申請16字節 xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); } } #endif //掛起調度器,防止函數重入 vTaskSuspendAll(); { if( pucAlignedHeap == NULL ) //說明是第一次調用此函數需要對對內存堆初始化確保內存堆首址也是8字節對齊 { /* Ensure the heap starts on a correctly aligned boundary. */ //假設&ucHeap是0x20000C64, //則&ucHeap[ portBYTE_ALIGNMENT ]是 0x20000C64+7=0x20000C6B //pucAlignedHeap = 0x20000C6B & (~0x00000007) = 0x20000C68 //pucAlignedHeap才是實際操作的堆首址 pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); } /* Check there is enough room left for the allocation. */ //已經分配的字節數xNextFreeByte + 將要分配的字節數xWantedSize //要小于總共有的字節數configADJUSTED_HEAP_SIZE if( ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) && //此條件是防止溢出,因為內存是地址是單調增長 ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */ { /* Return the next free byte then increment the index past this block. */ //返回地址給用戶 pvReturn = pucAlignedHeap + xNextFreeByte; //更新已經分配了的內存字節數 xNextFreeByte += xWantedSize; } traceMALLOC( pvReturn, xWantedSize ); } ( void ) xTaskResumeAll(); //解掛調度器 //如果使能的內存申請失敗的鉤子函數當申請失敗時會執行申請失敗鉤子函數 #if( configUSE_MALLOC_FAILED_HOOK == 1 ) { if( pvReturn == NULL ) { extern void vApplicationMallocFailedHook( void ); vApplicationMallocFailedHook(); } } #endif return pvReturn; }
其中portBYTE_ALIGNMENT_MASK是根據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 ); }
還剩空閑字節數
size_t xPortGetFreeHeapSize( void ) { return ( configADJUSTED_HEAP_SIZE - xNextFreeByte ); }
適用范圍、特點
適用于只需分配,不需釋放場合,執行時間確定,不會產生碎片,但是內存利用率不高
原文鏈接:https://blog.csdn.net/weixin_41572450/article/details/107746378
相關推薦
- 2023-09-18 ECharts 觸發click點擊事件的兩種方式
- 2022-07-24 python單向循環鏈表實例詳解_python
- 2022-04-21 Flutter?設置全局字體的實現_Android
- 2022-05-29 C#對XmlHelper幫助類操作Xml文檔的通用方法匯總_C#教程
- 2022-05-28 Entity?Framework?Core更新時間映射_實用技巧
- 2023-05-23 手把手教你如何一眼分辨是C還是C++_C 語言
- 2022-08-15 gitlab代碼合并(merge request )取消 [默認刪除分支(Delete source
- 2021-11-12 C/C++?Qt?StatusBar底部狀態欄應用教程_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支