一、FreeRTOS 内存管理简介
FreeRTOS有两种方法来创建任务,队列,信号量等,一种动态一种静态。静态方法需要手动定义任务堆栈。使用动态内存管理的时候 FreeRTOS 内核在创建任务、队列、信号量的时候会动态的申请 RAM。
我们在移植FreeRTOS时可以看到在 FreeRTOS 源码中有 heap_1.c、heap_2.c、heap_3.c、heap_4.c 和 heap_5.c 五种内存分配方法,我们当时移植的是 heap_4.c。标准 C 库中的 malloc()和 free() 也可以实现动态内存管理,但不是线程安全的,且执行时间不确定,效率低下等等。当内核需要 RAM 的时候可以使用 pvPortMalloc() 来替代 malloc() 申请内存,不使用内存的时候可以使用 vPortFree()函数来替代 free()函数释放内存。
二、内存碎片
内存碎片指的是小块的、碎片化的内存。
如图在分配前的内存堆是完整的。在第一次分配中分配了100B,10B,80B,80B四块内存。随后又释放掉一块10B和80B的内存,虽然最左边80B的内存被释放掉了,但无法与左边的剩余内存进行合并,并且如果下次分配的内存小于80B仍可在这块内存上继续切割。这样会导致内存在多次申请和释放内存后产生很小无法使用的内存碎片。
三、 内存分配方法比较
heap_1:分配简单时间确定;但只能申请内存不能释放内存;
heap_2:可申请可释放;但时间不定,会产生碎片;
heap_3:直接调用C库的malloc和free,简单;但速度慢,时间不定;
heap_4:相邻空间可合并,减少内存碎片产生;但时间不定;
heap_5:可管理多个非连续内存区域的heap_4;但时间不定。
四、内存管理相关API函数
函数 | 描述 |
void*pvPortMalloc(size t xWantedSize) | 申请内存 |
void vPortFree(void * pv) | 释放内存 |
size t xPortGetFreeHeapSize(void) | 获取当前空闲内存的大小 |
void *pvPortMalloc( size_t xWantedSize):
参数:xWantedSize:申请的内存大小,以字节为单位;
返回值:返回一个指针,指向已分配大小的内存;如果申请内存失败,则返回NULL。
void vPortFree( void * pv):
参数:*pv:指针指向一个要释放内存的内存块。
size t xPortGetFreeHeapSize( void ):
返回值:返回当前剩余的空闲内存大小。