下载 FreeRTOS
 

出色的 RTOS & 嵌入式软件

内核
最新资讯
FreeRTOS-Plus-TCP 现具有统一的 IPv4 和 IPv6 功能,支持多接口。
为基于 FreeRTOS 的固件实现防砖化 MCU FOTA:
宣布停止支持 FreeRTOS 202012 LTS。
FreeRTOS 网站现已提供简体中文版本
新的 FreeRTOS Long Term Support 版本现已发布。

堆栈使用和堆栈溢出检查

堆栈使用

[另请参阅 uxTaskGetStackHighWaterMark() API 函数]

每个任务都拥有其独立维护的堆栈。 如果使用 xTaskCreate() 创建任务,则用作任务堆栈的内存会从 FreeRTOS 堆自动分配,并通过传递给 xTaskCreate() API 函数的参数来确定内存大小。 如果使用 xTaskCreateStatic() 创建任务, 则用作任务堆栈的内存由应用程序编写者预先分配。 堆栈溢出是应用程序不稳定的一个很常见的原因。 因此,FreeRTOS 提供了两种可选机制, 可帮助开发者检测和纠正这种情况。 所采用的选项使用 configCHECK_FOR_STACK_OVERFLOW 配置常量配置。

请注意,这些选项仅适用于内存映射未分段的架构。 此外,在 RTOS 内核溢出检查开始之前,某些处理器可能会因堆栈损坏而发生故障或异常。 如果 configCHECK_FOR_STACK_OVERFLOW 未设置为 0 ,则应用程序必须提供堆栈溢出钩子函数。 该钩子函数必须 命名为 vApplicationStackOverflowHook(),并具有以下原型:


void vApplicationStackOverflowHook( TaskHandle_t xTask,
                                    signed char *pcTaskName );

xTask 和 pcTaskName 参数分别将违规任务的句柄和名称传递给该钩子函数。 但请注意,根据溢出的严重程度,这些参数本身可能会损坏,在这种情况下, 可直接检查 pxCurrentTCB 变量。

堆栈溢出检查会增加上下文切换的开销,因此建议只在开发或测试阶段使用此检查。


堆栈溢出检测——方法 1

在 RTOS 内核使任务退出运行状态后,堆栈可能达到其最大(最深)值, 因为此时的堆栈会包含任务上下文。 此时,RTOS 内核可以检查处理器堆栈指针是否仍 在有效堆栈空间内。 如果堆栈指针包含超出有效堆栈范围的值, 则调用堆栈溢出钩子函数。

此方法很快,但不能保证可以捕获所有堆栈溢出。 将 configCHECK_FOR_STACK_OVERFLOW 设置为 1 即可使用此方法。


堆栈溢出检测——方法 2

任务首次创建时,其堆栈会填充一个已知值。 任务退出运行状态时,RTOS 内核 可以检查有效堆栈范围内的最后 16 个字节,以确保这些已知值未被任务或中断活动 覆盖。 如果这 16 个字节中的任何一个不再为初始值,则调用堆栈溢出钩子函数。

这种方法比方法 1 效率低,但仍然相当快。 它很可能会捕获堆栈溢出, 但仍无法保证能够捕获所有溢出。

将 configCHECK_FOR_STACK_OVERFLOW 设置为 2 即可使用此方法。




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.