【FreeRTOS】内存管理简单介绍

有没有想过什么移植FreeRTOS时,为什么有多种的内存文件,我们工程只使用Heap_4,其他的有什么用?每个的区别是什么?FreeRTOS是一种流行的实时操作系统,广泛应用于嵌入式系统开发中。在嵌入式系统中,内存管理是一个非常重要的问题,因为资源有限,必须合理地分配和使用内存。本文将介绍FreeRTOS中的内存管理机制,并给出一些通俗易懂的例子。
在这里插入图片描述


文章目录

    • 1. 内存管理
      • 1.1 静态创建任务
    • 2. 内存管理文件
    • 3. 动态内存管理
    • 总结


系统移植的文章可以查看这个:
【FreeRTOS】FreeRTOS移植stm32详细步骤介绍


1. 内存管理

在FreeRTOS中,创建任务有两种方式:静态创建任务动态创建任务

1.1 静态创建任务

静态创建任务是在编译时为任务分配固定大小的内存块。通过定义任务时的参数来指定任务所需的栈空间大小。静态创建任务的函数是xTaskCreateStatic(),示例如下:

TaskHandle_t xTaskCreateStatic(TaskFunction_t pxTaskCode,const char *pcName,const uint32_t ulStackDepth,void *pvParameters,StackType_t *puxStackBuffer,StaticTask_t *pxTaskBuffer
);

其中,pxTaskCode是任务函数的指针,pcName是任务的名称,ulStackDepth是任务栈的大小,pvParameters是传递给任务函数的参数,puxStackBuffer是任务栈的起始地址,pxTaskBuffer是任务控制块的起始地址。通过静态创建任务,可以在编译时为任务分配固定大小的内存块,避免了动态内存分配的开销和风险。


2. 内存管理文件

在这里插入图片描述

  1. heap_1.c:这是最简单的内存管理实现,它使用静态数组作为堆内存,只能申请,不能释放,就是只实现了malloc功能,没有实现free功能。实现的原理就是定义一个大数组,然后将合适的空间静态的分配给每个任务,如果某个任务或队列信号量等删除了,那么这个空间也没办法释放,所以它适用于只创建,不删除的系统中。

  2. heap_2.c:这是对heap_1.c的改进,它支持动态内存分配和释放,但没有内存块合并的功能。跟Heap_1不一样的是,Heap_2使用最佳匹配算法来分配内存,并且支持了free功能,最佳匹配算法就是加入我要创建一个任务,它需要17字节的空间,算法可以在多个碎片空间内存中找出最佳的空间,例如有20、15、10、5字节的空间,算法就会分配20空间的内存中的17字节给系统使用,剩下的3字节仍然是空闲字节,可以被申请,但是如果一直没有被申请,就形成了内存碎片,所以Heap_2会产生内存碎片。适用于需要动态内存管理的应用场景,但不需要内存块合并的场景。

  3. heap_3.c:这是对heap_2.c的改进,它支持动态内存分配和释放,并且实现了内存块合并的功能。适用于需要动态内存管理的应用场景,且需要内存块合并的场景。

  4. heap_4.c:这是对heap_3.c的改进,它支持动态内存分配和释放,并且实现了内存块合并和分割的功能。Heap_4使用首次适应算法来分配内存,还会将相邻的空闲内存合并成为一个更大的空闲内存,这有助于较少内存的碎片问题,当需要分配一块内存时,FreeRTOS会遍历空闲内存块链表,查找第一个大小大于等于所需内存的空闲内存块。如果找到了满足条件的空闲内存块,FreeRTOS会将其分割成两部分,一部分用于分配,另一部分保留为剩余的空闲内存块。如果没有找到满足条件的空闲内存块,FreeRTOS会根据需要进行堆内存扩展,以满足分配要求。分配完成后,FreeRTOS会返回分配的内存块的起始地址。。适用于需要动态内存管理的应用场景,且需要内存块合并和分割的场景。

  5. heap_5.c:这是最复杂的内存管理实现,它支持动态内存分配和释放,并且实现了内存块合并、分割和按需增减堆内存的功能。适用于需要灵活管理堆内存的应用场景,但需要更多的内存管理开销。

我们很多情况下都是使用Heap_4,有多块内存会使用Heap_5,其他的很少用到。


3. 动态内存管理

动态内存管理是指在运行时根据需要动态分配内存。在FreeRTOS中,可以使用内置的内存管理器来实现动态内存分配。内存管理器提供了两个函数:pvPortMallocvPortFree,分别用于分配和释放内存。

例如,下面是一个动态分配内存的示例:

#include "FreeRTOS.h"
#include "task.h"void vTaskFunction(void *pvParameters) {char *pcBuffer = pvPortMalloc(1024);if (pcBuffer != NULL) {// 使用内存}vPortFree(pcBuffer);
}int main() {xTaskCreate(vTaskFunction, "Task", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);vTaskStartScheduler();return 0;
}

在任务函数中,使用pvPortMalloc函数分配了一个大小为1024字节的内存块,并将其赋值给pcBuffer指针。如果分配成功,就可以使用该内存块。最后,使用vPortFree函数释放内存块。


总结

FreeRTOS提供了静态内存管理和动态内存管理两种方式,可以根据具体情况选择合适的方式。静态内存管理可以避免动态内存分配的开销和风险,但需要在编译时为任务分配固定大小的内存块。动态内存管理可以根据需要动态分配内存,但可能存在内存碎片和分配失败的风险。在实际开发中,应该根据具体情况选择合适的内存管理方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/96587.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(三)行为模式:8、状态模式(State Pattern)(C++示例)

目录 1、状态模式(State Pattern)含义 2、状态模式的UML图学习 3、状态模式的应用场景 4、状态模式的优缺点 (1)优点 (2)缺点 5、C实现状态模式的实例 1、状态模式(State Pattern&#x…

光伏发电预测(LSTM、CNN_LSTM和XGBoost回归模型,Python代码)

运行效果:光伏发电预测(LSTM、CNN_LSTM和XGBoost回归模型,Python代码)_哔哩哔哩_bilibili 运行环境库的版本 光伏太阳能电池通过互连形成光伏模块,以捕捉太阳光并将太阳能转化为电能。因此,当光伏模块暴露…

深入探究 C++ 编程中的资源泄漏问题

目录 1、GDI对象泄漏 1.1、何为GDI资源泄漏? 1.2、使用GDIView工具排查GDI对象泄漏 1.3、有时可能需要结合其他方法去排查 1.4、如何保证没有GDI对象泄漏? 2、进程句柄泄漏 2.1、何为进程句柄泄漏? 2.2、创建线程时的线程句柄泄漏 …

成功解决@Async注解不生效的问题,异步任务处理问题

首先,有这样一个异步监听方法 然后配置好了异步线程池 package com.fdw.study.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Conf…

国产1.8V低电压输入,可用于驱动步进电机;H 桥驱动电路单元可以直接驱动IR-CUT

D6212是专为安防摄像头系统设计的驱动电路,电路由八路达林顿管 阵列和 H 桥驱动电路两个单元组成。八路达林顿管阵列均带有续流二极 管,可用于驱动步进电机;H 桥驱动电路单元可以直接驱动IR-CUT。单个 达林顿管在输入电压低至 1.8V 状态下支持…

口袋参谋:如何提升宝贝流量?这三种方法超实用!

​你的店铺能不能出爆款?提升单品流量是关键。 对于新手卖家来说,是缺乏运营技巧和运营经验的,运营技巧主要体现在标题写作、各种图片和视频制作等。 由于新手买家没有经验,习惯于直接使用数据包上传,导致宝贝没有展…

Java卷上天,可以转行干什么?

小刚是某名企里的一位有5年经验的高级Java开发工程师,每天沉重的的工作让他疲惫不堪,让他萌生出想换工作的心理,但是转行其他工作他又不清楚该找什么样的工作 因为JAVA 这几年的更新实在是太太太……快了,JAVA 8 都还没用多久&am…

cpp primer plus笔记01-注意事项

cpp尽量以int main()写函数头而不是以main()或者int main(void)或者void main()写。 cpp尽量上图用第4行的注释而不是用第5行注释。 尽量不要引用命名空间比如:using namespace std; 函数体内引用的命名空间会随着函数生命周期结束而失效,放置在全局引用的命名空…

PX4仿真添加world模型文件,并使用yolov8进行跟踪

前言 目的:我们是为了在无人机仿真中使用一个汽车模型,然后让仿真的无人机能够识别到这个汽车模型。所以我们需要在无人机仿真的环境中添加汽车模型。 无人机仿真中我们默认使用的empty.world文件,所以只需要将我们需要的模型添加到一起写进这个empty.world文件中去就可以…

jmeter添加断言(详细图解)

先创建一个线程组,再创建一个http请求。 为了方便观察,我们添加两个监听器,察看结果树和断言结果。 添加断言:响应断言,响应断言也是比较常用的一个断言 设置响应断言:正常情况下响应代码是200。选择响应代…

Multisim:JFET混频器设计(含完整程序)

目录 前言实验内容一、先看作业题目要求二、作业正文IntroductionPre-lab work3.13.2 Experiment Work4.1(2)circuit setup4.1(3)add 12V DC4.1(4)set input x1 and x24.1(5)4.1(6)4.1(7)4.2(1)(2)4.2(3)4.2(4)4.3(1)(2)4.3(3) Conclusion 三、资源包内容 前言 花了好大心血完成…

NPDP产品经理知识(产品创新管理)

复习文化,团队与领导力 产品创新管理: 如何树立愿景: 如何实现产品战略=== 计划 实施产品开发: 商业化,营销计划,推广活动

1-Java SE基础

Java SE基础知识总结 背景知识 3种技术架构 Java SE:Java Platform Standard Edition(标准版),完成桌面应用程序的开发,是其它两者的基础Java ME:Java Platform Micro Edition,开发电子消费产…

Vue中如何进行分布式任务调度与定时任务管理

在Vue中进行分布式任务调度与定时任务管理 分布式任务调度和定时任务管理是许多应用程序中的关键功能之一。它们用于执行周期性的、异步的、重复的任务,例如数据备份、邮件发送、定时报告生成等。在Vue.js应用中,我们可以结合后端服务实现分布式任务调度…

关于氮化镓的干蚀刻综述

引言 GaN及相关合金可用于制造蓝色/绿色/紫外线发射器以及高温、高功率电子器件。由于 III 族氮化物的湿法化学蚀刻结果有限,因此人们投入了大量精力来开发干法蚀刻工艺。干法蚀刻开发一开始集中于台面结构,其中需要高蚀刻速率、各向异性轮廓、光滑侧壁…

记一次 .NET某账本软件 非托管泄露分析

一:背景 1. 讲故事 中秋国庆长假结束,哈哈,在老家拍了很多的短视频,有兴趣的可以上B站观看:https://space.bilibili.com/409524162 ,今天继续给大家分享各种奇奇怪怪的.NET生产事故,希望能帮助…

Java基础(二)

1. 面向对象基础 1.1 面向对象和面向过程的区别 面向过程把解决问题的过程拆成一个个方法,通过一个个方法的执行解决问题。面向对象会先抽象出对象,然后用对象执行方法的方式解决问题。 面向对象开发的方式更容易维护和迭代升级、易复用、易扩展。 1…

3D孪生场景搭建:参数化模型

1、什么是参数化模型 参数化模型是指通过一组参数来定义其形状和特征的数学模型或几何模型。这些参数可以用于控制模型的大小、形状、比例、位置、旋转、曲率等属性,从而实现对模型进行灵活的调整和变形。 在计算机图形学和三维建模领域,常见的参数化模…

Docker 镜像的缓存特性

Author:rab 目录 前言一、构建缓存二、Pull 缓存总结 前言 首先我们要清楚,Docker 的镜像结构是分层的,镜像本身是只读的(不管任何一层),当我们基于某镜像运行一个容器时,会有一个新的可写层被…

Springboot 音乐网站管理系统idea开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 springboot 音乐网站管理系统是一套完善的信息系统,结合springboot框架和bootstrap完成本系统,对理解JSP java编程开发语言有帮助系统采用springboot框架(MVC模式开发),系统 具有完整的源代码和数据库&…