FreeRTOS——栈溢出保护

FreeRTOS 基础系列文章

 基本对象
  FreeRTOS——任务
  FreeRTOS——队列
  FreeRTOS——信号量
  FreeRTOS——互斥量
  FreeRTOS——任务通知
  FreeRTOS——流和消息缓冲区
  FreeRTOS——软件定时器
  FreeRTOS——事件组

 内存管理
  FreeRTOS——静态与动态内存分配
  FreeRTOS——堆内存管理
  FreeRTOS——栈溢出保护

 代码组织
  FreeRTOS——源代码组织
  FreeRTOS——创建新的项目
  FreeRTOS——配置文件


栈使用

每个任务都维护自己的。如果使用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 个字节中的任何一个不保持在它们的初始值,就会调用栈溢出钩子函数。

这种方法的效率不如方法一,但仍然相当快。很可能捕获栈溢出,但仍不能保证捕获所有溢出。

configCHECK_FOR_STACK_OVERFLOW 设置为 2 以使用此方法。

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值