GD32F4的ram分区的坑

GD32F4的片上RAM坑

1. 问题描述

在GD32F450VK上移植rtthread的时候,当执行到下面函数的时候

rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);

会进入context_rvds.S文件下HardFault_Handler中断,然后出错,如下:
在这里插入图片描述

HardFault_Handler中断一般跟内存相关,往往错误都是内存访问越界、内存不可操作或操作失败。

2. rtthread的rt_system_heap_init作用

我查看了一下关于HEAP_BEGIN和HEAP_END的配置,发现没什么问题。

#define GD32_SRAM_SIZE         256
#define GD32_SRAM_END          (0x20000000 + GD32_SRAM_SIZE * 1024)

#ifdef __CC_ARM
extern int Image$$RW_IRAM1$$ZI$$Limit;
#define HEAP_BEGIN    (&Image$$RW_IRAM1$$ZI$$Limit)
#elif __ICCARM__

#define HEAP_END          GD32_SRAM_END

rt_system_heap_init函数主要是为malloc相关函数预先指定可用空间的函数。

HEAP_BEGIN指向的是程序运行所需要的RAM空间的尾地址,HEAP_END指向整个RAM空间的尾地址,这样整个RAM空间就被分成了两部分,前边部分是程序运行所需要的RAM空间,后部分是RAM剩余的部分作为预先为malloc准备的空间,具体如下:
在这里插入图片描述

对于GD32F450VK来讲,RAM起始地址是0x20000000,空间大小是256k,(&Image$ $ RW_IRAM1$ $ ZI $ $Limit)是keil获取程序运行所需RAM空间结束地址的方式,所以上面的设计应该没有什么问题。

3. 找到问题

后来查找数据手册,最后发现这256k是分成好几块的,每一块描述如下:

GD32F4xx系列微控制器含有高达256KB片上SRAM、4KB备份SRAM和512KB附加SRAM,所有的SRAM均支持字节、半字(16比特)和整字(32比特)访问。

片上SRAM可分为4块,分别为SRAM0(112KB)、SRAM1(16KB)、SRAM2(64KB)和TCMSRAM(64KB)。SRAM0、SRAM1和SRAM2可以被所有的AHB主机访问,然而,TCMSRAM(紧耦合存储器SRAM)只可被Cortex ® -M4内核的数据总线访问。BKPSRAM(备份SRAM)应用于备份域,即使当VDD供电电源掉电时,该SRAM仍可保持其内容。附加SRAM(ADDSRAM)只在一些特殊的GD32F4xx器件中可用。由于采用AHB互联矩阵,上述SRAM块可以同时被不同的AHB主机访问,例如,即使CPU正在访问SRAM0,USBHS也可以访问SRAM1。

对应空间地址如下:
在这里插入图片描述

在这里插入图片描述

这个ADDSRAM对于256k及以下的RAM是没有的,我们发现256k被分成了好几部分,而且地址上还不是连续的,因此这256k不能连续分配,这样我们的GD32_SRAM_SIZE就不能为256了,最后修改如下:


//sram 
#define GD32_SRAM0_SIZE				 112
#define GD32_SRAM1_SIZE				 16
#define GD32_SRAM2_SIZE				 64
#define GD32_TCMSRAM_SIZE			 64

#define GD32_SRAM_SIZE         (GD32_SRAM0_SIZE + GD32_SRAM1_SIZE + GD32_SRAM2_SIZE)   //192
#define GD32_SRAM_END          (0x20000000 + GD32_SRAM_SIZE * 1024)

4. 其它

上面的设计会发现一个问题那就是TCMSRAM无法得到使用。那是因为TCMSRAM(紧耦合存储器SRAM)只可被Cortex ® -M4内核的数据总线访问。

解决这个问题的方法,可以通过修改连接脚本来设置程序运行的RAM空间,指定到TCMSRAM就可以了,这个实现我会在后面来分享。

猜你喜欢

转载自blog.csdn.net/Zhichao_Zhang/article/details/127277915