【学习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文件也存在一些缺陷。例如,它无法直接编辑&#…

BM3 链表中的节点每k个一组翻转

这个就是用栈,k个一组判断就好了 /*** struct ListNode {* int val;* struct ListNode *next;* ListNode(int x) : val(x), next(nullptr) {}* };*/ class Solution {public:/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回…

ubuntu设置系统代理

安装trojan等代理工具并配置启动,得到端口号 例如 10.10.1.10:8080系统代理设置 我们将在/etc/profile.d/proxy.sh下添加一个shell脚本文件,这将确保设置适用于所有已登录的用户: sudo vim /etc/profile.d/proxy.sh将以下内容写到文档中&…

学信息系统项目管理师第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…

Qml中double转int类型

在QML中,你可以使用JavaScript的内置函数将double类型转化为int类型。 1.去尾法:使用Math.floor()函数可以将一个double类型的数值向下取整为最接近的整数,Math.floor()将一个double类型的数值去尾转换为int类型。例: var doubl…

华为OD-非严格递增连续数字序列

题目描述 输入一个字符串仅包含大小写字母和数字 求字符串中包含的最长的非严格递增连续数字序列长度 比如: 12234属于非严格递增数字序列 输入描述 输入一个字符串仅包含大小写字母和数字 输出描述 输出字符串中包含的最长的非严格递增连续数字序列长度 示例…

适应高速率网络设备的-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用户…

【Java】【Stream流】分页

在Java开发中,使用Java自带Stream流的API来进行开发是一种常见的做法。 下面是一个简单的例子: 假设我们有一个包含100个数据项的列表。我们需要按照每页10个数据进行分页,并返回指定页码的数据。可以使用Java 8中的流来实现分页&#xff1…

使用 AutoGPTQ 和 transformers 让大语言模型更轻量化

大语言模型在理解和生成人类水平的文字方面所展现出的非凡能力,正在许多领域带来应用上的革新。然而,在消费级硬件上训练和部署大语言模型的需求也变得越来越难以满足。 🤗 Hugging Face 的核心使命是 让优秀的机器学习普惠化 ,而…

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,自行修复。

VS2022 C++修改Window系统DNS源代码V2.0

这是自己使用VS2022 C++编写开发的Window系统下修改DNS脚本程序第2个版本,适合Win10系统和Win7系统。cfg.txt文件存放要修改的DNS,最多4个。 详细源代码如下: setdns.cpp /* 1.全部清空DNSstring strParameter;strParameter = "netsh interface ip delete dns name=\…