OpenEdv-开源电子网

 找回密码
 立即注册

扫一扫,访问微社区

正点原子新作:阿波罗STM32F767&F429&探索者STM32F4开发板&赶快来下载资料哦。

查看: 8702|回复: 28

外部SRAM实验,让STM32的外部SRAM操作跟内部SRAM一样

  [复制链接]
头像被屏蔽

  离线 

56

主题

497

帖子

4

精华

金牌会员

Rank: 6Rank: 6

积分
1834
金钱
1834
注册时间
2013-11-18
在线时间
247 小时
发表于 2015-3-8 20:13:55 | 显示全部楼层 |阅读模式
正点原子公众号

        前几天看到论坛有人在问这个问题,我特意去做了这个实验,这样用外部SRAM就跟用内部SRAM一样,不用自己去申请内存,也不用考虑什么内存地址,一切让编译器自己去解决。

        废话不多说,我直接拿原子哥的战舰开发板库函数版的外部SRAM实验来修改。在库函数的system_stm32f10x.c这个初始化文件当中其实就已经有外部SRAM的初始化,我们只要增加“#define DATA_IN_ExtSRAM 1”这句宏定义

[C] 纯文本查看 复制代码
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
/* #define DATA_IN_ExtSRAM */
#define DATA_IN_ExtSRAM 1
#endif

        再编译的时候就会把外部SRAM的初始化编译进去,初始化的代码大家可以去看文件中的void SystemInit_ExtMemCtl(void) 这个函数。然后我们在工程设置那里把外部SRAM地址增加进去,如下图

       修改启动文件中的中的第39行,把__initial_sp 修改成 __initial_sp  EQU 0x20000000 + Stack_Size

        然后我们把Main中的testsram中的地址去掉,让编译器自己去指定地址

        再把原子哥的外部SRAM的初始化注释掉,因为前面已经在System_init已经初始化了。其实这里我们可以把原子的SRAM.c文件去掉不用它了,我这里没去掉,其实只是为了能正常调用fsmc_sram_test()来测试实验结果

        到这里我们可以编译了,下载到开发板,我们就可以看到实验结果

        我们继续深入点,看看testsram[]这个大数组到处编译在到哪里去了,用IDA64来反汇编下编译出来的AXF文件

        可以看到testsram这个大数组自动编译到外部sram的0x68000000这个地址上。我们再试试再定义几个大数组看看

        再来看看编译后的结果

       可以看到每个大数组都由编译器自己分配了内存的地址,压根不用我们自己去定义。

       到这里相信大家会有一个疑问,那编译是怎么来决定把哪些变量定义在内部SRAM,那些定义在外部SRAM。这一点我也研究清楚,我只知道编译会优先把变量都定义外部SRAM,当外部SRAM不够用情况才会定义在内部SRAM上,至于怎么让编译优先使用内部SRAM,我也没有搞明白。目前我能做到的是把已经初始化的全局变量都放在SRAM,做法是修改散列文件,让RW只在内存SRAM上编译。

       去掉小红框的勾,然后点击Edit我们来修改SRAM.sct文件,也就是编译散列文件

       把RW_RAM1中(也就是外部SRAM)的+RW去掉,这样已经初始化的全局变量就只会编译在内部SRAM中

       重新编译下工程,再来反汇编下看看编译结果

        可以看到usmart_nametab[]这个已经初始化的数组编译在内部SRAM上,adc2[]这个未初始化的数组,数组的大小比较而且能在内部Sram编译得下的,却还是编译在外部SRAM上。

        最后散列相关的知识,大家可以看看这里http://blog.csdn.net/lindabell/article/details/8957968#0-qzone-1-11984-d020d2d2a4e8d1a374a433f596ad1440

        前面没有修改启动文件,其它变量全部在内部SRAM的时候,程序运行是没有问题,减小数组的时候程序运行不起来,修改前面的红字部分后,程序就可以运行起来,但是LCD偶尔正常,偶尔不正常,调试下感觉是延时的问题,没有再继续调试了

签名被屏蔽
回复

使用道具 举报

  离线 

56

主题

4553

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
5461
金钱
5461
注册时间
2012-11-26
在线时间
937 小时
发表于 2015-3-8 20:31:23 | 显示全部楼层
楼主 请教一下 
你都把FSMC初始化干掉了,是怎么调用fsmc_sram_test()的 ?
道不同,不相与为谋
回复 支持 反对

使用道具 举报

头像被屏蔽

  离线 

56

主题

497

帖子

4

精华

金牌会员

Rank: 6Rank: 6

积分
1834
金钱
1834
注册时间
2013-11-18
在线时间
247 小时
 楼主| 发表于 2015-3-8 20:36:38 | 显示全部楼层
回复【2楼】jermy_z:
---------------------------------
我没有把FSMC初始化的干掉,我只是没有用原子哥的SRAM的代码了,直接用官方库自带的FSMC初始化,在SystemInit里就初始化外部SRAM,为的是在进去Main之前先初始化SRAM,因为进入Main之前会先初始化堆栈,必须要先初始化外部SRAM
签名被屏蔽
回复 支持 反对

使用道具 举报

  离线 

56

主题

4553

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
5461
金钱
5461
注册时间
2012-11-26
在线时间
937 小时
发表于 2015-3-8 20:41:51 | 显示全部楼层
回复【3楼】mzwhhwj:
---------------------------------
嗯  刚看了下代码 确实是这样  只要启用了那个宏就行了   感谢楼主分享
道不同,不相与为谋
回复 支持 反对

使用道具 举报

  离线 

113

主题

7460

帖子

12

精华

资深版主

Rank: 8Rank: 8

积分
10784
金钱
10784
注册时间
2013-9-10
在线时间
331 小时
发表于 2015-3-8 21:27:38 | 显示全部楼层
谢谢分享!!!

原子哥必须给精华啊
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

  离线 

485

主题

9万

帖子

30

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
120495
金钱
120495
注册时间
2010-12-1
在线时间
963 小时
发表于 2015-3-8 22:18:29 | 显示全部楼层
非常好,cool.
不过这种方法,如果速度要求比较严格,还是少用比较好.
建议自己控制到底用内部还是外部内存.可控性高.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
微信公众平台:正点原子   点击扫码添加
回复 支持 反对

使用道具 举报

  离线 

113

主题

7460

帖子

12

精华

资深版主

Rank: 8Rank: 8

积分
10784
金钱
10784
注册时间
2013-9-10
在线时间
331 小时
发表于 2015-3-9 08:04:17 | 显示全部楼层
回复【6楼】正点原子:
---------------------------------
每一种方法都有优点和缺点的,合适就行了,呵呵
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

  离线 

4

主题

120

帖子

1

精华

高级会员

Rank: 4

积分
739
金钱
739
注册时间
2014-8-7
在线时间
36 小时
发表于 2015-3-9 09:00:50 | 显示全部楼层
谢谢分享~~~
回复 支持 反对

使用道具 举报

  离线 

13

主题

31

帖子

0

精华

新手上路

Rank: 1

积分
15
金钱
15
注册时间
2013-4-28
在线时间
6 小时
发表于 2015-7-21 16:38:21 | 显示全部楼层
407+uCOSIII, 之前用的内部SRAM, 在调节任务堆栈的时候发现内存有点不足, 然后通过楼主的方式通过编译器定义到了外部SRAM上, 没有改Linker, 程序倒是运行正常, 但是通过串口助手调通讯的时候发现, 同样的发送间隔, 之前都是一条发一条收, 现在没那么完美了,偶尔会2对1或3对1的, 不知道是我程序的问题还是因为使用外部SRAM的问题?
qq:839948230
回复 支持 反对

使用道具 举报

  离线 

25

主题

83

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
212
金钱
212
注册时间
2014-12-18
在线时间
10 小时
发表于 2015-10-8 18:37:01 | 显示全部楼层

请问楼主

我做了同样的设置为什么进入不了main呢?

现在的现象是:

1.单独测试,外部扩展的RAM是可以正确读写的

2.进入不了main函数

另外,和楼主不同的是我的带一个Freertos系统,外加一个bootloader


回复 支持 反对

使用道具 举报

  离线 

7

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2015-1-16
在线时间
1 小时
发表于 2015-12-4 17:26:19 | 显示全部楼层

请问一下,你这样搞过之后,原子大哥的内存管理函数还能用吗

回复 支持 反对

使用道具 举报

  离线 

76

主题

245

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
341
金钱
341
注册时间
2014-8-11
在线时间
53 小时
发表于 2015-12-6 02:56:37 | 显示全部楼层
学习了,mark一下
我是一只菜鸟,但我会大鹏展翅
回复 支持 反对

使用道具 举报

  离线 

0

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2016-3-7
在线时间
17 小时
发表于 2016-3-8 18:06:08 | 显示全部楼层
mzwhhwj 发表于 2015-3-8 20:36
回复【2楼】jermy_z:
---------------------------------
我没有把FSMC初始化的干掉,我只是没有用原子哥的 ...

直接用官方库自带的FSMC初始化
这个地方是类似于初始化GPIO,还是有一个专门的函数,直接调用就可以了呢?
回复 支持 反对

使用道具 举报

  离线 

104

主题

367

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1985
金钱
1985
注册时间
2015-10-5
在线时间
319 小时
发表于 2016-3-14 18:47:30 | 显示全部楼层
这个程序在407上怎么改???我没有找到
回复 支持 反对

使用道具 举报

  离线 

0

主题

3

帖子

0

精华

新手上路

Rank: 1

积分
11
金钱
11
注册时间
2016-4-2
在线时间
2 小时
发表于 2016-4-2 23:20:14 | 显示全部楼层
楼主,能不能帮忙指教一下407的改法?
回复 支持 反对

使用道具 举报

  离线 

6

主题

91

帖子

0

精华

高级会员

Rank: 4

积分
761
金钱
761
注册时间
2014-11-15
在线时间
90 小时
发表于 2016-4-3 22:47:02 | 显示全部楼层
学习了,顶
回复 支持 反对

使用道具 举报

  离线 

3

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
71
金钱
71
注册时间
2015-4-22
在线时间
7 小时
发表于 2016-5-20 16:53:12 | 显示全部楼层
本帖最后由 东周往事 于 2016-5-23 09:38 编辑

您好,关于您提到的将启动文件中   __initial_sp  改为__initial_sp    EQU     0x20000000 + Stack_Size  我不知道是何缘故?如何理解呢?改变之后,系统将进入硬件异常,void HardFault_Handler(void)  。
回复 支持 反对

使用道具 举报

  离线 

4

主题

38

帖子

0

精华

初级会员

Rank: 2

积分
155
金钱
155
注册时间
2014-11-28
在线时间
26 小时
发表于 2016-7-14 13:25:29 | 显示全部楼层
深度好帖
回复 支持 反对

使用道具 举报

  离线 

19

主题

92

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
321
金钱
321
注册时间
2014-1-7
在线时间
33 小时
发表于 2016-7-16 15:35:01 | 显示全部楼层
目前我能做到的是把已经初始化的全局变量都放在SRAM,做法是修改散列文件,让RW只在内存SRAM上编译。  你这个全局变量是放在外部的SRAM还是内部的SRAM?
回复 支持 反对

使用道具 举报

  离线 

4

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
60
金钱
60
注册时间
2011-12-2
在线时间
4 小时
发表于 2016-7-17 22:05:27 | 显示全部楼层
正点原子 发表于 2015-3-8 22:18
非常好,cool.
不过这种方法,如果速度要求比较严格,还是少用比较好.
建议自己控制到底用内部还是外部内存.可 ...

这个SystemInit_ExtMemCtl初始化是不是要按照自己的硬件修改啊?原子哥
回复 支持 反对

使用道具 举报

  离线 

10

主题

49

帖子

0

精华

初级会员

Rank: 2

积分
152
金钱
152
注册时间
2016-4-25
在线时间
31 小时
发表于 2016-8-23 14:09:09 | 显示全部楼层
楼主,请教您一个问题就是。
void FSMC_SRAM_ReadBuffer(u8* pBuffer,u32 ReadAddr,u32 n)
{
for(;n!=0;n--)   
{             
*pBuffer++=*(vu8*)(Bank1_SRAM3_ADDR+ReadAddr);     
ReadAddr+=2;//这里需要加2,是因为STM32的FSMC地址右移一位对其.加2相当于加1.
}   
}  
这里的ReadAddr+=2 (同理,WriteAddr+=2;//这里需要加2,是因为STM32的FSMC地址右移一位对其.加2相当于加1.)怎么理解,能给解释一下吗,谢谢
回复 支持 反对

使用道具 举报

  离线 

0

主题

1

帖子

0

精华

新手上路

Rank: 1

积分
7
金钱
7
注册时间
2016-8-23
在线时间
0 小时
发表于 2016-8-23 14:16:45 | 显示全部楼层
我在F407的板子上对着你的方法试了下,LCD屏幕不亮,请问是什么原因呢
回复 支持 反对

使用道具 举报

  离线 

9

主题

91

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2471
金钱
2471
注册时间
2015-1-23
在线时间
24 小时
发表于 2016-11-15 17:29:15 | 显示全部楼层
0x20000000+Stack_Size  可以去掉,
回复 支持 反对

使用道具 举报

  离线 

1

主题

554

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1151
金钱
1151
注册时间
2015-5-28
在线时间
143 小时
发表于 2016-11-29 10:45:15 | 显示全部楼层
顶,收藏了,以后用得到~
回复 支持 反对

使用道具 举报

  离线 

4

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
194
金钱
194
注册时间
2015-5-30
在线时间
65 小时
发表于 2016-11-30 10:34:58 | 显示全部楼层
MARK|||||
回复 支持 反对

使用道具 举报

  离线 

0

主题

1

帖子

0

精华

新手上路

Rank: 1

积分
13
金钱
13
注册时间
2017-5-9
在线时间
2 小时
发表于 2017-5-9 16:38:47 | 显示全部楼层
东周往事 发表于 2016-5-20 16:53
您好,关于您提到的将启动文件中   __initial_sp  改为__initial_sp    EQU     0x20000000 + Stack_Size   ...

您好,最近也在做这个实验,请问,您当时是怎么解决这个问题的?谢谢
回复 支持 反对

使用道具 举报

  离线 

9

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2017-5-9
在线时间
17 小时
发表于 2017-11-21 14:19:46 | 显示全部楼层
jw5387 发表于 2016-4-2 23:20
**** 作者被禁止或删除 内容自动屏蔽 ****

我也想知道,这个方法在407上貌似不好用
回复 支持 反对

使用道具 举报

  离线 

20

主题

144

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1257
金钱
1257
注册时间
2012-8-25
在线时间
296 小时
发表于 2017-11-21 16:13:04 | 显示全部楼层
iar 改好icf文件
#pragma location=".exram"
int  a;

a就到外部去了
回复 支持 反对

使用道具 举报

  离线 

28

主题

206

帖子

0

精华

高级会员

Rank: 4

积分
501
金钱
501
注册时间
2016-8-25
在线时间
45 小时
发表于 2017-12-27 09:20:52 | 显示全部楼层
毛小毛 发表于 2015-7-21 16:38
407+uCOSIII, 之前用的内部SRAM, 在调节任务堆栈的时候发现内存有点不足, 然后通过楼主的方 ...

为什么我按照楼上的方法,试验之后发现黑屏
回复 支持 反对

使用道具 举报

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

本版积分规则




QQ|联系我们|手机版|官方淘宝店|新浪微博|微信公众平台|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2018-1-21 09:07

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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