简体   繁体   English

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

[英]Unused gaps in Embedded C program's task stack

In an embedded C development running an RTOS with multiple tasks, where each task has its own stack, why would a stack have an unused gap in between used sections? 在运行带有多个任务的RTOS的嵌入式C开发中,每个任务都有自己的堆栈,为什么堆栈在使用的部分之间会有未使用的间隙?

The stacks are populated with a known pattern at startup to determine worst-case stack usage. 在启动时使用已知模式填充堆栈,以确定最坏情况下的堆栈使用情况。 When the stack contents are viewed at run-time using an IDE memory viewer, a gap of the known pattern can be seen between normal stack data. 当在运行时使用IDE内存查看器查看堆栈内容时,可以在正常堆栈数据之间看到已知模式的间隙。

For example: 例如:

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

Why would normal stack use leave a gap instead of contiguous data? 为什么正常使用堆栈会留下间隙而不是连续数据?

Any suggestions appreciated, thanks 任何建议表示赞赏,谢谢

Update 更新资料

To answer the questions, a single gap of 96 bytes has been seen on a single stack where the total stack size is 0x400 bytes. 为了回答这些问题,在总堆栈大小为0x400字节的单个堆栈上看到96个字节的间隙。

Thank you for all of your comments, there are some great suggestions. 感谢您的所有评论,这里有一些很棒的建议。 In this case I can rule Alignment due to the size of the gap and the single occurrence. 在这种情况下,由于间隙的大小和一次出现,我可以裁定“对齐”。 An uninitialised array is probably the cause as all other RAM is initially populated with the same pattern as the stacks. 未初始化的数组可能是引起问题的原因,因为所有其他RAM最初都使用与堆栈相同的模式进行填充。

My other (concerning) thought was a corrupt stack pointer but this seems unlikely as the software runs without issue. 我的另一个(有关)思想是堆栈指针损坏,但这似乎不太可能,因为该软件可以正常运行。

The signature pattern is a method of determining stack usage, but is not a perfect mechanism - if nothing is ever written to a variable, the pattern will not be modified. 签名模式是一种确定堆栈使用情况的方法,但不是完美的机制-如果什么都没有写入变量,则该模式将不会被修改。

"Unused" is a misleading term; “未使用”是一个误导性术语; rather not modified is a better description. 不是修改是一个更好的描述。

This would commonly occur in instances of buffers that might not be fully utilised. 这通常发生在可能未充分利用的缓冲区实例中。 For example if you had say: 例如,如果您说过:

char string_buff[128] ;

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

only 6 characters of string_buff will be written, and show as a 122 byte "unused" gap. 仅会写入string_buff 6个字符,并显示为122字节的“未使用”间隙。

If the code were modified thus: 如果代码被修改为:

char string_buff[128] = {0} ;

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

The entire buffer would show as used at the expense of initialising the entire buffer. 整个缓冲区将显示为已使用,但需要初始化整个缓冲区。

I am not completely sure I understand you. 我不确定我是否了解您。 The gaps between stacks can come from the linker inserting a safety threshold on "top" (that is, in the direction of stack increase) of each stack to protect from the situation where a tasks stack is used up completely by task routines and an interrupt occurs - in an unmanaged situation the interrupt, in fact all possible interrupts which are allowed by the priority protocol of your CPU, may add on top of each tasks maximum stack usage. 堆栈之间的间隙可能来自链接器在每个堆栈的“顶部”(即,沿堆栈增加的方向)插入一个安全阈值,以防止任务例程和中断完全耗尽任务堆栈的情况发生-在非托管状态下,中断(实际上是CPU的优先级协议允许的所有可能的中断)可能会在每个任务的基础上增加最大堆栈使用率。 In a managed situation (most RTOS manage interrupt handling, or can at least be configured to do so) at least a small portion for the interrupt entry will temporarily reside on the task stack until the OS vectoring has moved to a system stack which will handle stacking the current and all higher priority ISRs. 在受管理的情况下(大多数RTOS管理中断处理,或者至少可以配置为这样做),至少一小部分中断条目将临时驻留在任务堆栈上,直到OS引导已移至将处理的系统堆栈堆叠当前和所有更高优先级的ISR。 Thus also in a managed interrupt scheme there needs to be a safety margin on top of each stack. 因此,同样在托管中断方案中,每个堆栈顶部都需要有安全余量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM