每当任务,队列或是信号量被创建时,内核需要进行动态内存分配。当内核请求内存时,其调用 pvPortMalloc()而不是直接调用 malloc();当释放内存时,调用 vPortFree()而不是直接调用 free()。 pvPortMalloc()具有与 malloc()相同的函数原型; vPortFree()也具有与 free()相同的函数原型。
目前最新版FreeRTOS 自带有5种 pvPortMalloc()与 vPortFree()实现范例
heap_1.c, heap_2.c, heap_3.c, heap_4.c, heap_5.c——这三个文件都放在目录 FreeRTOS\Source\Portable\MemMang 中。
原文解释:
heap_1 - the very simplest, does not permit memory to be freed
heap_2 - permits memory to be freed, but not does coalescence adjacent free blocks.
heap_3 - simply wraps the standard malloc() and free() for thread safety
heap_4 - coalescences adjacent free blocks to avoid fragmentation. Includes absolute address placement option
heap_5 - as per heap_4, with the ability to span the heap across multiple non-adjacent memory areas
Heap_1.c 实现了一个非常基本的 pvPortMalloc()版本,而且没有实现 vPortFree()。
如果应用程序不需要删除任务,队列或者信号量,则具有使用 heap_1 的潜质。Heap_1
总是具有确定性。
Heap_2.c 也是使用了一个由 configTOTAL_HEAP_SIZE 定义大小的简单数组。不同于 heap_1 的是, heap_2 采用了一个最佳匹配算法来分配内存,并且支持内存释放。
由于声明了一个静态数组,所以会让整个应用程序看起来耗费了许多内存——即使是在数组没有进行任何实际分配之前。最佳匹配算法保证 pvPortMalloc()会使用最接近请求大小的空闲内存块。
Heap_2.c 并不会把相邻的空闲块合并成一个更大的内存块,所以会产生内存碎片——如果分配和释放的总是相同大小的内存块,则内存碎片就不会成为一个问题。
Heap_2.c 适合用于那些重复创建与删除具有相同栈空间任务的应用程序。 Heap_4.c就优化合并了内存碎片问题。
Heap_3.c 简单地调用了标准库函数 malloc()和 free(),但是通过暂时挂起调度器使得函数调用备线程安全特性。