龙空技术网

FreeRTOS——堆栈应该用多大

YLFM 383

前言:

如今同学们对“vs2015堆栈大小设置”大约比较关怀,兄弟们都需要分析一些“vs2015堆栈大小设置”的相关内容。那么小编在网络上网罗了一些对于“vs2015堆栈大小设置””的相关知识,希望兄弟们能喜欢,你们快快来了解一下吧!

FreeRTOS FAQ – Memory Usage, Boot Times & Context Switch Times

堆栈应该有多大?

可以使用xTaskCreate()或xTaskCreateStatic()API函数创建任务。 函数的usStackDepth参数指定将分配给正在创建的任务的堆栈大小(换句话说,不是字节!)。 人们通常会问如何确定usStackDepth值,但是,除了以下所述的一种方式之外,使用RTOS确定所需的堆栈数量与编写裸机应用程序( 不使用操作系统)。

就像编写裸机应用程序时一样,所需的堆栈数量取决于以下应用程序特定的参数:

函数调用嵌套深度函数作用域变量声明的数量和大小功能参数数处理器架构编译器编译器优化级别中断服务程序的堆栈要求–对于许多RTOS端口,该要求为零,因为RTOS在进入中断服务程序时将切换为使用专用的中断堆栈。

每次计划程序临时停止运行任务以运行其他任务时,处理器上下文都会保存到任务的堆栈中。 然后,下次任务运行时,已保存的处理器上下文将从任务堆栈中弹出。 保存处理器上下文所需的堆栈空间是RTOS本身唯一增加的任务堆栈需求。

虽然不容易确定要分配多少任务的堆栈,但RTOS确实提供了允许使用务实的尝试和错误方法来调整任务堆栈大小的功能。 可以使用uxTaskGetStackHighWaterMark()API函数来查看实际使用了多少堆栈,如果分配了过多的堆栈,则可以减小堆栈的大小,并且可以使用堆栈溢出检测功能来确定堆栈是否太小 。 此外,可以使用uxTaskGetSystemState()API函数或众多具有FreeRTOS意识的IDE插件之一,一次查看所有RTOS任务的堆栈使用情况。

FreeRTOS下载包含每个端口的演示应用程序,每个演示应用程序随附的FreeRTOSConfig.h文件定义了一个名为configMINIMAL_STACK_SIZE的常量。 强烈建议不要为任务分配的堆栈小于端口演示应用程序中使用的configMINIMAL_STACK_SIZE设置。

See also Erich Styger’s blog post on using the GNU stack analysis tool.()

RAM如何分配给队列?

如果使用xQueueCreateStatic()API函数创建了队列,则该队列所需的RAM由应用程序编写器提供,并且不会发生内存分配。

如果使用xQueueCreate()API函数创建队列,则队列所需的RAM从FreeRTOS堆的xQueueCreate()API函数内分配。

RAM如何分配给任务?

如果使用xTaskCreateStatic()API函数创建任务,则该任务所需的RAM由应用程序编写器提供,并且不会发生内存分配。

如果使用xTaskCreate()API函数创建任务,则该任务所需的RAM从FreeRTOS堆的xTaskCreate()API函数内部分配。

main()使用的堆栈不被任务使用,但是(取决于端口)可以被中断使用。

如何减少使用的RAM数量?

FreeRTOS + Trace可以跟踪内存分配和内存空闲事件,因此在分析并因此优化内存使用方面很有用。在大多数情况下,可以使用直接任务通知来代替二进制信号量。 与二进制信号量(必须创建的通用对象)不同,直接向任务通知直接发送到任务,并且不使用任何RAM。事件组中的每个标志(位)都可以用作二进制信号量,因此可以用一个事件组替换多个二进制信号量。使用uxTaskGetStackHighWaterMark()函数查看可以为较小的堆栈分配哪些任务。使用xPortGetFreeHeapSize()和xPortGetMinimumEverFreeHeapSize()API函数(如果有)来查看分配了多少FreeRTOS堆但从未使用过,并进行相应调整。如果正在使用heap_1.c,heap_2.c,heap_4.c或heap_5.c,并且您的应用程序中没有任何东西直接调用malloc()(与pvPortMalloc()相对),那么请确保未为链接器分配堆C库,因为它将永远不会被使用。将configMAX_PRIORITIES和configMINIMAL_STACK_SIZE(位于portmacro.h中)设置为应用程序可接受的最小值。恢复main()使用的堆栈。一旦启动RTOS调度程序,就不需要在程序进入时使用的堆栈(除非您的应用程序调用vTaskEndScheduler(),仅在PC和Flashlite端口的发行版中直接支持该堆栈,或者直接将其用作中断堆栈)在ARM Cortex-M和RX端口中完成)。每个任务都有自己分配的堆栈,因此一旦RTOS调度程序启动,分配给main()的堆栈就可以重用。最小化main()使用的堆栈。当您创建第一个应用程序任务时,将自动创建空闲任务。因此,在程序进入时(在RTOS调度程序启动之前)使用的堆栈必须足够大,才能嵌套调用xTaskCreate()(或xTaskCreateStatic())。手动创建空闲任务可以满足此堆栈要求的一半。要手动创建空闲任务:

在Sourcetasks.c中找到函数prvInitialiseTaskLists()。

通过调用xTaskCreate()在函数的底部创建空闲任务。从Sourcetasks.c剪切此行并将其粘贴到main()中。

合理化任务数量。在以下情况下,不需要空闲任务:

您的应用程序具有一个永不阻塞的任务。

您的应用程序不对vTaskDelete()进行任何调用。

减少定义BaseType_t使用的数据大小(这可能会增加执行时间)。还可以执行其他一些小的调整(例如,任务优先级队列不需要事件管理),但是如果降至此级别,则需要更多的RAM!

标签: #vs2015堆栈大小设置