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

时间:2015-05-27 08:48:24

标签: embedded malloc heap keil freertos

我正在以下列方式创建任务内的元素列表:

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

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

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

2 个答案:

答案 0 :(得分:4)

(是 - FreeRTOS pvPortMalloc()返回void *。)

如果你有60K的SRAM,并且configTOTAL_HEAP_SIZE很大,那么在分配256个字节之后你不太可能会用完堆,除非你手头几乎没有任何剩余的堆。许多FreeRTOS演示将继续创建对象,直到使用所有堆,因此如果您的应用程序基于其中一个,那么在代码执行之前,您的堆将很少。您可能还通过创建具有大量堆栈的任务来完成诸如堆积空间负载之类的操作。

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的即时通知。

答案 1 :(得分:2)

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

<强>然而 根据使用的分配器,很可能已经耗尽内存。 IIRC有一个没有free()任何块(free()只是一个虚拟)。因此返回的任何块都将丢失。如果您只分配内存,这仍然很有用,例如在启动时,然后使用你已经拥有的东西。

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

此外,您可能会将内存分散到碎片中。根据您的alloc / free模式,您很快就会看起来像瑞士奶酪堆:在分配的块之间有许多漏洞。因此,虽然仍然有足够的可用内存,但没有一个块足够大,可以满足所需的大小。

如果只分配那里大小的块,那么最好使用自己的分配器或池(固定大小的块)。 Thaqt将被静态分配(例如数组)并在启动期间链接为链表。然后,Alloc / free将在堆栈上推送/弹出(或放入/获取队列)。这也会非常快,并且具有复杂性O(1)(如果写得正确,则为中断安全)。

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

最后:不要投射void *。 (嗯,这实际上是标准malloc()返回的内容,我希望FreeRTOS变体做同样的事情。)