千家信息网

FreeRTOS动态内存分配管理示例分析

发表于:2025-11-08 作者:千家信息网编辑
千家信息网最后更新 2025年11月08日,本篇内容主要讲解"FreeRTOS动态内存分配管理示例分析",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"FreeRTOS动态内存分配管理示例分析"吧!动态
千家信息网最后更新 2025年11月08日FreeRTOS动态内存分配管理示例分析

本篇内容主要讲解"FreeRTOS动态内存分配管理示例分析",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"FreeRTOS动态内存分配管理示例分析"吧!

动态内存管理

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 );}

适用范围、特点

适用于只需分配,不需释放场合,执行时间确定,不会产生碎片,但是内存利用率不高

到此,相信大家对"FreeRTOS动态内存分配管理示例分析"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

字节 内存 分配 管理 数组 动态 实际 函数 地址 示例 分析 用户 内容 情况 空闲 策略 钩子 学习 调度 实用 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 守护网络安全简报 增强计算机网络安全管理 如何配置电脑服务器 中小学学生网络安全管理制度 连接个人热点什么是网络安全密钥 大学以软件开发 天津正规软件开发过程标准 网络技术中最好玩的是什么 现代战舰服务器下载数据是什么 网络安全管理方法论 查数据库快还是缓存文件快 计算机网络技术需要什么课本 武汉哪里有学习软件开发的 为什么要提升网络安全 淮南电脑服务器回收最新报价 数据库运维安全管理 抖音上恐龙岛是哪个服务器 指挥官杯网络安全竞赛 数据库知网文献下载 网络安全保密 问题隐患 快吧我的世界1.12.2服务器 证券交易软件开发实例 数据接收首选客户端服务器 大话2云水一梦服务器啥时候开的 云服务器带宽哪家便宜 计算机网络技术的创业方向 山西软件开发电话 曲靖进销存软件开发费用 互联网科技图片+psd 苍穹多维数据库
0