STM32如何解决堆栈溢出问题及详细分析溢出原因

2019-10-16 00:08发布

在开发过程中,我们有时候可能会遇到数据错误的情况,而这个情况发生多数是由于堆栈溢出导致,这里我们将详细讲解复现堆栈溢出会导致的问题及提供相应的解决方法。 1 .建立一个测试工程 1-函数定义.png 定义主函数 2-堆栈空间大小定义.png 定义堆栈地址大小,分别都定义为0x00000200 5-栈地址.png 编译后查看生成的.map文件,可以看到栈起始地址为0x20000d50,大小为512byte 2. 理论计算分析程序定义了全局变量大小为32位(对应4字节)的700个数据,所以全局变量占用RAM空间计算:G=0x20000000 + 4*700 = 0x20000AF0 由于栈地址是向下生长方式,我们定义了局部变量数据大小为50032位的数,所以实际运行时局部变量占用RAM的起始地址为:L=0x20000D50 + 512 – 4*500 = 0x20000780所以局部变量占用RAM的地址范围为:0x20000780 --- 0x20000F50 由上计算可知,局部变量部分地址空间与全局变量使用的地址空间有冲突,这将导致程序运行过程全局变量数值被局部变量替换掉。 3. 测试论证程序运行测试如下图所示: 3-1全局变量初始化.png 3-2全局变量初始化.png 全局变量初始化完成 4-1局部变量存储起始地址.png 初始化局部变量,由上图可看出原来全局变量的数值已被局部变量替换 4. 解决方法4.1 理论计算由之前可以算出局部变量使用了2000byte的RAM地址空间,由于堆栈地址设置要求是0x0100的整数倍,所以这里可以将大小设置为0x0800,即2048个字节数据。 4.2 设置栈空间大小改大栈空间大小,如下图所示: 7-改大栈空间大小.png 修改栈空间大小后查看生成的.map文件,如下图所示: 8-变大后的map图.png 4.3 修改后测试验证 6-栈修改后起始地址.png 由上图测试可以知道,局部变量存储地址已经从0x20000D80开始,与全局变量存储地址不冲突,至此可以解决遇到的堆栈溢出问题。          上述方法已解决了我们遇到的堆栈溢出问题,但实际编程时,我们不建议在子函数中使用大数组,需要源代码的朋友请添加QQ707372788索取。    关注微信公众号:嵌入式STM32软硬件开发,让自己每周都学多一点嵌入式开发吧

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
18条回答
战舰水手
1楼-- · 2019-10-16 16:22
来俩不甜的 发表于 2016-12-9 16:16
0x20000D50是起始地址,那下面这个式子 +512 是什么意思?
L=0x20000D50 + 512 – 4*500 = 0x20000780
堆 ...

栈的范围就是0x20000D50 ->0x20000D50 + 512
stm32你是我的菜噢
2楼-- · 2019-10-16 17:36
 精彩回答 2  元偷偷看……
来俩不甜的
3楼-- · 2019-10-16 17:58
战舰水手 发表于 2016-12-10 13:03
栈的范围就是0x20000D50 ->0x20000D50 + 512

向下增长什么意思,我感觉是 20000d50 ~ 20000d50-512
stm32你是我的菜噢
4楼-- · 2019-10-16 18:47
来俩不甜的 发表于 2016-12-10 19:57
向下增长什么意思,我感觉是 20000d50 ~ 20000d50-512

向下增长是指数据存储的方式,栈范围是你定义的栈空间,这是两回事,不知道你懂了没有呢
来俩不甜的
5楼-- · 2019-10-16 21:28
stm32你是我的菜噢 发表于 2016-12-11 14:44
向下增长是指数据存储的方式,栈范围是你定义的栈空间,这是两回事,不知道你懂了没有呢

能看得出来是这个意思,还想知道这种东西哪有讲解的?
YMC
6楼-- · 2019-10-16 22:32
确实是好贴 ,这种方法很靠谱,一直寻找可以用软件查找这些问题,却找不到

一周热门 更多>