嵌入式C程序任务堆栈中未使用的空白

时间:2019-02-06 12:46:47

标签: c stack rtos

在运行带有多个任务的RTOS的嵌入式C开发中,每个任务都有自己的堆栈,为什么堆栈在使用的部分之间会有未使用的间隙?

在启动时使用已知模式填充堆栈,以确定最坏情况的堆栈使用情况。当在运行时使用IDE内存查看器查看堆栈内容时,可以在正常堆栈数据之间看到已知模式的间隙。

例如:

Stack top
-----------------
unused area
-----------
used area 2
-----------
unused area
-----------
used area 1
-----------------
Stack bottom

为什么使用普通堆栈会留下间隙而不是连续数据?

任何建议表示赞赏, 谢谢

更新

为回答这些问题,在单个堆栈上发现了96个字节的间隙,堆栈的总大小为0x400字节。

感谢您的所有评论,这里有一些很棒的建议。在这种情况下,由于间隙的大小和一次出现,我可以裁定“对齐”。未初始化的数组可能是导致此问题的原因,因为所有其他RAM最初都是使用与堆栈相同的模式填充的。

我的另一个(有关)思想是堆栈指针损坏,但是由于软件运行没有问题,因此这似乎不太可能。

2 个答案:

答案 0 :(得分:1)

签名模式是一种确定堆栈使用情况的方法,但不是完美的机制-如果什么都没有写入变量,则该模式将不会被修改。

“未使用”是一个误导性术语;宁可未修改是一个更好的描述。

这通常发生在可能没有被充分利用的缓冲区实例中。例如,如果您说过:

char string_buff[128] ;

sprintf( string_buf, "%s", "hello" ) ;

将仅写入string_buff的6个字符,并显示为122字节的“未使用”间隙。

如果对代码进行了修改:

char string_buff[128] = {0} ;

sprintf( string_buf, "%s", "hello" ) ;

整个缓冲区将显示为已使用状态,但需要初始化整个缓冲区。

答案 1 :(得分:0)

我不确定我是否完全了解您。 堆栈之间的间隙可能来自链接器在每个堆栈的“顶部”(即,沿堆栈增加的方向)插入一个安全阈值,以防止任务例程和中断完全耗尽任务堆栈的情况发生-在非托管状态下,中断(实际上是CPU的优先级协议允许的所有可能的中断)可能会在每个任务的基础上增加最大堆栈使用率。在受管理的情况下(大多数RTOS管理中断处理,或者至少可以配置为这样做),至少一小部分中断条目将临时驻留在任务堆栈上,直到OS引导已移至将处理的系统堆栈堆叠当前和所有更高优先级的ISR。因此,在托管中断方案中,每个堆栈的顶部也必须有一个安全余量。