发现STM32的堆栈分配到外部RAM,运行就硬FAULT。不知是否有解决办法?
还是STM32的堆栈压根就不能放到外部RAM ?
问题是折腾了好久还是没法解决
我用操作系统,任务很多,RAM用量很大,任务的堆栈空间被分配到了外部空间,一运行就FAULT。
请问哪个Demo的问题能不能解决?
如果Demo的问题,表示堆栈可以分配到外部RAM。
你的问题是堆栈分配,与程序大小无关。
楼主可以写一个最小的程序,看看可不可以把堆栈分配到外
那个ST的DEMO也不行,到外部RAM立刻FAULT
我查了很多例程,无论是ST官方的例程还是Micrium公司为STM3210E-EVAL移植的例程还是KEIL的例程,都没有使用外部RAM的例子。不知道是偶然因素还是巧合还是另有原因
什么叫那个demo也不行
你是说库里“SRAM_DataMemory”那个demo么,很符合你的用途啊:Use the external SRAM mounted on STM3210E-EVAL board as program data memory and internal SRAM for Stack.
很多人都跑过这个demo,没有问题的呀。
SRAM_DataMemory的Demo ?
我用的是ST的um0549文档里的任何一个DEMO呀。就是ST官方的在STM3210E-EVAL开发板上运行的软件包。我要用里面的工程使用外部512K空间。但是每次都Fault.
lut1lut你用的SRAM_DataMemory那个demo是哪里的?
STM32堆栈放在外扩RAM死机问题:找到问题的答案了
堆栈的设置是在所有初始化之前做的,STM32是在复位后取向量表的第一个向量作为堆栈指针,取向量表的第二个向量作为第一条指令的入口地址。从这个原理可以看出,在外部RAM还没初始化是是不能访问外部RAM的,如果这时设置堆栈在外扩RAM当然要死机!
香主没搞清我的问题哦
我不是设置堆栈放在外扩RAM,而是内部RAM。但是跑一会堆栈就到外部去了。因为用UCOS-II,申请一个数组做任务的堆栈,如果勾上了RAM1,所有的变量都被分配到了外部空间,内部RAM就跟不存在一样。
这个问题用分散加载文件已经解决了一半,昨晚测试了一下,仿真好使,但是脱机就白屏。没来得急不跑操作系统是什么效果。
上次用ST的DEMO测试的结果是只要RAM1打上勾,不管堆栈的初始指针怎么设,因为所有的变量包括堆栈都在外部RAM,所以跑一会堆栈还是回到外部RAM了,然后就硬FAULT了。
更正一下香主的说法
ST的DEMO初始化外部RAM访问接口是在启动代码里完成的,也就是在执行MAIN函数之前已经完成了初始化。所以不存在版主所说的因为没有初始化外部RAM而造成的死机。
那么我们再来看下CM3核的启动过程,CPU从复位开始第一个指令就是从向量表的第一个位置取堆栈指针SP的值,再接着从第二个位置取PC的初始值,接着跳转到PC指向的地址执行程序,也就是RESET的地方,在ST的例子里就是初始化外部RAM接口的第一条指令,直到完成外部接口的初始化SP的值都一直不会变,因为初始化指令并未调用函数之类的,所以不存在压栈的操作,SP的值自然就一直是初始的值了,不会变化。启动代码的最后一条指令就是
LDR R0, =__main
BX R0
从上面可以看出是跳转到主程序。但现在是只要分配了外部RAM空间,一执行BX R0就FAULT了。这时再查看SP的值,已经指向了外部RAM了。
谢谢13楼的分析
你有没有尝试先停在BX R0这条指令,查看是否所有寄存器,尤其是堆栈指针和R0的内容是正确的?
昨晚的测试结果
回版主。停过BX R0这条指令,所有的值都是正确的。
昨晚又仔细看了一下KEIL底下测试外部RAM的readme,按照说明,要选中微库,勾上外部空间RAM1,把内部IRAM1前面的勾去掉,把启动代码里的相应宏置1,又测试了一下,发现好使了。但这样内部RAM就只能做堆栈了,不能分配变量进去。
但是后来跑了个大点的程序,仿真的时候好使,一脱机就不好使了,而且不好使了之后再用原来的程序去仿真也不好使了。要重新烧写一个使用内部RAM的好使的程序让片子跑起来,然后再去仿真之前那个大程序,又好使了,但只要一断电,就不好使。
也不知道什么原因
从芯片角度讲可以支持堆栈放在外扩RAM中,但需要正确地设
看LZ说的问题,都变来变去,真是好笑。
"不是设置堆栈放在外扩RAM,而是内部RAM。但是跑一会堆栈就到外部去了"
”发现STM32的堆栈分配到外部RAM,运行就硬FAULT“
你想想这对不对?
是你的程序问题!
不是吗? 自动把堆栈设置到外部RAM,
这不好笑吗? 它知道你的MCU有外部RAM吗?
外部总线已经可以使用了吗?如果外部的不是RAM,
而是SDRAM. 哪不是开国际玩笑!
ARM有个设置: RO BASE 和RW BASE
就是代码的开始地址 和 RAM的 开始地址!
还要就是 一个SP值。
例如我以前是这样设置的:
AT91_SRAM_Stack_Begin EQU 0x00204000
AT91_SDRAM_Stack_Begin EQU 0x21000000
。。。。。。。
。。。。。。
。。。不 聊了。
回17楼
我用的可是ST官方的DEMO测试出来的。跟我自己的程序没关系好不好
最后测试结果
经过无数次实验,证明STM32堆栈不能放到外部SRAM空间,放到外部空间必死。
堆栈放到内部空间,变量放到外部SRAM,仿真好使,掉电经常起不来,不知道什么原因。要两次上电时间很短能起来,长了就起不来。