FreeRTOS内存管理
简介
Freertos的内存管理分别在heap_1.c,heap_2.c,heap_3.c,heap_4.c,heap_5.c个文件中,选择合适的一种应用于嵌入式项目中即可。
本文的图片中
红色部分Block代表:在内存对齐过程中舍弃掉的部分字节。
蓝色部分Block代表:链表结构体头,包含可以分配的内存大小和Next指针。
绿色部分Block代表:实际可分配给用户的内存。
黄色部分Block代表:已经分配给用户的内存。
heap_1.c
特点:
- 最简单的内存分配算法。
- 分配后无法释放内存。
- 支持1/2/4/8/16/32多种内存对齐方式。
- 线程安全。
初始化
- ucHeadp数组代表整个堆内存空间。
- xNextFreeByte = 0。
- 初始化以后pucAlignedHeap指针会指向内存对齐后的第一个位置。
*pvPortMalloc():
- 依次返回pvReturn(pucAlignedHeap+xNextFreeByte)所指向的地址,并更新xNextFreeByte大小。
### vPortFree():
- 无法使用,传入的指针非空会进入断言。
heap_2.c
特点:
- 采用链表结构管理,按内存块大小排序。
- 分配后可以释放内存,但是会产生内存碎片。
- 支持1/2/4/8/16/32多种内存对齐方式。
- 线程安全。
初始化
- ucHeap数组代表整个堆内存空间。
- 初始化以后pucAlignedHeap指针会指向内存对齐后的第一个位置。
- xStart表示链表头,pxFirstFreeBlock代表第一块可分配空间,xEnd代表链表尾。
*pvPortMalloc():
- 按内存字节对齐方式调整实际分配大小。(实际大小=内存对齐+链表结点结构体大小)
- 遍历整个内存链表,如果找到足够分配的内存Block头,则加上结构体头偏移量,将pvReturn位置记录待返回给用户,并将该结点从链表中移除。
- 分配完成后,如果剩余的内存大小仍然大于最小的BlockSize(包含链表结构体),就将该Block切割,并按照BlockSize从小到大的方式插入空闲内存链表。
###vPortFree():
- Free的过程非常简单,只是根据传入的指针参数,反向找到结构体头,然后根据该节点BlockSize从小到大重新插入空闲内存链表中即可。
总结:
- 内存的分配和释放过程是线程安全的。
- 在内存分配和释放过程会产生内存碎片,所以heap_2.c不适用于频繁地内存分配的场合。试想这样一种情况:不停地进行小片内存分配(比如:8个字节)直到内存用完,分配完成后全部重新Free,由于结点信息仍然存在,将导致以后都无法分配超过8个字节的内存。
heap_3.c
特点:
- 使用标准库中的malloc和free方法。
- 无法在中断中分配和释放内存。
- 线程安全。
在标准库的基础上,简单地加上线程安全的处理,保证malloc不会被线程切换打断。
heap_4.c
特点:
- 采用链表结构管理,按地址大小排序。
- 分配后可以释放内存,不会产生内存碎片。
- 支持1/2/4/8/16/32多种内存对齐方式。
- 线程安全。
初始化
- ucHeadp数组代表整个堆内存空间。
- 初始化以后pucAlignedHeap指针会指向内存对齐后的第一个位置。
- xStart表示链表头,pxFirstFreeBlock代表第一块可分配空间,xEnd代表链表尾。和heap_2.c不一致的是这里的链尾结构体也分配在ucHeap内存中。
*pvPortMalloc():
- 按内存字节对齐方式调整实际分配大小。(实际大小=内存对齐+链表结点结构体大小)
- 遍历整个内存链表,如果找到足够分配的内存Block头,则加上结构体头偏移量,将pvReturn位置记录待返回给用户,并将该结点从链表中移除。
- 如果剩余的内存大小仍然大于最小的BlockSize(包含链表结构体),就将Block切割,并按照地址从小到大的方式插入内存链表,并更新xFreeBytesRemaining。
###vPortFree():
- 根据传入的指针参数,反向找到结构体头,然后迭代空闲链表,根据该节点的地址从低到高,找到相应的插入位置。
- 当Free的时候,有两种情况,一种是连续(如图中黄色块3),一种是不连续(如图中黄色块1,2)。
- 插入空闲内存链表后,如果该节点与后面的节点是连续的,则将这两个节点整合成一个大的节点。
总结:
- 内存的分配和释放过程是线程安全的。
- 和heap_2.c非常相似,最大不同点在于释放内存的时候不会产生碎片,具体做法是在插入空闲内存链表的时候多了一步操作:如果两个空闲节点在内存上是连续的,则将这两个节点重新整合成一个。
- 另外一点和heap_2.c不同的地方在于,空闲内存链表排序方式不一样,heap_2.c是按照blockSize排序,而heap_4.c是按照内存地址排序,所以heap_4.c的空闲链表在内存上是很容易整合的,而heap_2.c由于没有按内存地址排序,所以整合比较麻烦。
heap_5.c
特点:
- 采用链表结构管理,按地址大小排序。
- 分配后可以释放内存,不会产生内存碎片。
- 支持1/2/4/8/16/32多种内存对齐方式。
- 线程安全。
- 可以自定义内存区。
Malloc和Free方法和heap_4.c一模一样。
区别在与heap_4.c使用prvHeapInit()函数将ucHeap这个全局变量作为内存区,而heap_5.c没有这个prvHeapInit()函数,而是提供了另一个函数vPortDefineHeapRegions(),自己定义内存区。
FreeRTOS内存管理的更多相关文章
- FreeRTOS——内存管理
1. 标准malloc() 和 free() 库函数的缺陷: 1)在小型的嵌入式系统中,可能不可用. 2)具体实现相对较大,占用较多宝贵的代码空间. 3)通常不具备线程安全性. 4)具有不确定性,每次 ...
- FreeRTOS的内存管理
FreeRTOS提供了几个内存堆管理方案,有复杂的也有简单的.其中最简单的管理策略也能满足很多应用的要求,比如对安全要求高的应用,这些应用根本不允许动态内存分配的. FreeRTOS也允许你自己实现内 ...
- FreeRTOS --(2)内存管理 heap1
转载自https://blog.csdn.net/zhoutaopower/article/details/106631237 FreeRTOS 提供了5种内存堆管理方案,分别对应heap1/heap ...
- 轻量级操作系统FreeRTOS的内存管理机制(一)
本文由嵌入式企鹅圈原创团队成员朱衡德(Hunter_Zhu)供稿. 近几年来,FreeRTOS在嵌入式操作系统排行榜中一直位居前列,作为开源的嵌入式操作系统之一,它支持许多不同架构的处理器以及多种编译 ...
- FreeRTOS 动态内存管理
以下转载自安富莱电子: http://forum.armfly.com/forum.php 本章节为大家讲解 FreeRTOS 动态内存管理,动态内存管理是 FreeRTOS 非常重要的一项功能,前面 ...
- FreeRTOS --(6)内存管理 heap5
转载自https://blog.csdn.net/zhoutaopower/article/details/106748308 FreeRTOS 中的 heap 5 内存管理,相对于 heap 4&l ...
- FreeRTOS --(5)内存管理 heap4
FreeRTOS 中的 heap 4 内存管理,可以算是 heap 2 的增强版本,在 <FreeRTOS --(3)内存管理 heap2>中,我们可以看到,每次内存分配后都会产生一个内存 ...
- FreeRTOS --(3)内存管理 heap2
在<FreeRTOS --(2)内存管理 heap1>知道 heap 1 的内存管理其实只是简单的实现了内存对齐的分配策略,heap 2 的实现策略相比 heap 1 稍微复杂一点,不仅仅 ...
- freertos之内存管理
任务.信号量.邮箱才调度器开始调度之前就应该创建,所以它不可能像裸奔程序那样的函数调用能确定需要多少内存资源,RTOS提供了3种内存管理的方法: 1 方法一:确定性好适合于任务.信号量.队列都不被删除 ...
随机推荐
- C# 试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)
C# 在调用C++dll时,可能会出现 :试图加载格式不正确的程序. (异常来自 HRESULT:0x8007000B)这个错误. 一般情况下是C#目标平台跟C++dll不兼容,64位跟32位兼容性问 ...
- LeetCode33 搜索旋转排序数组
搜索旋转排序数组 题目描述: 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 搜索一个给定的目标 ...
- 服务器编程入门(13) Linux套接字设置超时的三种方法
摘要: 本文介绍在套接字的I/O操作上设置超时的三种方法. 图片可能有点宽,看不到的童鞋可以点击图片查看完整图片.. 1 调用alarm 使用SIGALRM为connect设置超时 设置方法: ...
- MySQL 数据库--内置功能
一 视图 视图:是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 优点:们可以把查询过程中的临 ...
- 沉淀再出发:ELK使用初探
沉淀再出发:ELK使用初探 一.前言 ELK是Elasticsearch.Logstash.Kibana的简称,这三者是核心套件,但并非全部. 最近ElasticSearch可以说是非常火的一款开源软 ...
- CentOS7.4 Keepalived+LVS 负载均衡 后台节点健康检查
主机信息 VIP 10.10.10.55 LVS01 10.10.10.59 Web01 10.10.10.60 Web02 10.10.10.61 一.apache简单配置 1.(10.10.10. ...
- [T-ARA][나 어떡해/1977 기억 안나][我怎么办/1977我不记得了]
歌词来源: 我怎么办:https://music.163.com/#/song?id=28111191 1977我不记得了:https://music.163.com/#/song?id=281111 ...
- olivehc--百度开源的cdn cache
github 地址:http://git.baidu.com/olivehc/olivehc 主要是为了方便管理,百度cdn承载了全百度40%的流量,但是cdn团队只有几个人(一次培训中提到只有4个) ...
- storm-kafka
包依赖
- C# winform 数据库操作知识点总结(干货)
1.数据库连接及操作 在说数据库操作之前,先说一下数据库连接操作字符串的获取 首先,点击服务器资源管理器,接下来选中数据连接右键点击添加连接,填入你要连接的服务器名称,点击单选框使用SQL Serve ...