Rtos任务堆栈大小检查

本文介绍了在RTOS和ARM开发中如何估算任务栈大小,包括手动统计、利用IDE和填充数据检测的方法。手动统计涉及局部变量、函数参数、返回地址和任务切换的栈需求,并建议预留安全余量。IDE如MDK可以提供栈需求分析,但无法处理函数指针调用。填充数据法通过设置栈填充字节检测溢出,但存在检测盲区。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

RTOS和ARM 开发过程每个任务都需要自己的栈空间,应用不同,每个任务需要的栈大小也是不同的。总结了几个方法

方法一 (手动统计)

我初步将估算如下的几个选项简单的累加就可以得到粗略的栈大小:

  • 局部变量
  • 函数行参
  • 函数返回地址
  • 任务切换
  • 执行过程中,中断发生

在局部变量和形参在代码运行过程中,如果在嵌套一个函数的时候,这个就发生入栈的操作,所以计算的时候大家要考虑一下。
函数返回地址使用的专用寄存器LR (link register )寄存器里面的,如果函数其他函数的话,这个也是要入栈的。
任务切换的时候,也是保存当前任务的所有寄存器的状态或者值。
发生中断时候,有一部分寄存器会自动入栈(这里的咱是任务栈),发生在中断中的嵌套都是系统栈
计算的时候加这些能考虑全部加上,然后为了保险期间还是留有余量。建议在乘以一个安全系统(这个值一般是2)。当然这是我们能考虑到一些栈的使用,还有一些无法确定情况,比如使用printf函数、还有就是函数指针间接调用。
所有在实际使用过程中还是比较麻烦的。

方法二 —(使用IDE)

一般 IDE 开发环境都有这样的功能,比如 MDK 会生成一个 htm 文件,通过这个文件用户可以知道每个被调用函数的最大栈需求以及各个函数之间的调用关系。但是 MDK无法确定通过函数指针实现函数调用时的栈需求。(好像也是有风险)
在这里插入图片描述

方法三 (使用填充数据)

任务创建的时候将任务栈所有数据初始化为 0xa5,任务切换时进行任务栈检测的时候会检测末尾的 16 个字节是否都是 0xa5,通过这种方式来检测任务栈是否溢出了。相比方法一,这种方法的速度稍慢些,但是这样就有效地避免了方法一里面的部分情况。不过依然不能保证所有的栈溢出都能检测到,比如任务栈末尾的 16 个字节没有用到,即没有被修改,但是任务栈已经溢出了,这种情况是检测不到的。另外任务栈溢出后,任务栈末尾的 16 个字节没有修改,但是溢出部分的栈区数据被修改了,这部分栈区的数据不重要或者暂时没有用到还好,但如果是重要数据被修改将直接导致系统进入硬件异常,这种情况下,栈溢出检测功能也是检测不到的。

	/* Avoid dependency on memset() if it is not required. */
	#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
	{
		/* Fill the stack with a known value to assist debugging. */
		( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) ulStackDepth * sizeof( StackType_t ) );
	}
	```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值