打印

如何解决STM32堆栈放在外扩RAM死机问题?

[复制链接]
15927|41
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tsx1983|  楼主 | 2008-10-17 11:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
发现STM32的堆栈分配到外部RAM,运行就硬FAULT。不知是否有解决办法?
还是STM32的堆栈压根就不能放到外部RAM ?
沙发
香水城| | 2008-10-17 12:19 | 只看该作者

又开辟新战场了:上次我问的问题楼主搞清楚了吗?

使用特权

评论回复
板凳
tsx1983|  楼主 | 2008-10-17 14:03 | 只看该作者

问题是折腾了好久还是没法解决

我用操作系统,任务很多,RAM用量很大,任务的堆栈空间被分配到了外部空间,一运行就FAULT。

使用特权

评论回复
地板
香水城| | 2008-10-17 14:22 | 只看该作者

请问哪个Demo的问题能不能解决?

如果Demo的问题,表示堆栈可以分配到外部RAM。

你的问题是堆栈分配,与程序大小无关。

使用特权

评论回复
5
香水城| | 2008-10-17 14:38 | 只看该作者

楼主可以写一个最小的程序,看看可不可以把堆栈分配到外

使用特权

评论回复
6
tsx1983|  楼主 | 2008-10-17 15:36 | 只看该作者

那个ST的DEMO也不行,到外部RAM立刻FAULT

我查了很多例程,无论是ST官方的例程还是Micrium公司为STM3210E-EVAL移植的例程还是KEIL的例程,都没有使用外部RAM的例子。不知道是偶然因素还是巧合还是另有原因

使用特权

评论回复
7
tsx1983|  楼主 | 2008-10-21 10:47 | 只看该作者

我顶起来

我顶起来,直到找到能解答的高手

使用特权

评论回复
8
lut1lut| | 2008-10-21 11:03 | 只看该作者

什么叫那个demo也不行

你是说库里“SRAM_DataMemory”那个demo么,很符合你的用途啊:Use the external SRAM mounted on STM3210E-EVAL board as program data memory and internal SRAM for Stack.

很多人都跑过这个demo,没有问题的呀。

使用特权

评论回复
9
tsx1983|  楼主 | 2008-10-21 12:22 | 只看该作者

SRAM_DataMemory的Demo ?

我用的是ST的um0549文档里的任何一个DEMO呀。就是ST官方的在STM3210E-EVAL开发板上运行的软件包。我要用里面的工程使用外部512K空间。但是每次都Fault.
lut1lut你用的SRAM_DataMemory那个demo是哪里的?


使用特权

评论回复
10
香水城| | 2008-10-22 13:46 | 只看该作者

STM32堆栈放在外扩RAM死机问题:找到问题的答案了

堆栈的设置是在所有初始化之前做的,STM32是在复位后取向量表的第一个向量作为堆栈指针,取向量表的第二个向量作为第一条指令的入口地址。从这个原理可以看出,在外部RAM还没初始化是是不能访问外部RAM的,如果这时设置堆栈在外扩RAM当然要死机!

使用特权

评论回复
11
tsx1983|  楼主 | 2008-10-22 14:16 | 只看该作者

香主没搞清我的问题哦

我不是设置堆栈放在外扩RAM,而是内部RAM。但是跑一会堆栈就到外部去了。因为用UCOS-II,申请一个数组做任务的堆栈,如果勾上了RAM1,所有的变量都被分配到了外部空间,内部RAM就跟不存在一样。
这个问题用分散加载文件已经解决了一半,昨晚测试了一下,仿真好使,但是脱机就白屏。没来得急不跑操作系统是什么效果。

上次用ST的DEMO测试的结果是只要RAM1打上勾,不管堆栈的初始指针怎么设,因为所有的变量包括堆栈都在外部RAM,所以跑一会堆栈还是回到外部RAM了,然后就硬FAULT了。

使用特权

评论回复
12
tsx1983|  楼主 | 2008-10-22 14:42 | 只看该作者

更正一下香主的说法

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
香水城| | 2008-10-22 18:20 | 只看该作者

谢谢13楼的分析

你有没有尝试先停在BX R0这条指令,查看是否所有寄存器,尤其是堆栈指针和R0的内容是正确的?

使用特权

评论回复
14
tsx1983|  楼主 | 2008-10-23 09:41 | 只看该作者

昨晚的测试结果

回香主。停过BX R0这条指令,所有的值都是正确的。

昨晚又仔细看了一下KEIL底下测试外部RAM的readme,按照说明,要选中微库,勾上外部空间RAM1,把内部IRAM1前面的勾去掉,把启动代码里的相应宏置1,又测试了一下,发现好使了。但这样内部RAM就只能做堆栈了,不能分配变量进去。

但是后来跑了个大点的程序,仿真的时候好使,一脱机就不好使了,而且不好使了之后再用原来的程序去仿真也不好使了。要重新烧写一个使用内部RAM的好使的程序让片子跑起来,然后再去仿真之前那个大程序,又好使了,但只要一断电,就不好使。

也不知道什么原因

使用特权

评论回复
15
香水城| | 2008-10-23 13:22 | 只看该作者

从芯片角度讲可以支持堆栈放在外扩RAM中,但需要正确地设

使用特权

评论回复
16
tsx1983|  楼主 | 2008-10-23 19:28 | 只看该作者

回17楼

我用的可是ST官方的DEMO测试出来的。跟我自己的程序没关系好不好

使用特权

评论回复
17
tsx1983|  楼主 | 2008-10-25 10:57 | 只看该作者

最后测试结果

经过无数次实验,证明STM32堆栈不能放到外部SRAM空间,放到外部空间必死。

堆栈放到内部空间,变量放到外部SRAM,仿真好使,掉电经常起不来,不知道什么原因。要两次上电时间很短能起来,长了就起不来。

使用特权

评论回复
18
Swd21ic| | 2008-10-25 15:09 | 只看该作者

re

看LZ说的问题,都变来变去,真是好笑。 

"不是设置堆栈放在外扩RAM,而是内部RAM。但是跑一会堆栈就到外部去了" 
 

楼主说的是运行uC/OS-II时的全局数组任务堆栈,全局数组分配是在外部SRAM,
因此当OSStart启动侯,使用PSP指到外部的0x68xxx的地址后会死机..
而一开始启动时用的MSP是在内部的SRAM.~ 

使用特权

评论回复
19
香水城| | 2008-10-25 16:58 | 只看该作者

重复地进行错误的操作,做多少次试验结论都是错的

20楼: 最后测试结果 

经过无数次实验,证明STM32堆栈不能放到外部SRAM空间,放到外部空间必死。

堆栈放到内部空间,变量放到外部SRAM,仿真好使,掉电经常起不来,不知道什么原因。要两次上电时间很短能起来,长了就起不来。


请楼主按照我在6楼的建议——“写一个最小的程序演示你的问题”,并把这个程序发上来,大家帮你看看到底是你的程序有问题,还是确如你所说“STM32堆栈不能放到外部SRAM空间”,谢谢。

使用特权

评论回复
20
lut1lut| | 2008-10-28 11:21 | 只看该作者

内部片上SRAM和外部RAM之间数据的相互操作

两种情况:

1.
堆栈放在内部片上RAM,即0x2000,0000开始的地方
全局变量放在外部SRAM
这样的配置对应以下的linker文件

-Z(DATA)DATA_I,DATA_Z,DATA_N=EXTSRAMSTART-EXTSRAMEND
-Z(DATA)CSTACK+_CSTACK_SIZE=RAMSTART-RAMEND

代码中main()函数中的局部数组test_array[20]是处于堆栈的 --> 0x2000,****
全局数组Tab[20]是作为全局变量放置的 --> 0x6800,****

2.
全局变量放在内部片上RAM,即0x2000,0000开始的地方
堆栈放在外部SRAM
这样的配置对应以下的linker文件

-Z(DATA)DATA_I,DATA_Z,DATA_N=RAMSTART-RAMEND 
-Z(DATA)CSTACK+_CSTACK_SIZE=EXTSRAMSTART-EXTSRAMEND

代码中main()函数中的局部数组test_array[20]是处于堆栈的 --> 0x6800,****
全局数组Tab[20]是作为全局变量放置的 --> 0x2000,****

对于IAR的环境来说,需要注意的是<stm32f10x_vector.c>中#define DATA_IN_ExtSRAM,使得在跳到main之前做low_level_init时使能对FSMC的bank1的region3的操作。(当然这是针对于ST的官方评估板,即外部SRAM挂在FSMC的bank1的region3上)

在此不过说明外部SRAM可以作为堆栈使用,并不会有什么hardfault异常。该异常的产生肯定是和用户自己的代码有关,或者环境设置不当造成的。
相关链接:https://bbs.21ic.com/upfiles/img/200712/20071213112742926.zip

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

25

主题

160

帖子

0

粉丝