【学习FreeRTOS】第20章——FreeRTOS内存管理

1.FreeRTOS内存管理简介

在使用 FreeRTOS 创建任务、队列、信号量等对象的时,一般都提供了两种方法:

  • 动态方法创建:自动地从FreeRTOS管理的内存堆中申请创建对象所需的内存,并且在对象删除后,可将这块内存释放回FreeRTOS管理的内存堆
  • 静态方法创建:需用户提供各种内存空间,并且使用静态方式占用的内存空间一般固定下来了,即使任务、队列等被删除后,这些被占用的内存空间一般没有其他用途
  • 总结:动态方式管理内存相比与静态方式,更加灵活。

除了FreeRTOS提供的动态内存管理方法,标准的C库也提供了函数malloc()和函数free()来实现动态地申请和释放内存。为什么不用标准的C库自带的内存管理算法——因为标准C库的动态内存管理方法有如下几个缺点:

  • 占用大量的代码空间不适合用在资源紧缺的嵌入式系统中
  • 没有线程安全的相关机制
  • 运行有不确定性,每次调用这些函数时花费的时间
  • 可能都不相同·内存碎片化

因此,FreeRTOS提供了多种动态内存管理的算法,可针对不同的嵌入式系统。

2.FreeRTOS内存管理算法

FreeRTOS提供了5种动态内存管理算法,分别为: heap_1、heap_2、heap_3、heap_4、heap_5 。在我们FreeRTOS例程中,使用的均为heap_4内存管理算法

算法优点缺点应用场合
heap_1分配简单,时间确定只允许申请内存,不允许释放内存工程创建的任务等不需要删除
heap_2最适应算法,允许申请和释放内存不能合并相邻的空闲内存块会产生碎片、时间不定频繁创建/删除,且创建的任务堆栈相同
heap_3直接调用C库函数malloc()和 free() ,简单速度慢、时间不定
heap_4首次适应算法,允许申请释放,相邻空闲内存合并减少内存碎片的产生时间不定频繁分配/释放不同大小的内存
heap_5能够管理多个非连续内存区域的 heap_4时间不定内存地址不连续的场景

2.1.heap_1内存管理算法

heap_1只实现了pvPortMalloc,没有实现vPortFree。也就是说,它只能申请内存,无法释放内存。如果你的工程,创建好的任务、队列、信号量等都不需要被删除,那么可以使用heap_1内存管理算法heap_1的实现最为简单,管理的内存堆是一个数组,在申请内存的时候,heap_1内存管理算法只是简单地从数组中分出合适大小的内存,内存堆数组的定义如下所示:

/* 定义一个大数组作为 FreeRTOS 管理的内存堆 */
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];

在这里插入图片描述

2.2.heap_2内存管理算法

  • 相比于heap_1内存管理算法, heap_2内存管理算法使用最适应算法,并且支持释放内存
  • heap_2内存管理算法并不能将相邻的空闲内存块合并成一个大的空闲内存块,不可避免地会产生内存碎片

最适应算法假设heap有3块空闲内存(按内存块大小由小到大排序)︰5字节、25字节、50字节,现在新创建一个任务需要申请20字节的内存:

  1. 找出最小的、能满足pvPortMalloc的内存:25字节
  2. 把它划分为20字节、5字节,返回这20字节的地址,剩下的5字节仍然是空闲状态,留给后续的pvPortMalloc使用
    在这里插入图片描述

2.3.heap_4内存管理算法

heap_4内存管理算法使用了首次适应算法,也支持内存的申请与释放,并且能够将空闲且相邻的内存进行合并,从而减少内存碎片的现象。

首次适应算法: 假设heap有3块空闲内存(按内存块地址由低到高排序)︰5字节、50字节、25字节,现在新创建一个任务需要申请20字节的内存

  1. 找出第一个能满足pvPortMalloc的内存:50字节
  2. 把它划分为20字节、30字节;返回这20字节的地址,剩下30字节仍然是空闲状态,留给后续的pvPortMalloc使用

在这里插入图片描述

2.4.heap_5内存管理算法

heap_5内存管理算法是在 heap_4内存管理算法的基础上实现的,但是heap_5内存管理算法在heap_4内存管理算法的基础上实现了管理多个非连续内存区域的能力,heap_5内存管理算法默认并没有定义内存堆,需要用户手动指定内存区域的信息,对其进行初始化。
适用场景:在嵌入式系统中,那些内存的地址并不连续的场景。

怎么指定一块内存?——使用如下结构体:

typedef struct HeapRegion{uint8_t * 	pucStartAddress; 	/* 内存区域的起始地址 */size_t 		xSizeInBytes; 		/* 内存区域的大小,单位:字节 */
}HeapRegion_t; 

怎么指定多块不连续内存?

Const  HeapRegion_t  xHeapRegions[] ={{ (uint8_t *)0x80000000, 0x10000 }, 	/* 内存区域 1 */	{ (uint8_t *)0x90000000, 0xA0000 }, 	/* 内存区域 2 */{ NULL, 0 } 							/* 数组终止标志 */
};
vPortDefineHeapRegions(xHeapRegions); 

3.FreeRTOS内存管理相关API函数介绍

  • 申请内存——void * pvPortMalloc( size_t xWantedSize )
    xWantedSize:申请的内存大小,以字节为单位;
    返回值:返回一个指针,指向已分配大小的内存。如果申请内存失败,则返回NULL。
  • 释放内存——void vPortFree( void *pv )
    *pv:指针指向一个要释放内存的内存块;
  • 获取当前空闲内存的大小——size_t xPortGetFreeHeapSize( void );
    返回值:返回当前剩余的空闲内存大小.

在一段内存没有被释放之前绝对不能再调用一次函数pvPortMalloc()为其再次分配内存,否则会导致内存泄露

4.API函数分析

4.1.相关变量介绍

  • 定义一个大数组作为 FreeRTOS 管理的内存堆
/* 定义一个大数组作为 FreeRTOS 管理的内存堆 */
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];//一般是10K
  • 内存块结构体介绍
typedef struct A_BLOCK_LINK 
{ struct A_BLOCK_LINK* 	pxNextFreeBlock;	/* 指向下一个内存块 */size_t 					xBlockSize; 		/* 最高位表示内存块是否已经被分配 * 其余位表示内存块的大小 */ 
} BlockLink_t;

4.2.初始化内存堆:prvHeapInit()

在这里插入图片描述
在这里插入图片描述

4.3.空闲内存链表的插入:prvInsertBlockIntoFreeList( )

在这里插入图片描述

在这里插入图片描述

4.4.内存申请:pvPortMalloc( )

在这里插入图片描述

4.5.内存释放:vPortFree( )

在这里插入图片描述

5.FreeRTOS内存管理实验

  • 实验目的:学习使用FreeRTOS内存管理,并观察内存在申请和释放过程中内存大小的变化情况。
  • 实验设计:将设计两个任务: start_task、task1两个任务的功能如下:
    start_task用来创建task1任务
    task1用于按键扫描,当KEYO按下则申请内存,当KEY1按下则释放内存,并打印剩余内存信息
    在这里插入图片描述

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

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

相关文章

使用威胁搜寻增加网络安全

什么是威胁搜寻 威胁搜寻(也称为网络威胁搜寻)是一种主动网络安全方法,涉及主动搜索隐藏的威胁,例如组织网络或系统内的高级持续性威胁和入侵指标。威胁搜寻的主要目标是检测和隔离可能绕过网络外围防御的威胁,使管理…

怎么把pdf转换成jpg格式?

怎么把pdf转换成jpg格式?在我们日常的办公过程中,PDF文件是一个经常被使用来传输文件的格式。它能够确保我们的文件内容不会混乱,并以更加完美的方式呈现出来。然而,PDF文件也存在一些缺陷。例如,它无法直接编辑&#…

学信息系统项目管理师第4版系列02_法律法规

1. 信息安全的法律体系可分为四个层面 1.1. 一般性法律法规,如宪法、国家安全法,国家秘密法 1.2. 规范和惩罚信息网络犯罪的法律,如刑法、《全国人大常委会关于维护互联网安全的决定》等 1.3. 直接针对信息安全的特别规定,如《…

Spring AOP 的实现及原理

目录 什么是 Spring AOP ?AOP 是啥 ?Spring AOP 可以干啥 ? AOP 的组成Spring AOP 的实现Spring AOP 的实现原理 什么是 Spring AOP ? AOP 是啥 ? 我们知道 OOP 是面向对象编程, 那 AOP 又是啥呢 ? AOP(Aspect Oriented Prog…

适应高速率网络设备的-2.5G/5G/10G网络变压器/网络滤波器介绍

Hqst盈盛(华强盛)电子导读:在高速发展的互联网/物联网时代,为满足高网速的网络数据传输需求,网络设备在制造中也要选用合适的网络变压器/滤波器产品,有哪些可供选择的高速率网络变压器产品也是广大采购人员…

jvs-rules(规则引擎)更新:新增功能介绍

jvs-rules更新内容 1.复合变量新增数据补充节点,实现请求回来的数据再以入参方式请求其他数据进行数据补充(例如通过参数A,请求回数据B,再以数据B为入参,请求回数据C) 2.规则流结束节点支持新增、新建、引…

基于jeecg-boot的flowable流程跳转功能实现

更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码: https://gitee.com/nbacheng/nbcio-boot 前端代码:https://gitee.com/nbacheng/nbcio-vue.git 在线演示(包括H5) : http://122.227.135.243:9888 今天我…

【Linux】权限

欢迎来到Cefler的博客😁 🕌博客主页:那个传说中的man的主页 🏠个人专栏:题目解析 🌎推荐文章:题目大解析3 目录 👉🏻shell命令解释器👉🏻Linux用户…

Mysql45讲学习笔记

前言:这篇文章主要总结事务,锁、索引的一些知识点,然后分享一下自己学习小心得,我会从点到线在到面展开说说,对于学习任何知识,我们都应该藐其全貌,不要一开始就选入细节 基础 一、基础架构&a…

基于ssm+vue德云社票务系统源码和论文

基于ssmvue德云社票务系统源码和论文063 开发工具:idea 数据库mysql5.7 数据库链接工具:navcat,小海豚等 技术:ssm 1.选题的依据和意义 互联网时代,随着生活节奏的加快和不断上升的压力,人们急需寻找到情绪的宣泄…

docker第二次作业

1、使用mysql:5.6和 owncloud 镜像,构建一个个人网盘。 拉取镜像 docker pull mysql:5.6 docker pull ow ncloud 运行镜像生成容器 [rootharbor ~]# docker run -d --name mydb1 --env MYSQL_ROOT_PASSWORD123456 mysql:5.6 [rootharbor ~]# docker run -d --name…

Axure RP软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 Axure RP是Axure公司开发的一款原型设计工具,广泛应用于产品设计和UI/UX设计领域。以下是Axure RP软件的主要特点和功能: 原型设计:Axure RP提供了丰富的界面元素和交互元素,用户…

THINKPHP 微联云投票系统源码独立版 + 支持刷礼物

THINKPHP 微联云投票系统源码独立版 支持刷礼物 nginxphp7.2以上 mysql5.6以上 简单测试后台基本没什么问题,暂时发现H5前端有bug,自行修复。

苹果新健康专利:利用 iPhone、Apple Watch 来分析佩戴者的呼吸情况

根据美国商标和专利局(USPTO)公示的清单,苹果获得了一项健康相关的技术专利,可以利用 iPhone、Apple Watch 来分析佩戴者的呼吸系统。 苹果在专利中概述了一种测量用户呼吸功能的系统,通过 iPhone 上的光学感测单元&am…

6. 使用python将多个Excel文件合并到同一个excel-附代码解析

【目录】 文章目录 6. 使用python将多个Excel文件合并到同一个excel-附代码解析1. 目标任务2. 结果展示3. 代码示例4. 代码解析4.1 导入库4.2 调用库的类、函数、变量语法4.3 os.listdir-返回目录中的文件名列表4.4 startswith-用于判断一个字符串是否以指定的前缀开头4.5 ends…

React 使用 useRef() 获取循环中所有子组件实例

目录 背景思考实现完整代码:成功运行后的界面如下: 知识点总结uesRef() 作对象处理useImperativeHandle() 父组件操作引入子组件的内部方法最后 背景 之前项目中使用了antd pro 中的 可编辑表格 (EditableProTable),在页面中表格要经过多层遍…

vue实现表格的动态高度

需求:表格能够根据窗口的大小自动适配页面高度 防抖和节流函数的使用场景是当需要对频繁触发的事件进行限制时,例如: 防抖函数常用于限制用户在短时间内多次触发某一事件,例如搜索框输入并搜索,当用户一直在输入时,我们可以使用防抖函数来避免多次请求搜索结果,减轻服…

【UniApp开发小程序】私聊功能后端实现 (买家、卖家 沟通商品信息)【后端基于若依管理系统开发】

声明 本文提炼于个人练手项目,其中的实现逻辑不一定标准,实现思路没有参考权威的文档和教程,仅为个人思考得出,因此可能存在较多本人未考虑到的情况和漏洞,因此仅供参考,如果大家觉得有问题,恳…

【Flutter】Flutter 使用 infinite_scroll_pagination 实现无限滚动分页

【Flutter】Flutter 使用 infinite_scroll_pagination 实现无限滚动分页 文章目录 一、前言二、安装和基本使用1. 添加依赖2. 基础配置和初始化 三、实际业务中的用法1. 与 API 集成2. 错误处理 四、完整示例1. 创建一个无限滚动列表2. 使用在你的应用中3. 完整代码示例 五、总…

VSCode如何为远程安装预设(固定)扩展

背景 在使用VSCode进行远程开发时(python开发之远程开发工具选择_CodingInCV的博客-CSDN博客),特别是远程的机器经常变化时(如机器来源于动态分配),每次连接新的远程时,都不得不手动安装一些开…