FreeRTOS的内存管理
FreeRTOS的内存管理
FreeRTOS是目前最流行的实时操作系统内核之一,广泛应用于各种嵌入式设备中。内存管理是操作系统的核心功能之一,FreeRTOS提供了多种内存管理方案以适应不同的应用场景。本文将详细介绍FreeRTOS中的5种内存管理方式,包括它们的实现原理、优缺点以及适用场景。
FreeRTOS的内存管理方式
在FreeRTOS源码中,共有5个关于内存管理的文件,分别对应内存管理的5种方式,它们是heap_1.c、heap_2.c、heap_3.c、heap_4.c、heap_5.c。
"堆"(heap)的意思是一块空闲的内存,需要提供管理函数。在C语言中,有malloc
与free
函数,malloc
函数的作用就是从堆里划分出一块空间给程序使用,而free
函数的作用是将用完的内存标记为"空闲",以便下次再用。
与之对应的是"栈"(stack),函数调用时将局部变量保存在栈中,包括当前程序的环境也是保存在栈中,可以从堆中分配一段空间用作栈。
在FreeRTOS中内存管理的接口函数为pvPortMalloc
,vPortFree
,对应C库的malloc
、free
。文件在portable
目录下,表示你可以提供自己的函数。
5种内存管理方式的优缺点
文件 | 优点 | 缺点 |
---|---|---|
heap_1.c | 分配简单,时间确定 | 只分配,不回收 |
heap_2.c | 动态分配,最佳匹配 | 碎片,时间不定 |
heap_3.c | 调用标准库函数 | 速度慢,时间不定 |
heap_4.c | 相邻空闲内存可合并 | 解决碎片问题,时间不定 |
heap_5.c | 在heap_4基础上支持分隔的内存块 | 解决碎片问题,时间不定 |
在实际应用中,heap_4是最常用的内存管理方法。
5种内存管理方法的学习理解
heap_1
heap_1适用于程序不需要删除内核对象的场景,这是因为它只实现了pvPortMalloc
,没有实现vPortFree
。它的实现最简单,没有碎片问题,在一些要求非常严格的系统里,不允许使用动态内存,就可以使用heap_1。
heap_2
heap_2还在使用是为了兼容以前的代码,新设计中都是使用heap_4来替代heap_2,更加高效。
heap_2也是在数组上分配内存,和heap_1不一样的是它支持了最佳匹配算法来分配内存,同时它支持了vPortFree
。那么什么是最佳匹配算法呢?假设heap有3块空闲内存:5字节、25字节、100字节,vPortMalloc
想申请20字节,算法就会负责找出最小同时还能满足申请的字节(这个例子里是25字节),把它划分为20字节和5字节,20字节给申请使用,5字节仍是空闲状态,留给后续使用。
heap_2的缺点是不会合并相邻的空闲内存,所以会导致严重的碎片化问题。同样的,它却适用于频繁的创建、删除任务,前提是任务的栈的大小都是相同的。
heap_3
heap_3使用标准C库里的malloc
、free
函数,所以堆大小由链接器的配置决定,配置项configTOTAL_HEAP_SIZE
不再起作用。
C库里的malloc
、free
函数并非线程安全的,Heap_3中先暂停FreeRTOS的调度器,再去调用这些函数,使用这种方法实现了线程安全。
heap_4
heap_4使用首次适应算法来分配内存,还会把相邻的空闲内存合并为一个较大的空闲内存,这有助于较小内存的碎片问题。
举例说明以下首次适应算法:假设堆中有3块空闲内存,分别是5字节、200字节、100字节。pvPortMalloc
想申请20字节,找出第一个满足20字节的内存(200字节),把它划分成20字节,180字节,返回这20字节的地址,剩下的180字节仍然是空闲状态,以便后续使用。
heap_4的合并相邻内存的功能使用以下场景:频繁的分配、释放不同大小的内存。
heap_5
heap_5分配内存、释放内存的算法和heap_4是一样的,相对于heap_4,heap_5并不局限于管理一个大数组:它可以管理多块、分隔开的内存。当内存的地址并不连续时,这种场景下可以使用heap_5
既然内存是分隔开的,那么就需要进行初始化,确定这些内存块在哪、多大。
- 在使用
pvPortMalloc
之前,必须先指定内存块的信息 - 使用
vPortDefineHeapRegions
来指定这些信息
本文原文来自CSDN