网站搜索引擎优化公司,xuzhou网站制作,win10 中国建设银行网站,佛山新网站建设策划本文介绍MCU平台下确定栈空间大小的方法。
通常使用IDE开发MCU程序在生成Image文件时#xff0c;Image文件被划分为代码区#xff0c;数据区#xff0c;BSS区#xff0c;堆区#xff0c;栈区。其中#xff0c;代码区#xff0c;数据区#xff0c;BSS区空间大小由编译器…本文介绍MCU平台下确定栈空间大小的方法。
通常使用IDE开发MCU程序在生成Image文件时Image文件被划分为代码区数据区BSS区堆区栈区。其中代码区数据区BSS区空间大小由编译器最终决定对于MCU堆区一般设置为0唯一不好确定的就是栈区空间的大小了。栈空间大小由非常关键弄不好会导致栈溢出后果非常严重。本文基于实测的方式确定栈区空间的大小。
1.基本概念
栈空间分为静态栈空间和动态栈空间。
1)静态栈空间
静态栈空间大小一般可由编译器分析函数调用关系及调用深度来确定顾名思义它只能分析固定的函数调用关系而我们的MCU程序运行过程中可能会有中断造成函数的调用关系及深度是无法预料的如果仅按静态栈大小来设置栈空间大小很有可能是不够的。查看静态栈空间大小有助于我们确定最小的栈空间大小。
如Keil中可以在Link中增加“--callgraph”来生成静态调用图其中也包括栈的使用也可以用“--infostack”或“--infosummarystack”列出所有全局符号的栈的使用情况。 2)动态栈空间
动态栈空间大小就是我们的程序在运行过程中包含中断的栈空间大小。实际使用的栈空间大小是动态变化的随中断及函数调用而变化确定栈空间的大小就是要确定动态栈空间最大能有多大再预留一定的裕量就是我们在编写程序时需要设置的栈空间大小。也是本文后续要介绍的。 2.方法步骤
1)预先分配一个足够大的栈空间大小这个空间在确定栈空间大小后会修改。这个在Keil中通过“startup.s”文件进行设置在gcc编译器中可通过“.ld”文件确定。同时我们也知道栈顶的位置通常在RAM空间的最后。
2)编写一小段程序初始化这段栈空间大小为一个确定的数字如“0xDEADDEAD”。代码如下
InitStack(0x20003ffb, 0x400);void InitStack(uint32_t Address, uint32_t nLength)
{while ((int32_t)nLength 0){*(volatile uint32_t *)Address 0xDEADDEAD;Address - 4;nLength - 4;}
}
3)运行我们的程序我们可以进行一系列的测试包括外部中断及各种输入以确保程序执行中函数调用关系处于最深的情况。
4)当程序执行完毕后我们检查2)中特定数值被修改的位置这个位置和栈顶的偏移就是我们实际需要的栈空间大小。如我们使用JLink-Commander的“Mem32”指令可在程序运行过程中读取指定地址及长度的数据。指令如下连接过程略
Mem32 20003ffb 0x100
5)获得栈空间大小后为了以防万一步骤3)测试不充分可以再保留一定的裕量如50%将此值作为最终的栈空间大小的设定值。 总结本文介绍了MCU平台下确定栈空间大小的方法。