硬汉嵌入式论坛

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

[SDRAM] 【原创】像使用内部SRAM一样定义使用STM32H7的外部SDRAM,含MDK和IAR两版

  [复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106692
QQ
发表于 2020-7-8 13:53:15 | 显示全部楼层 |阅读模式
V7-058_内部TCM,SRAM和外部SDRAM等六块内存的超方便使用方式.rar (2.71 MB, 下载次数: 674)

支持内部TCM,SRAM,外部SDRAM等六块内存的超方便使用方式



回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106692
QQ
 楼主| 发表于 2020-7-8 13:56:10 | 显示全部楼层
对应教程看此贴章节即可,之前做了内部TCM和几个不同域的SRAM,这次将SDRAM加上。



【安富莱】STM32H7用户手册发布,重在BSP驱动包设计方法,HAL库的框架学习,授人以渔,更新至78章(2020-05-25)
http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980


QQ截图20200708135509.jpg

回复

使用道具 举报

23

主题

1404

回帖

1473

积分

至尊会员

积分
1473
发表于 2020-7-8 17:57:40 | 显示全部楼层
原来关键在zero_init上
代码不规范,亲人两行泪!
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106692
QQ
 楼主| 发表于 2020-7-9 09:12:00 | 显示全部楼层
missfox 发表于 2020-7-8 17:57
原来关键在zero_init上

对,这个地方要注意。
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2020-7-13 15:24:25 | 显示全部楼层
MARK一下,[SDRAM] 像使用内部SRAM一样定义使用STM32H7的外部SDRAM,含MDK和IAR两版
回复

使用道具 举报

609

主题

3049

回帖

4896

积分

至尊会员

积分
4896
发表于 2020-7-13 17:06:44 | 显示全部楼层
如果使用这个方法,能否在函数内部定义使用啊 ?

另外这个方法,能否取代 malloc 功能 ?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106692
QQ
 楼主| 发表于 2020-7-14 09:24:55 | 显示全部楼层
hpdell 发表于 2020-7-13 17:06
如果使用这个方法,能否在函数内部定义使用啊 ?

另外这个方法,能否取代 malloc 功能 ?


这个不能在函数内部。

如果用在函数内部的话,教程的第27章

QQ截图20200714092448.jpg
回复

使用道具 举报

0

主题

30

回帖

30

积分

新手上路

积分
30
发表于 2021-2-3 22:52:51 | 显示全部楼层
硬汉哥,我想问一下,APP程序可以直接加载到外部SDRAM中来运行吗?类似于电脑内存,上电加载APP程序运行,掉电后程序丢失这样的功能,实现APP程序数据的保护,硬汉哥有做过类似的实验吗?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106692
QQ
 楼主| 发表于 2021-2-4 07:40:55 | 显示全部楼层
BruceWang 发表于 2021-2-3 22:52
硬汉哥,我想问一下,APP程序可以直接加载到外部SDRAM中来运行吗?类似于电脑内存,上电加载APP程序运行, ...

F429做过一个例子

STM32F429的程序加载到SDRAM的运行方法
http://www.armbbs.cn/forum.php?m ... 9299&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

0

主题

10

回帖

10

积分

新手上路

积分
10
发表于 2021-2-10 09:18:53 | 显示全部楼层
@eric,这是 ac5 的版本,您能发个 ac6 的来试试吗? 谢谢!
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106692
QQ
 楼主| 发表于 2021-2-10 10:36:36 | 显示全部楼层
syfcoltd 发表于 2021-2-10 09:18
@eric,这是 ac5 的版本,您能发个 ac6 的来试试吗? 谢谢!

ac6的一样,这个方法也可以用于AC6
回复

使用道具 举报

0

主题

10

回帖

10

积分

新手上路

积分
10
发表于 2021-2-10 14:00:55 | 显示全部楼层
eric2013 发表于 2021-2-10 10:36
ac6的一样,这个方法也可以用于AC6

我在V6板子上有使用 AC6 编译是没问题的,但移到 V7 用 AC6 编译后戴入却还没进到 main() 就死在 HardFault_Handler。
所以我参考这个 V7-508 重做一次,目前使用 AC5 是没问题的,但心想没道理,所以想请教您是否我那边没弄好。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106692
QQ
 楼主| 发表于 2021-2-10 18:34:27 | 显示全部楼层
syfcoltd 发表于 2021-2-10 14:00
我在V6板子上有使用 AC6 编译是没问题的,但移到 V7 用 AC6 编译后戴入却还没进到 main() 就死在 HardFau ...

SDRAM那个比较特殊,用于AC6的,这个里面的zero_init不起作用了,被AC6忽略,所以会进硬件异常。
__attribute__((section (".RAM_SDRAM"), zero_init))

AC6上使用你要修改SDRAM的SCT配置为如下,添加.ANY (+ZI)

1.png
回复

使用道具 举报

1

主题

22

回帖

25

积分

新手上路

积分
25
发表于 2021-5-20 17:02:10 | 显示全部楼层
eric2013 发表于 2021-2-10 18:34
SDRAM那个比较特殊,用于AC6的,这个里面的zero_init不起作用了,被AC6忽略,所以会进硬件异常。
__attr ...

硬漢哥 您好,
這邊也發現使用 SCT FILE + SDRAM,
Compiler 要使用AC5 ,
若使用AC6 會開不起來,連RUN(F5) 都是灰化!!? 程序是卡在 HardfaultHandler.
MAIN.C
__attribute__((section (".RAM_SDRAM"),zero_init)) uint16_t SDRAMSRAMCount;
__attribute__((section (".RAM_SDRAM"),zero_init)) uint32_t SDRAMSRAMBuf[10];

SCT 內容:
   RW_IRAM5 0xC0000000 UNINIT 0x02000000  {  ; RW data - 32MB SDRAM (0xC0000000)
   .ANY (+ZI)
   *(.RAM_SDRAM)
   }

還有何處需要改嗎?
回复

使用道具 举报

1

主题

22

回帖

25

积分

新手上路

积分
25
发表于 2021-5-20 17:05:24 | 显示全部楼层
syfcoltd 发表于 2021-2-10 14:00
我在V6板子上有使用 AC6 编译是没问题的,但移到 V7 用 AC6 编译后戴入却还没进到 main() 就死在 HardFau ...

Hello 您好,

這邊測試也是AC5 OK,
AC 6 卡在 Hardfault , 有方案解可分享嗎?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106692
QQ
 楼主| 发表于 2021-5-21 10:29:55 | 显示全部楼层
James2jian 发表于 2021-5-20 17:05
Hello 您好,

這邊測試也是AC5 OK,

使用我发的这个个例子测试下,修改下时钟,适配下你的板子,我这里没问题。
回复

使用道具 举报

1

主题

22

回帖

25

积分

新手上路

积分
25
发表于 2021-5-21 13:51:12 | 显示全部楼层
eric2013 发表于 2021-5-21 10:29
使用我发的这个个例子测试下,修改下时钟,适配下你的板子,我这里没问题。

歸類現況: (RTX5 環境也相同 AC6 編譯會HARDFAULT會HARDFAULT)
AC 5:
__attribute__((section (".RAM_SDRAM"),zero_init)) uint16_t SDRAMSRAMCount;
__attribute__((section (".RAM_SDRAM"),zero_init)) uint32_t SDRAMSRAMBuf[20000];
LR_IROM1 0x08000000 0x00200000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00200000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }

  RW_IRAM2 0x24000000 0x00080000  {  ; RW data
   .ANY (+RW +ZI)
  }
  
  RW_DMARxDscrTab 0x30040000 0x60 {
  *(.RxDecripSection)
  }
  RW_DMATxDscrTab 0x30040060 0x140 {
  *(.TxDecripSection)
  }
  RW_Rx_Buffb 0x30040200 0x1800 {
  *(.RxArraySection)
  }
  
   RW_IRAM5 0xC0000000 UNINIT 0x02000000  {  ; RW data - 32MB SDRAM (0xC0000000)
   ;.ANY (+ZI)  => 該段也不能加,加後會Hardfault: __Main 進不去
   *(.RAM_SDRAM)
  }
}

AC 6:  /*-----------------------------------------------------------------------------------------------*/
__attribute__((section (".RAM_SDRAM"),zero_init)) uint16_t SDRAMSRAMCount;
__attribute__((section (".RAM_SDRAM"),zero_init)) uint32_t SDRAMSRAMBuf[20000];
會告警:
../../User/main.c(76): warning: unknown attribute 'zero_init' ignored [-Wunknown-attributes]
__attribute__((section (".RAM_SDRAM"),zero_init)) uint16_t SDRAMSRAMCount;

SCT:

.... 同上
  RW_IRAM2 0x24000000 0x00080000  {  ; RW data
   .ANY (+RW +ZI)
  }
  
  RW_DMARxDscrTab 0x30040000 0x60 {
  *(.RxDecripSection)
  }
  RW_DMATxDscrTab 0x30040060 0x140 {
  *(.TxDecripSection)
  }
  RW_Rx_Buffb 0x30040200 0x1800 {
  *(.RxArraySection)
  }
  SDRAM SECTION: 我這邊使用V7加入後就Hardfault:
   RW_IRAM5 0xC0000000 UNINIT 0x02000000  {  ; RW data - 32MB SDRAM (0xC0000000)
   ;.ANY (+ZI)  =>  
   *(.RAM_SDRAM)
  }
還是硬漢哥:
可提供你手邊AC6 SDRAM 的編譯的版本呢? 好參考研究,感謝您。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106692
QQ
 楼主| 发表于 2021-5-22 08:11:00 | 显示全部楼层
James2jian 发表于 2021-5-21 13:51
歸類現況: (RTX5 環境也相同 AC6 編譯會HARDFAULT會HARDFAULT)
AC 5:
__attribute__((section (".RAM_S ...

我楼主位的例子,按照13楼的方式修改就可以用。
回复

使用道具 举报

5

主题

61

回帖

76

积分

初级会员

积分
76
发表于 2021-7-15 17:48:30 | 显示全部楼层

定时器中断 启动 HAL_ADC_Start_DMA(&hadc3, ADC3_Value, 6);
配置ADC+DMA
ALIGN_32BYTES(__attribute__((section (".RAM_D3"))) uint32_t ADC3_Value[6]);
我一读取数组ADC3_Value[],数组ADC3_Value就不更新了
硬汉我用SCB_InvalidateDCache_by_Addr((uint32_t *)(&ADC3_Value[0]), 6);  读取到了数据

这个SCB_InvalidateDCache_by_Addr需要注意什么吗?
或者有没有其他方式读取到ADC3_Value里的值
回复

使用道具 举报

12

主题

153

回帖

204

积分

高级会员

积分
204
发表于 2021-7-16 00:42:50 来自手机 | 显示全部楼层
原来论坛里已经分享过这种方法了
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106692
QQ
 楼主| 发表于 2021-7-16 09:08:05 | 显示全部楼层
WZH 发表于 2021-7-16 00:42
原来论坛里已经分享过这种方法了

你分享的也不错
回复

使用道具 举报

0

主题

68

回帖

68

积分

初级会员

积分
68
发表于 2021-8-23 17:24:51 | 显示全部楼层
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106692
QQ
 楼主| 发表于 2021-8-24 08:58:46 | 显示全部楼层
wander 发表于 2021-8-23 17:24
https://developer.arm.com/documentation/ka003046/latest官方有回复了

谢谢,也是好贴。
回复

使用道具 举报

1

主题

10

回帖

13

积分

新手上路

积分
13
发表于 2021-11-20 16:18:34 | 显示全部楼层
AC6的问题,被这个地方卡了好久。终于解决了。
回复

使用道具 举报

1

主题

10

回帖

13

积分

新手上路

积分
13
发表于 2021-11-22 15:30:57 | 显示全部楼层
sct文件中:
  RW_IRAM2 0x24000000 0x00080000  { ;5122kB AXI SRAM
  *(.RAM_D1)
  }
  RW_IRAM3 0x30000000 0x00048000  {; AHB D2域, SRAM1-3 总计288kB
  *(.RAM_D2)
  }
  ;RW_IRAM4 0x38000000 0x00010000  {; AHB D3域 SRAM1-3 总计64kB
  ;*(.RAM_D3)
  ;}
  RW_IRAM4 0xC0000000 UNINIT 0x02000000  {;SDRAM 总计32MB,不能初始化,因为上电之后FMC总线还未初始化。
  *(.RAM_SDRAM)
  }

但根据官方的做法是不行的。
u32 dcmiBuf[2][1000*1000] __attribute__((section(".bss.RAM_SDRAM")));,官方做法,不行的,被分配到其他区的了,未分配到SDRAM区。
u32 dcmiBuf[2][1000*1000] __attribute__((section(".bss.ARM.__at_0xC0000000")));,这个是可以的。且不初始化。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106692
QQ
 楼主| 发表于 2021-11-22 16:17:34 | 显示全部楼层
what 发表于 2021-11-22 15:30
sct文件中:
  RW_IRAM2 0x24000000 0x00080000  { ;5122kB AXI SRAM
  *(.RAM_D1)

.bss.RAM_SDRAM和.RAM_SDRAM是两个东西。
回复

使用道具 举报

7

主题

46

回帖

67

积分

初级会员

积分
67
发表于 2021-12-1 09:33:37 | 显示全部楼层
我的AC6也是不行

RW_SDRAM 0xd0000000 UNINIT 0x02000000  {  ; RW data
        .ANY (+ZI)
        *(.SDRAM)

uint8_t g_sdram_buf1[1024]  __attribute__((section(".SDRAM"))) ;

开机,进入HardFault_Handler。
回复

使用道具 举报

7

主题

46

回帖

67

积分

初级会员

积分
67
发表于 2021-12-1 10:04:04 | 显示全部楼层
RW_SDRAM 0xd0000000 UNINIT 0x02000000  {  ; RW data
        .ANY (+ZI)
        *(.bss.SDRAM)

uint8_t g_sdram_buf1[1024]  __attribute__((section(".bss.SDRAM"))) ;

这种方式也不行
开机,进入HardFault_Handler。
回复

使用道具 举报

7

主题

46

回帖

67

积分

初级会员

积分
67
发表于 2021-12-1 14:46:18 | 显示全部楼层
@硬汉大神,有没有其他的注意事项。
我不调用SDRAM变量,一切都正常了
回复

使用道具 举报

7

主题

46

回帖

67

积分

初级会员

积分
67
发表于 2021-12-1 14:54:21 | 显示全部楼层
@eric2013  大神,有没有其他注意事项了???

卡在这个地方两天了
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106692
QQ
 楼主| 发表于 2021-12-1 15:41:40 | 显示全部楼层
shzdf123 发表于 2021-12-1 14:54
@eric2013  大神,有没有其他注意事项了???

卡在这个地方两天了

分享你的工程到百度云。
回复

使用道具 举报

7

主题

46

回帖

67

积分

初级会员

积分
67
发表于 2021-12-1 16:23:14 | 显示全部楼层
没办法了,我将SDRAM屏蔽,同时,将AXI_SRAM分为两个AXI_SRAM1、AXI_SRAM2,变量也定义到AXI_SRAM2。

        RW_AXI_SRAM1 0x24000000 0x00040000  {  ; RW data
                .ANY (+RW)
        }
        RW_AXI_SRAM2 0x24040000 UNINIT 0x00040000  {  ; RW data
                .ANY (+ZI)
                *(AXI_SRAM2)
        }
__attribute__((section("AXI_SRAM2"))) __attribute__ ((aligned(4))) uint8_t g_sdram_buf1[1024]  ;

测试:烧入程序,哎,正常了,程序停止在main()处。
查看变量地址,也是分配到AXI_SRAM2了。
说明定义方式是OK的。那是不是说程序在main()前就操作sdram了呢?

好吧,恢复SDRAM,将debug中run to main()取消打勾,烧入程序,运行。
SystemInit()正常,__main(),进入硬件异常中断。
__main()好象就是将SCT变量装载到运行地址,是不是这个地方出错了?
这个时候SDRAM还没初始化。。。

好吧,将初始化安排在SystemInit()末尾处,初始化时钟、初始化SDRAM。
运行,OK,一切正常。更新SDRAM中g_sdram_buf1数组数据,一切OK。

感觉我的解决方式和别人不一样。。。心有点虚。。。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106692
QQ
 楼主| 发表于 2021-12-1 16:56:24 | 显示全部楼层
shzdf123 发表于 2021-12-1 16:23
没办法了,我将SDRAM屏蔽,同时,将AXI_SRAM分为两个AXI_SRAM1、AXI_SRAM2,变量也定义到AXI_SRAM2。

        R ...

你是放在了函数SystemInit里面了吧,也可以。
回复

使用道具 举报

7

主题

46

回帖

67

积分

初级会员

积分
67
发表于 2021-12-1 17:17:30 | 显示全部楼层
简单测试了下SDRAM读写速度:
AXI SRAM定到SDRAM,SDRAM读出到SDRAM。
主频400MHz,AXI_SRAM主频200MHz,SDRAM主频100MHz
4字节读写。
写32MB:
        for (i=0; i<0x800000; i++)
        {
                *p++ = 0x32323232;
        }
读32MB:
        for (i=0; i<0x800000; i++)
        {
                g_sdram_temp = *p++;
        }
写时间:105ms,写速度319,566KB/S
读时间:493ms,读速度68,061KB/S

回复

使用道具 举报

7

主题

46

回帖

67

积分

初级会员

积分
67
发表于 2021-12-1 20:47:17 | 显示全部楼层
http://www.armbbs.cn/forum.php?m ... F%E4%BB%A5%E3%80%82
__main()里会用到SDRAM,在这之前SDRAM要初始化,而__main()之前只有SystemInit(),除了SystemInit(),还可以放在哪里?求教
回复

使用道具 举报

7

主题

46

回帖

67

积分

初级会员

积分
67
发表于 2021-12-1 20:58:50 | 显示全部楼层
eric2013 发表于 2021-12-1 16:56
你是放在了函数SystemInit里面了吧,也可以。

我放在main()函数里就报错,只能放在SysInit()。我看你1楼的例程是放在main()里。
理论上,在sct里已经定义了UNINIT,应该不会处理SDRAM里的变量,但我的就是不行。。。
估计,是不是AC6这点有点不同,还是我哪里没有搞清楚
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106692
QQ
 楼主| 发表于 2021-12-2 12:08:53 | 显示全部楼层
shzdf123 发表于 2021-12-1 20:58
我放在main()函数里就报错,只能放在SysInit()。我看你1楼的例程是放在main()里。
理论上,在sct里已经 ...

运行我楼主位例子,原始方式也有错吗

按说不应该啊。
回复

使用道具 举报

7

主题

46

回帖

67

积分

初级会员

积分
67
发表于 2021-12-2 13:47:24 | 显示全部楼层
eric2013 发表于 2021-12-2 12:08
运行我楼主位例子,原始方式也有错吗

按说不应该啊。

我是747,没法运行。不知道是不是747与743的区别
回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2021-12-6 15:09:10 | 显示全部楼层
太感谢了,最近在搞LPC54608的板子,想用它的SDRAM,正需要这个
回复

使用道具 举报

3

主题

7

回帖

16

积分

新手上路

积分
16
发表于 2022-10-26 15:02:33 | 显示全部楼层
GD32F450IG扩展SDRAM
__attribute__((section (".RAM_SDRAM"))) uint16_t Lcd_frameBuff[2][1280*800];
SCT
LR_IROM1 0x08000000 0x00100000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00100000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  
  RW_IRAM1 0x20000000 0x00030000  {  ; RW data - SRAM0(112KB) + SRAM1(16KB) + SRAM2(64KB)= 192KB
   .ANY (+RW +ZI)
  }
  
  RW_IRAM2 0x10000000 0x00010000  {  ; RW data - 64KB DTCM SRAM
  .ANY (+RW +ZI)
  }

  RW_IRAM5 0xC0000000 UNINIT 0x02000000  {  ; RW data - 32MB SDRAM(0xC0000000)
   *(.RAM_SDRAM)
  }
}
AC5和AC6通过。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-30 05:23 , Processed in 0.609046 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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