FreeRTOS 源代码下载 (V2.5.0 及更高)包含了四个样例 RAM 分配方案。各种示例应用可
视情况使用。下面的小节说明了可用的方案及使用条件,并着重说明了可演示其用法的示例
程序。
每个方案都包含在一个单独的源文件中(分别是heap_1.c、heap_2.c、heap_3.c和heap_4.c),
它们可位于 Source/Portable/MemMang 目录中。若需要可添加其他方案。
方案 1 - heap_1.c
这是所有方案里最简单的。当内存分配后,它不允许释放内存,但除了这点,它适合于大量
的应用。
该算法仅在请求 RAM 时,将一个数组分为更小的块。数组总大小通过定义
configTOTAL_HEAP_SIZE 设置 - 定义于 FreeRTOSConfig.h 中。此方案特点为:
若您的应用永远不会删除任务或队列 (永远不会调用 vTaskDelete () 或 vQueueDelete ()),
则可使用。
• 它是确定性的 (总是用相同时间返回一个块)。
• 它被 PIC、AVR 及 8051 演示应用使用 - 因为它们在调用 vTaskStartScheduler() 后,不会
动态创建或删除任务。
heap_1.c 适用于很多在内核启动前即创建了所有任务和队列的小实时系统。
方案 2 - heap_2.c
此方案使用了最佳适用算法,与方案 1 不同,它允许释放之前分配的块。然而,它不会将相
邻的自由块合并为一个大块。
同样,可用的RAM总量通过定义configTOTAL_HEAP_SIZE设置 - 定义于FreeRTOSConfig.h
中。
此方案特点为:
• 即使应用反复调用 vTaskCreate ()/vTaskDelete () 或 vQueueCreate ()/vQueueDelete ()
(导致多次调用 pvPortMalloc() 和 vPortFree()),仍可使用此方案。
• 若分配和释放的内存为随机大小 —— 仅在每个被删除的任务都有不同的栈深度,或被删
除的队列有不同的长度时才会如此—— 则不应使用此方案。
• 若您的应用创建队列或任务块的顺序不可预测,则可能导致内存碎片问题。可能所有应
用都不会这样,但是应对此了解。
• 它不是确定性的 - 但它也不是效率特别低的。
heap_2.c 适合于很多必须动态创建任务的小实时系统。
方案 3 - heap_3.c
它仅是标准 malloc() 和 free() 函数的封装。它可确保线程安全。此方案特点为:
• 需要链接器建立堆,编译器库提供 malloc() 和 free() 的实现。
• 它不是确定性的。
• 可能会大幅增加内核代码量。
• 它被 PC (x86 单板电脑)演示应用所使用。
方案 4 - heap_4.c
此方案使用了首先适用算法,与方案 2 不同,它不会将相邻的自由内存块合并为一个大块(它
不包含合并算法)。
可用的堆空间总量通过 configTOTAL_HEAP_SIZE 设置 - 定义于 FreeRTOSConfig.h 中。
xPortGetFreeHeapSize() API 函数返回还未分配的堆空间总量(令 configTOTAL_HEAP_SIZE
设置优化),但它不会提供未分配内存如何分片为更小块的信息。
此实现的特点为:
• 即使应用反复删除任务、队列、信号量、互斥量等等,仍可使用此实现。
• 相比于 heap_2 实现,它不容易产生分片为多个小块的堆空间 - 即使在分配和释放的内存
大小随机时也是如此。
• 它不是确定性的 - 但它比多数标准 C 库的 malloc 实现的效率高得多。
对于需要在应用代码中直接使用移植层内存分配方案 (而不是通过调用 API 函数,间接调用
pvPortMalloc() and vPortFree())的应用而言, heap_4.c 尤其有用。 |