硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1308|回复: 2
收起左侧

[STM32H7] 关于初始化时sp寄存器赋值问题

[复制链接]

22

主题

183

回帖

249

积分

高级会员

积分
249
QQ
发表于 2024-5-14 18:07:55 | 显示全部楼层 |阅读模式
sp寄存器是系统堆栈指针,这个堆栈指针是向下生长的。


我使用arm_gcc编译器,依据链接脚本示例,将_estack设置为任意RAM空间的结尾地址,这个值会在startup_xx.s的Reset_Handler,也就是整个程序开始运行时赋值给sp寄存器

示例sp寄存器.png

但是我自己的链接器脚本,这个值不能是任何一个RAM空间结尾地址,而必须减少16字节。否则Reset_Handler赋值sp寄存器时,会跑飞。
链接器脚本.png

因为我是有bootload程序的(跳转部分抄的论坛),是否是bootload程序中的堆栈空间没有清空,导致了程序认为堆栈中有值。但是很奇怪的啊,程序开始运行应该会认为是空堆栈才对,内存有数据也不影响堆栈啊。
bootload跳转.png

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115514
QQ
发表于 2024-5-15 09:49:06 | 显示全部楼层
1、放在末尾的问题,可以用别的IDE测试下,比如MDK或者IARK看看是否正常。
2、你这个BOOT的判断部分,如果你用的是D2或者D3,这个判断是无效的。
回复

使用道具 举报

22

主题

183

回帖

249

积分

高级会员

积分
249
QQ
 楼主| 发表于 2024-6-3 14:38:54 | 显示全部楼层
找到问题在哪里了,是gcc堆栈符号_estack与链接脚本分配堆栈没有正常匹配的问题。
通过比对AC6编译和gcc编译的软件,在bootload跳转到APP的入口处打断点,查看SP、MSP寄存器的差别找到问题。


以下是合理的定义处理


gcc版启动文件中,将符号_estack定义为堆栈顶符号
gcc启动文件.png

这个符号在链接器脚本中定义是这样的才对,需要与_Min_Stack_Size相关联指向真正的堆栈顶
如何定义堆栈顶符号.png
查看map可知确实符号与堆栈确实关联了
堆空间关联.png

以下为cubeMX自动生成,产生误导的链接器脚本
其中堆栈顶符号与链接器分配的堆栈空间并没有关系
误导的链接器.png
查看map可知确实没有关联
无关联的堆顶符.png
至于为什么他这样分配可以正常运行呢?关注到gcc编译必须的这个sysmem.c文件中的_sbrk函数,他已经脱离链接器分配的堆栈空间判定了,而是以堆栈顶符号、bss段结束符号、堆符号进行判定,在这个函数中,事实上将堆符号与堆栈顶符号之间的区域都当成堆栈了,与链接器预分配的大小已经无关了。
sysmem函数.png

回顾我最开始的问题
我事实上是将堆栈空间预分配到D1域RAM中的,但是抄参考链接器脚本时,_estack堆栈顶符号是在DTCM域RAM的末尾,我削减16个字节之后能运行起来也是很神奇,可能这部分RAM本没有数据?然后当堆栈强行用了?

自动生成的参考程序这里真的很不靠谱,再预分配一些段到Stack后他就有崩溃风险了,因为我们用的局部变量非常少,可能很长一段开发过程都不会出问题,后面哪天崩溃debug都不好找。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-4-29 12:27 , Processed in 0.293593 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表