FreeRTOS学习 -- 12、内存管理

1、内存管理简介

(1)创建任务、队列、信号量等对象时,两种内存创建方法:

        动态内存创建:自动地从FreeRTOS管理的内存堆中申请创建对象所需的内存,并且在对象删除后,可将这块内存释放回FreeRTOS管理的内存堆。

        静态内存创建:需用户提供各种内存空间,并且使用静态方式占用的内存空间一般固定下来了,即使任务、队列等被删除后,这些被占用的内存空间一般没有其他用途。

动态方式管理内存比静态方式管理内存更加灵活。

 (2)标准C语言库也提供了函数malloc()和函数free()实现内存的申请和释放,但其存在如下缺点:

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

针对以上缺点,FreeRTOS提供了多种动态内存管理算法,可用于不同的嵌入式系统。

2、FreeRTOS五种内存管理算法

        FreeRTOS提供了5种动态内存管理算法,分别为: heap_1、heap_2、heap_3、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字节的内存:

找出最小的、能满足pvPortMalloc的内存:25字节
把它划分为20字节、5字节,返回这20字节的地址,剩下的5字节仍然是空闲状态,留给后续的pvPortMalloc使用。。

2.3 heap_4内存管理算法

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

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

  • 找出第一个能满足pvPortMalloc的内存:50字节
  • 把它划分为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、内存管理相关API函数

  • 申请内存——void * pvPortMalloc( size_t xWantedSize )

        xWantedSize:申请的内存大小,以字节为单位;
        返回值:返回一个指针,指向已分配大小的内存。如果申请内存失败,则返回NULL。

  • 释放内存——void vPortFree( void *pv )

        *pv:指针指向一个要释放内存的内存块;

  • 获取当前空闲内存的大小——size_t xPortGetFreeHeapSize( void );

        返回值:返回当前剩余的空闲内存大小

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

4、API函数分析

4.1 相关变量介绍

(1)定义一个大数组作为FreeRTOS管理的内存堆:

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

(2)内存块结构体介绍

typedef struct A_BLOCK_LINK 
{ 
	struct A_BLOCK_LINK* 	pxNextFreeBlock;	/* 指向下一个内存块 */
	size_t 					xBlockSize; 		/* 最高位表示内存块是否已经被分配 * 其余位表示内存块的大小 */ 
} BlockLink_t;

4.2 初始化内存堆:prvHeapInit()

4.3 空闲内存链表的插入:

4.4 内存申请:pvPortMalloc( )

4.5 内存释放:vPortFree( )

参考博客:【学习FreeRTOS】第20章——FreeRTOS内存管理-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

unbuntu mysql8.0新建用户及开启远程连接

MySQL更新到8.0以上版本后,在创建连接远程的用户的时候和之前5.x的版本有了很大的不同,不能使用原来同时创建用户和授权的命令。 以下是记录的MySQL8.0创建用户并授权的命令: 查看用户表: user mysql; select host,user,authen…

【医学嵌入模型】中文医疗文本处理大模型 PCL-MedBERT

中文医疗文本处理大模型 PCL-MedBERT 提出背景对ELECTRA限制的深入分析eHealth的创新方法实体识别关系抽取 总结 最近再做医学项目,需要从文本中抽取医学概念和关系,通用模型的抽取效果还可以。 但还想找医学嵌入模型,能够更准确地从文本中识…

每天学习一个Linux命令之scp

每天学习一个Linux命令之scp 在Linux系统中,scp(Secure Copy)是一个用于在本地主机和远程主机之间进行文件传输的命令行工具。它基于SSH协议,通过加密方式传输文件,确保传输的安全性和完整性。scp命令非常强大且使用简…

mapbox-gl扩展sprites图片

在mapbox-gl.js中,通过在styles中设置sprite和glyphs,实现样式图标和字体的加载。而一旦style加载完成,如果重置地图中的style,则会导致地图全部重新加载,图层的顺序,地图上的要素,都会丢失&…

InputStreamReader类详解

咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE相关知识点了,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好…

(十二)图像的Sobel梯度锐化

环境:Windows10专业版 IDEA2021.2.3 jdk11.0.1 OpenCV-460.jar 系列文章: (一)PythonGDAL实现BSQ,BIP,BIL格式的相互转换 (二)BSQ,BIL,BIP存储格式的相互转换算法 (三…

Science Robotics 逼真面部表情的机器人

人类可以产生数千种不同的面部表情来传达无数微妙的情绪状态,这种能力是人类社会互动中最有效和最有效的界面之一。在 2019 年冠状病毒病流行期间,口罩使社交互动变得尴尬,因为它们掩盖了面部表情。同时,当摄像机打开时&#xff0…

鸿蒙OS开发实例:【消息传递】

介绍 在HarmonyOS中,参考官方指导,其实你会发现在‘指南’和‘API参考’两个文档中,对消息传递使用的技术不是一对一的关系,那么今天这篇文章带你全面了解HarmonyOS 中的消息传递 概况 参照官方指导,我总结了两部分…

java中的继承和组合

继承 在java中继承指的是让类与类之间产生父子关系,被继承的类叫做父类或者基类、超类,继承的类叫做子类或者派生类。这里所说的继承和现实生活中的继承可以理解为同一个意思。当子类继承父类时,子类就能使用父类之中的非私有成员&#xff0c…

Topaz Video AI for mac 视频增强软件

Topaz Video AI for Mac是一款专为Mac用户设计的视频增强软件,它利用先进的人工智能技术和机器学习算法,为用户提供卓越的视频编辑和增强体验。 软件下载:Topaz Video AI for mac v4.2.2激活版 这款软件能够快速提高视频的清晰度、色彩饱和度…

Vue2版本封装公共echarts的监听方法

#注意 : 因为一个页面有多个图表,所以封装一个公共的js文件,方便后续使用。 适用于Vue2版本,粘贴即用即可。 1、echartsMixin.js文件如下 // echartsMixin.js import echarts from echartsexport default {data() {return {myC…

翻译 《The Old New Thing》 - Why is a registry file called a “hive“?

Why is a registry file called a “hive“?https://devblogs.microsoft.com/oldnewthing/20030808-00/?p42943 为什么注册表文件被称为‘蜂巢’? Raymond Chen 2003年8月8日 分享一个没用的知识: 话说有一位 Windows NT 的开发者十分讨厌蜜蜂。于是&a…

Delphi模式编程

文章目录 Delphi模式编程涉及以下几个关键方面:**设计模式的应用****Delphi特性的利用****实际开发中的实践** Delphi模式编程的实例 Delphi模式编程是指在使用Delphi这一集成开发环境(IDE)和Object Pascal语言进行软件开发时,采用…

C#属性显示

功能&#xff1a; 显示对象的属性&#xff0c;包括可显示属性、可编辑属性、及不可编辑属性。 1、MainWindow.xaml <Window x:Class"FlowChart.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://sche…

Topaz Gigapixel AI for Mac 图像放大软件

Topaz Gigapixel AI for Mac是一款专为Mac用户设计的智能图像放大软件。它采用了人工智能技术&#xff0c;特别是深度学习算法&#xff0c;以提高图像的分辨率和质量&#xff0c;使得图像在放大后仍能保持清晰的细节。这款软件的特点在于其能够将低分辨率的图片放大至高分辨率&…

跃然纸上的灵感再现,手绘风格的开源绘图白板工具:Excalidraw

Excalidraw&#xff1a;即绘即思&#xff0c;直观呈现未来流程图&#xff01;- 精选真开源&#xff0c;释放新价值。 概览 在撰写文章或构建演示案例的过程中&#xff0c;为了增强视觉表现力和信息传达深度&#xff0c;适时融入图表或图形显得至关重要。Excalidraw作为一款基于…

【2024系统架构设计】案例分析- 4 嵌入式

目录 一 基础知识 二 真题 一 基础知识 1 基本概念 ◆系统可靠性是系统在规定的时间内及规定的环境条件下,完成规定功能的能力,也就是系统无故障运行的概率。或者,可靠性是软件系统在应用或系统错误面前,在意外或错误使用的情况下维持软件系统的功能特性的基本能力。

使用mysql官网软件包安装mysql

确定你的操作系统&#xff0c;我的是Centos myqsl 所有安装包的地址&#xff1a;https://repo.mysql.com/yum/ 如果你是使用rpm安装你可以到对应的版本里面找到对应的包。 mysql 发行包的地址&#xff1a;http://repo.mysql.com/ 在这里你可以找到对应的发布包安装。 这里使用y…

基于单片机的二维码LCD显示控制设计

**单片机设计介绍&#xff0c;基于单片机的二维码LCD显示控制设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的二维码LCD显示控制设计是一个集硬件、软件与通信于一体的综合性项目。此设计的主要目标是实现单片机…