如何更改 FreeRTOS 中任务的最大可用堆大小?

How can I change maximum available heap size for a task in FreeRTOS?

我正在通过以下方式在任务中创建元素列表:

        l = (dllist*)pvPortMalloc(sizeof(dllist));

dllist 有 32 字节大。 我的嵌入式系统有 60kB SRAM,所以我希望系统可以轻松处理我的 200 个元素列表。我发现在为 8 个元素分配 space 后,系统在第 9 次 malloc 函数调用(256 字节+)时崩溃。

如果可能,我可以在哪里更改 freeRTOS 中的堆大小? 我可以以某种方式请求堆大小的当前状态吗? 我在文档中找不到此信息,所以我希望有人可以提供一些关于此事的见解。 提前致谢!

对于标准分配器,您将在 FreeRTOSConfig.h 中找到一个配置选项。

但是: 很可能你 运行 已经内存不足,这取决于所使用的分配器。 IIRC 有一个不 free() 任何块(free() 只是一个虚拟)。所以返回的任何块都将丢失。如果您只分配内存,这仍然有用,例如在启动时,然后使用你所拥有的。

其他分配器可能不会在返回后合并相邻的块,增加碎片的速度比成熟的分配器快得多。

此外,您可能会因碎片化而丢失内存。根据您的 alloc/free 模式,您很快可能会得到一个看起来像瑞士奶酪的堆:分配的块之间有许多孔。因此,尽管仍然有足够的可用内存,但没有一个块足够大以满足所需的大小。

如果您只在那里分配那个大小的块,您最好使用自己的分配器或池(固定大小的块)。 Thaqt 将被静态分配(例如数组)并在启动期间链接为链表。 Alloc/free 将只是 push/pop 在堆栈上(或 put/get 在队列上)。这也将非常快并且复杂度为 O(1)(如果编写正确则中断安全)。

请注意,普通的 malloc()/free() 不是中断安全的。

最后:不要投void *。 (好吧,这实际上是标准 malloc() returns,我希望 FreeRTOS 变体也能做到这一点)。

(是 - FreeRTOS pvPortMalloc() returns void*。)

如果您有 60K 的 SRAM,并且 configTOTAL_HEAP_SIZE 很大,那么在分配 256 字节后您不太可能 运行 出堆 除非 你手头几乎没有剩余的堆。许多 FreeRTOS 演示会一直创建对象,直到使用完所有堆,因此如果您的应用程序基于其中一个,那么在执行代码之前您的堆就会不足。您可能还通过创建具有巨大堆栈的任务来耗尽堆负载 space。

heap_4 和 heap_5 将合并相邻的块,这将尽可能减少碎片,但我认为这不是你的问题 - 特别是因为你没有提到释放任何地方。

除非您正在使用 heap_3.c(这只会使标准 C 库 malloc 和空闲线程安全),否则您可以调用 xPortGetFreeHeapSize() 来查看您有多少空闲堆。您可能还可以使用 xPortGetMinimumEverFreeHeapSize() 来查询您离 运行 堆耗尽有多近。更多信息:http://www.freertos.org/a00111.html

您还可以定义一个 malloc() 失败挂钩 (http://www.freertos.org/a00016.html) 以获得 pvPortMalloc() 返回 NULL 的即时通知。