OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 22249|回复: 38

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

  [复制链接]

58

主题

499

帖子

4

精华

金牌会员

Rank: 6Rank: 6

积分
1920
金钱
1920
注册时间
2013-11-18
在线时间
268 小时
发表于 2015-3-8 20:13:55 | 显示全部楼层 |阅读模式

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

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

[mw_shl_code=c,true]#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL) /* #define DATA_IN_ExtSRAM */ #define DATA_IN_ExtSRAM 1 #endif[/mw_shl_code]

        再编译的时候就会把外部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偶尔正常,偶尔不正常,调试下感觉是延时的问题,没有再继续调试了

已经放下多年的FPGA,要重新再拾起来,却是如此的陌生
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

70

主题

6763

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

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

使用道具 举报

58

主题

499

帖子

4

精华

金牌会员

Rank: 6Rank: 6

积分
1920
金钱
1920
注册时间
2013-11-18
在线时间
268 小时
 楼主| 发表于 2015-3-8 20:36:38 | 显示全部楼层
回复【2楼】jermy_z:
---------------------------------
我没有把FSMC初始化的干掉,我只是没有用原子哥的SRAM的代码了,直接用官方库自带的FSMC初始化,在SystemInit里就初始化外部SRAM,为的是在进去Main之前先初始化SRAM,因为进入Main之前会先初始化堆栈,必须要先初始化外部SRAM
已经放下多年的FPGA,要重新再拾起来,却是如此的陌生
回复 支持 反对

使用道具 举报

70

主题

6763

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

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

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

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

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

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

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

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

使用道具 举报

4

主题

125

帖子

1

精华

高级会员

Rank: 4

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

使用道具 举报

13

主题

31

帖子

0

精华

新手入门

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

使用道具 举报

26

主题

85

帖子

0

精华

中级会员

Rank: 3Rank: 3

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

请问楼主

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

现在的现象是:

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

2.进入不了main函数

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


回复 支持 反对

使用道具 举报

13

主题

34

帖子

0

精华

初级会员

Rank: 2

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

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

回复 支持 反对

使用道具 举报

81

主题

270

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
452
金钱
452
注册时间
2014-8-11
在线时间
87 小时
发表于 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,还是有一个专门的函数,直接调用就可以了呢?
回复 支持 反对

使用道具 举报

172

主题

539

帖子

0

精华

论坛元老

Rank: 8Rank: 8

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

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

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

使用道具 举报

6

主题

91

帖子

0

精华

高级会员

Rank: 4

积分
767
金钱
767
注册时间
2014-11-15
在线时间
91 小时
发表于 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

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

使用道具 举报

19

主题

96

帖子

0

精华

中级会员

Rank: 3Rank: 3

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

使用道具 举报

4

主题

15

帖子

0

精华

初级会员

Rank: 2

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

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

使用道具 举报

11

主题

55

帖子

0

精华

初级会员

Rank: 2

积分
158
金钱
158
注册时间
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

精华

新手入门

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

使用道具 举报

16

主题

147

帖子

0

精华

论坛元老

Rank: 8Rank: 8

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

使用道具 举报

1

主题

561

帖子

0

精华

金牌会员

Rank: 6Rank: 6

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

使用道具 举报

4

主题

11

帖子

0

精华

中级会员

Rank: 3Rank: 3

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

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
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

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

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

使用道具 举报

49

主题

341

帖子

0

精华

论坛元老

Rank: 8Rank: 8

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

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

使用道具 举报

39

主题

234

帖子

0

精华

高级会员

Rank: 4

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

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

使用道具 举报

2

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
87
金钱
87
注册时间
2017-2-26
在线时间
16 小时
发表于 2018-12-5 16:56:13 | 显示全部楼层
u32 testsram[num];数组调大了能用,调小了就不能用了,好奇怪?
回复 支持 反对

使用道具 举报

2

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
87
金钱
87
注册时间
2017-2-26
在线时间
16 小时
发表于 2018-12-5 17:01:44 | 显示全部楼层
又调试了一下,发现当数组定义小了的时候,SP指针不论前面怎么定义他就是指向0x6800 0000+Stack_Size处,这时不能运行。
数组定义大了的时候,sp指向前面定义的0x2000 0000+Stack_Size处,程序就正常运行了。还是奇怪?
回复 支持 反对

使用道具 举报

13

主题

633

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1331
金钱
1331
注册时间
2016-8-1
在线时间
229 小时
发表于 2018-12-5 17:13:48 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

27

主题

427

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
4371
金钱
4371
注册时间
2017-5-30
在线时间
579 小时
发表于 2018-12-7 22:59:29 | 显示全部楼层
探索者F407不能用这个方法诶,有其他人试验过探索者吗?
回复 支持 反对

使用道具 举报

6

主题

36

帖子

1

精华

初级会员

Rank: 2

积分
169
金钱
169
注册时间
2018-12-5
在线时间
4 小时
发表于 2018-12-14 15:10:25 | 显示全部楼层
回复 支持 反对

使用道具 举报

2

主题

70

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
366
金钱
366
注册时间
2019-1-16
在线时间
101 小时
发表于 2019-5-5 16:10:30 | 显示全部楼层
mark!!!
回复 支持 反对

使用道具 举报

60

主题

124

帖子

0

精华

中级会员

Rank: 3Rank: 3

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

你好,我拿了一个例程安装上面的方法,也是硬件错误,是什么原因,请问你解决了吗
回复 支持 反对

使用道具 举报

60

主题

124

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
478
金钱
478
注册时间
2017-11-22
在线时间
136 小时
发表于 2020-2-11 14:06:38 | 显示全部楼层
whj467467274672 发表于 2018-12-7 22:59
探索者F407不能用这个方法诶,有其他人试验过探索者吗?

你好,我的也是探索者,为什么不能用,能说下吗,我改了,然后就运行硬错误
回复 支持 反对

使用道具 举报

60

主题

124

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
478
金钱
478
注册时间
2017-11-22
在线时间
136 小时
发表于 2020-2-11 14:09:16 | 显示全部楼层
cloudshen 发表于 2016-8-23 14:16
**** 作者被禁止或删除 内容自动屏蔽 ****

出现硬错误了,不知道原因
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2019-10-17
在线时间
19 小时
发表于 2020-2-28 17:56:32 | 显示全部楼层
cloudshen 发表于 2016-8-23 14:16
**** 作者被禁止或删除 内容自动屏蔽 ****

请问解决了吗
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-26 06:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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