FreeRTOS动态内存分配管理示例分析
本篇内容主要讲解“FreeRTOS动态内存分配管理示例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“FreeRTOS动态内存分配管理示例分析”吧!
动态内存管理
FreeRTOS提供5种动态内存管理策略,分别为heap_1到heap_5,源码在FreeRTOS/Source/portable/MemMang下,本质是对一个或者多个大数组进行操作来对系统提供内存的申请、释放(有的策略没有)功能。下面先看看heap_1是怎么做的。
heap_1.c 内存堆管理
大数组在哪里
#if( configAPPLICATION_ALLOCATED_HEAP == 1 )//这种情况是可以把待管理的数组分配在外部SRAM、SDRAM中extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];#else//这种情况是把待管理的数组分配在内部RAM,由编译器决定地址static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];#endif
可以看到这个局部静态全局大数组名字是ucHeap
,大小是configTOTAL_HEAP_SIZE,这个宏在FreeRTOSConfig.h
中定义
实际可用数组字节数
//因为需要字节对齐,所以实际能使用的内存字节数要减去portBYTE_ALIGNMENT#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;//实际管理的数组首地址 //如果不是1字节对齐则先需要portBYTE_ALIGNMENT字节对齐#if( portBYTE_ALIGNMENT != 1 ){if( xWantedSize & portBYTE_ALIGNMENT_MASK ){//如果用户申请字节数不是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字节对齐{ //假设&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 ) ) );}//已经分配的字节数xNextFreeByte + 将要分配的字节数xWantedSize//要小于总共有的字节数configADJUSTED_HEAP_SIZEif( ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) &&//此条件是防止溢出,因为内存是地址是单调增长( ( xNextFreeByte + xWantedSize ) > xNextFreeByte )){//返回地址给用户pvReturn = pucAlignedHeap + xNextFreeByte;//更新已经分配了的内存字节数xNextFreeByte += xWantedSize;}traceMALLOC( pvReturn, xWantedSize );}( void ) xTaskResumeAll();//解挂调度器//如果使能的内存申请失败的钩子函数当申请失败时会执行申请失败钩子函数#if( configUSE_MALLOC_FAILED_HOOK == 1 ){if( pvReturn == NULL ){extern void vApplicationMallocFailedHook( void );vApplicationMallocFailedHook();}}#endifreturn pvReturn;}
其中portBYTE_ALIGNMENT_MASK是根据portBYTE_ALIGNMENT定义,在portable.h中
#if portBYTE_ALIGNMENT == 8#define portBYTE_ALIGNMENT_MASK ( 0x0007 )#endif
释放
可以看到heap_1是没有提供释放,是无法释放的
void vPortFree( void *pv ){( void ) pv;configASSERT( pv == NULL );}
还剩空闲字节数
size_t xPortGetFreeHeapSize( void ){return ( configADJUSTED_HEAP_SIZE - xNextFreeByte );}
适用范围、特点
适用于只需分配,不需释放场合,执行时间确定,不会产生碎片,但是内存利用率不高
到此,相信大家对“FreeRTOS动态内存分配管理示例分析”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341