GD32开发实战指南(基础篇) 第20章 GD32的存储结构

发布者:SparklingRiver最新更新时间:2024-11-04 来源: elecfans关键字:GD32  开发实战  存储结构 手机看文章 扫描二维码
随时随地手机看文章

开发环境:

MDK:Keil 5.30

开发板:GD32F207I-EVAL

MCU:GD32F207IK


1 GD32存储结构的工作原理

1.1 Cortex-M内核的存储器映射

存储器映射是指把芯片中或芯片外的FLASH,RAM,外设,BOOTBLOCK等进行统一编址。即用地址来表示对象。这个地址绝大多数是由厂家规定好的,用户只能用而不能改。用户只能在挂外部RAM或FLASH的情况下可进行自定义。

如下图,是Cortex-M3存储器映射结构图。

1684499765582h595y8083z

Cortex-M3是32位的内核,因此其PC指针可以指向2^32=4G的地址空间,也就是0x0000_0000 - 0xFFFF_FFFF这一大块空间。根据图中描述,Cortex-M3内核将0x0000_0000 - 0xFFFF_FFFF这块4G大小的空间分成8大块:代码、SRAM、外设、外部RAM、外部设备、专用外设总线-内部、专用外设总线-外部、特定厂商等,因此使用该内核的设计者必须按照这个进行各自芯片的存储器结构设计。

1.2 GD32存储器结构

首先,我们对比一下Cortex-M3存储器结构和GD32存储器结构:

C:\\Users\\BruceOu\\Desktop\\11.jpg?imageView2/2/w/1000

图中可以很清晰的看到,GD32的存储器结构和Cortex-M3的很相似,不同的是,GD32加入了很多实际的东西,如:Flash、SRAM等。只有加入了这些东西,才能成为一个拥有实际意义的、可以工作的处理芯片-GD32。

GD32的存储器地址空间被划分为大小相等的8块区域,每块区域大小为512MB。

对GD32存储器知识的掌握,实际上就是对Flash和SRAM这两个区域知识的掌握。


2 FLASH读写数据

2.1 GD32的Flash

GD32的Flash,严格说,应该是Flash模块。该Flash模块包括:Flash主存储区(Main memory)、Flash信息区(Information block),以及Flash存储接口寄存器区(Flash memory interface)。三个组成部分分别在0x0000 0000 - 0xFFFF FFFF不同的区域,GD32F2的Flash结构如下表所示。

1684499766584ucx37erq24

【注】信息块存储了boot loader,不能被用户编程或擦除。

GD32的闪存模块由:主存储闪存块、信息块和选项字节块3部分组成。

主存储器 ,该部分用来存放代码和数据常数(如加const类型的数据)。对于主存储闪存容量不多于512KB的GD32F20x_CL,闪存页大小为2KB。对于主存储闪存容量不少于768KB的GD32F20x_CL,使用了两片闪存;前512KB容量在第一片闪存(bank0)中,后续的容量在第二片闪存(bank1)中。其中bank0的闪存页大小为2KB, bank1的闪存页大小为4KB。主存储闪存的每页都可以单独擦除。

__信息__块,是用来存储GD自带的启动程序,用于串口下载,当B0接3.3V,B1接GND时,运行的就这部分代码,用户选择字节,则一般用于配置保护等功能。

选项字节块 ,该部分用于控制闪存储器读取等,是整个闪存储器的控制机构。

对于主存储器和信息块的写入有内嵌的闪存编程管理;编程与擦除的高压由内部产生。

在执行闪存写操作时,任何对闪存的读操作都会锁定总线,在写完成后才能正确进行,在进行读取或擦除操作时,不能进行代码或者数据的读取操作。

下面对GD32的存储器进行总结。

C:\\Users\\ouxiaolong\\Desktop\\zaszddf.jpg?imageView2/2/w/1000

图中淡蓝色就是你需要知道的。

  • Peripherals:外设的存储器映射,对该区域操作,就是对相应的外设进行操作;

  • SRAM:运行时临时存放代码的地方;

  • Flash:存放代码的地方;

  • System Memory:GD32出厂时自带的你只能使用,不能写或擦除;

  • Option Bytes:可以按照用户的需要进行配置(如配置看门狗为硬件实现还是软件实现);

今后,你的编写代码、程序运行、寄存器设置、ICP、IAP都依靠这些东西。


2.2 FLASH读写实现

GD32F20x 系列产品的片上 Flash 起始地址时 0x0800 0000,最大容量可达 3072 KB。读操作为 0 等待,可支持字节、半字(16 bits)和字(32 bits)访问。 Flash 编程以半字(16 bits)或字(32bits)为单位。擦除可以以页(page)为单位,也可以进行全片擦除(information blocks 除外)。

Flash的寄存器有很多,当时GD的工程师已经封装好了,直接用就可以,我这里就不在贴出来了。

Flash操作很简单,我们将数据写入到Flash中,再将其读出来。主要有以下步骤:

1.Flash解锁操作

2.清除Flash标志

3.页擦除

4.读写操作

5.锁定

核心代码如下:

#define FLASH_ADR 0x0807F800


/**

  * @brief  flash test

  * @param  WriteAddr, InData

  * @retval OutData

  */

uint32_t flash_test(uint32_t WriteAddr, uint32_t InData)

{

    uint32_t OutData = 0;


    //解锁

    fmc_unlock();

    //清除标志位

    fmc_flag_clear(FMC_FLAG_BANK0_PGERR | FMC_FLAG_BANK0_WPERR | FMC_FLAG_BANK0_END | FMC_FLAG_BANK1_PGERR | FMC_FLAG_BANK1_WPERR | 

    FMC_FLAG_BANK1_END);

    //要擦出页的起始地址

    fmc_page_erase(WriteAddr);

    //写数据

    fmc_word_program(WriteAddr, InData);


    //锁定

    fmc_lock();


    OutData=(*(__IO uint32_t*)(WriteAddr));

    return OutData;

}

程序就不讲了,这里需要注意一个C语言的知识点。


OutData=(*(__IO uint32_t*)(WriteAddr));


这一句很多新手很懵逼,也就是从一个地址中读取数据,多看看指针相关的知识就好理解了。

主函数如下:

/*

    brief      main function

    param[in]  none

    param[out] none

    retval     none

*/

int main(void)

{

    uint32_t InData = 12345678;

    uint32_t OutData;


    // systick init

    sysTick_init();


    //usart init 115200 8-N-1

    com_init(COM1, 115200, 0, 1);


    // led1 init

    led_init(LED1);


    printf('InData = %d\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\r\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n',InData);


    // flash test

    OutData= flash_test(FLASH_ADR, InData);


    printf('OutData = %d\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\r\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n',OutData);


    if(OutData == InData)

    {

        printf('Flash test success !\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\r\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n');

    }

    else

    {

        printf('Flash test fail !\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\r\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n');

    }

    while(1)

    {

        led_on(LED1);   // 亮

        delay_ms(1000);

        led_off(LED1);   // 灭 

        delay_ms(1000);

    }

}


2.3 实验结果

将程序边看一完成后下载到板子中,通过串口助手,按下板子的复位按键可以看到如下现象。

168449976724761wuxzkxp2

3 SRAM启动

3.1 GD32的启动模式

首先要回顾一下GD32的启动模式,因为启动模式决定了向量表的位置,GD32有三种启动模式:

1)主闪存存储器(Main Flash)启动:从GD32内置的Flash启动(0x0800 0000-0x0807 FFFF),一般我们使用JTAG或者SWD模式下载程序时,就是下载到这个里面,重启后也直接从这启动程序。以0x08000000 对应的内存为例,则该块内存既可以通过0x00000000 操作也可以通过0x08000000 操作,且都是操作的同一块内存。

2)系统存储器(System Memory)启动:从系统存储器启动(0x1FFFF000 - 0x1FFF F7FF),这种模式启动的程序功能是由厂家设置的。一般来说,我们选用这种启动模式时,是为了从串口下载程序,因为在厂家提供的ISP程序中,提供了串口下载程序的固件,可以通过这个ISP程序将用户程序下载到系统的Flash中。以0x1FFFFFF0对应的内存为例,则该块内存既可以通过0x00000000 操作也可以通过0x1FFFFFF0操作,且都是操作的同一块内存。

3)片上SRAM启动:从内置SRAM启动(0x2000 0000-0x3FFFFFFF),既然是SRAM,自然也就没有程序存储的能力了,这个模式一般用于程序调试。SRAM 只能通过0x20000000进行操作,与上述两者不同。从SRAM 启动时,需要在应用程序初始化代码中重新设置向量表的位置。

用户可以通过设置BOOT0和BOOT1的引脚电平状态,来选择复位后的启动模式。如下图所示:

16844997675999ih3hfv9z9

启动模式只决定程序烧录的位置 ,加载完程序之后会有一个重映射(映射到0x00000000地址位置);真正产生复位信号的时候,CPU还是从开始位置执行。

值得注意的是GD32上电复位以后,代码区都是从0x00000000开始的,三种启动模式只是将各自存储空间的地址映射到0x00000000中。

3.2 GD32的SRAM

不同类型的Cortex-M单片机的SRAM大小是不一样的,但是他们的起始地址都是0x2000 0000,终止地址都是0x2000 0000+其固定的容量大小。

SRAM的理解比较简单,其作用是用来存取各种动态的输入输出数据、中间计算结果以及与外部存储器交换的数据和暂存数据。设备断电后,SRAM中存储的数据就会丢失。

GD32F20x 系列产品的片上 SRAM 起始地址是 0x2000 0000,最大容量可达 384KB,可支持字节、半字(16bits)和字(32bits)访问。 片上 SRAM 被分为 SRAM0、 SRAM1 和 SRAM2 等三个模块,且每个模块都有一个与 AHB 总线矩阵连接的专用接口,这意味着它们可以被同时访问。

模块容量地址范围
SRAM1112KB0x2000 0000 ~
0x2001 BFFF

SRAM216KB0x2001 C000 ~
0x2001 FFFF

SRAM3256KB0x2002 0000 ~
0x2005 FFFF

3.3 片上SRAM启动实现

在使用片上SRAM调试之前,需要了解为何要使用片上SARM来启动程序,因此GD32的片上Flash的擦写次数有限,若超过最大擦除次数则会损坏内部Flash,因此在平时的程序调试阶段,最好使用SRAM启动。

总的来说,SRAM启动程序有如下用途:

1.调试阶段,需要频繁更新程序,可以SRAM启动,加快调试,减少flash擦写损耗

2.程序SWD/JTAG接口已经配置为普通端口,程序启动后无法程序更新,可在SRAM中启动后,再更新flash程序

3.程序已经开启了读保护,可在SRAM启动后,进行读保护关闭

片上SRAM启动实现的方法很简单,这里以GDF207+Keil5举例,实现方法如下:

1.修改内存分配

修改了内存分配,也就是修改分散加载文件xxx.sct文件。

16844997678613pbroii5be

修改后再次生成工程,分散文件也会修改。

1684499768136mcxb3il87a

下面谈谈SRAM参数的分配,首先确定MCU的RAM大小,笔者使用的MCU是GD32F207,因此SRAM大小是256KB,然后还需要根据程序的编译大小来分配SRAM空间。

1684499768519imq0kzsipv

如果想方便点可以直接看MAP文件。

16844997687846pfdozcr9u

FLASH和RAM的大小分别如下:

Flash = Code + RO Data + RW Data = 3.88KB(3968)

RAM = RW-data + ZI-data=8.07KB(8264)

因此笔者这里分配空间如下:

IROM1地址为0x2000 0000, 大小是0x10000=65536=64kB

IRAM1地址为0x2000 3000, 大小是0x20000=131072=128kB

当然啦,SRAM空间分配需要根据自己的 MCU来决定。

2.修改debug配置

新建RAM.ini文件,配置如下:

/*----------------------------------------------------------------------------

 * Name:    RAM.ini

 * Purpose: RAM Debug Initialization File

 * Note(s):

 *----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------

  Setup()  configure PC & SP for RAM Debug

 *----------------------------------------------------------------------------*/

FUNC void Setup (void) {

  SP = _RDWORD(0x20000000);          // Setup Stack Pointer

  PC = _RDWORD(0x20000004);          // Setup Program Counter

  _WDWORD(0xE000ED08, 0x20000000);   // Setup Vector Table Offset Register

}


FUNC void OnResetExec (void)  {      // executes upon software RESET

  Setup();                           // Setup for Running

}


load %L incremental


Setup();                             // Setup for Running


g, main


然后加载进来。

168449976904471crcriy6z

RAM.ini文件主要是初始化SP和PC指针。Cortex-M3复位时会从0x00000000和0x00000004的相对位置取出MSP初值以及将复位向量地址赋给PC,在SRAM中的绝对位置就是0x20000000和0x20000004。GD32F207需要手动配置。

C:\\Users\\BruceOu\\Desktop\\1.png?imageView2/2/w/1000

3.修改下载配置

需要把程序下载到SRAM,修改相应的下载地址。

1684499769605bhv2p1ahoz

4.修改中断向量表指针

由启动文件可知,程序启动首先执行Reset_Handler函数,SRAM启动硬件强制将PC指针赋值为0x200001E0,PC指针加1开始执行启动文件,故Reset_Handler函数的运行地址需为0x200001E1才行,否则程序就会跑飞。

因此需要在中断向量表的末尾添加SPACE 0x96。

1684499769910zngknxcfmo

同时在在main函数中添加设置中断向量表以及系统初化函数。

nvic_vector_table_set(NVIC_VECTTAB_RAM,0x00);

SystemInit();

5.修改启动模式

这里选择SRAM启动,因此BOOT0->1 BOOT1->1。

最后编译下载程序,然后就可以运行程序了。

1684499770201dea23o8tko


关键字:GD32  开发实战  存储结构 引用地址:GD32开发实战指南(基础篇) 第20章 GD32的存储结构

上一篇:GD32 ADC内部通道采样异常原因
下一篇:【GD32 MCU 入门教程】GD32 MCU 常见外设介绍 (6) ADC 模块介绍

推荐阅读最新更新时间:2026-03-25 10:37

GD32开发实战指南(基础篇) 第18章 CRC校验
开发环境: MDK:Keil 5.30 开发板:GD32F207I-EVAL MCU:GD32F207IK 1 CRC的校验原理 __循环冗余校验(CRC)计算单元是根据固定的生成多项式得到任一32位全字的CRC计算结果。__在其他的应用中, CRC技术主要应用于核实数据传输或者数据存储的正确性和完整性。标准EN/IEC 60335-1即提供了一种核实闪存存储器完整性的方法。 CRC计算单元可以在程序运行时计算出软件的标识,之后与在连接时生成的参考标识比较,然后存放在指定的存储器空间。那么首先来看看CRC校验原理。 1.1基本原理 CRC检验原理实际上就是在一个p位二进制数据序列之后附加一个r位二进制检验码(序列),从而构
[单片机]
GD32开发实战指南(基础篇) 第9章 呼吸灯
开发环境: MDK:Keil 5.30 开发板:GD32F207I-EVAL MCU:GD32F207IK 1 呼吸灯的工作原理 呼吸灯,就是指灯光设备的亮度随着时间由暗到亮逐渐增强,再由亮到暗逐渐衰减,很有节奏感地一起一伏,就像是在呼吸一样,因而被广泛应用于手机、电脑等电子设备的指示灯中。 要使用数字器件控制灯光的强弱,我们很自然就想到 PWM(脉冲宽度调制)技术。假如以LED 作为灯光设备,且由控制器输出的 PWM 信号可以直接驱动 LED,PWM 信号中的低电平可点亮 LED 灯。当 LED 以较高的频率进行开关(亮灭)切换时,由于视觉暂留效应,人眼是看不到 LED 灯的闪烁现象的,反映到人眼中能感觉到的
[单片机]
GD32开发实战指南(基础篇) 第1章 开发环境搭建
开发环境: MDK:Keil 5.30 开发板:GD32F207I-EVAL MCU:GD32F207IK 1 GD32F207I-EVAL开发板简介 笔者使用的开发板是兆易创新设计的GD32F207I-EVAL开发板。 GD32F207I-EVAL开发板使用 GD32F207IK作为主控制器,主频120MHz、集成3MB Flash、256KB SRAM、通用定时器10、Adv. TM2、Basic TM2、系统时钟1、看门狗2、RTC1、USART4、UART4、I2C3、SPI3、I2S1、SDIO1、CAN2.0B2、USB2.0 OTG FS1、以太网MAC1、TFT-LCD16、数字摄像头接口1、Crypro/
[单片机]
GD32开发实战指南(基础篇) 第4章 GD32启动流程详解(Keil版)
开发环境: MDK:Keil 5.30 开发板:GD32F207I-EVAL MCU:GD32F207IK 对于我们常用的桌面操作系统而言,我们在开发应用时,并不关心系统的初始化,绝大多数应用程序是在操作系统运行后才开始运行的,操作系统已经提供了一个合适的运行环境,然而对于嵌入式设备而言,在设备上电后,所有的一切都需要由开发者来设置,这里处理器是没有堆栈,没有中断,更没有外围设备,这些工作是需要软件来指定的,而且不同的CPU类型、不同大小的内存和不同种类的外设,其初始化工作都是不同的。本文将以GD32F207IK (基于Cortex-M3)为例进行讲解。 在开始正式讲解之前,你需要了解ARM寄存器、汇编以及反编译相关的知识
[单片机]
汽车ECU微控制器存储器层次结构解析
当你翻开ECU的微控制器的用户手册,比如英飞凌Aurix TC29x系列为例,如下所示: 我们可以看到并非只有常见的RAM和ROM,如果你是新手,那么这些看起来都不认识,搞不清谁属于RAM,谁又属于ROM,本文就试图来搞清这点。 在微控制器(MCU)和计算机系统中,存储器(Memory)按功能、速度和用途可以分为多种类型。上图中提到的术语都是嵌入式系统中常见的存储器类型,我们可以先从 RAM(随机存取存储器) 和 ROM(只读存储器) 两个大类入手,逐步深入解析。 01 ROM 类存储器 (非易失性)——PMU 在汽车电子领域,微控制器不仅需要强大的算力,更需
[汽车电子]
浅谈存储器体系结构的未来发展趋势
  对存储器带宽的追求成为系统设计最突出的主题。SoC设计人员无论是使用ASIC还是FPGA技术,其思考的核心都是必须规划、设计并实现存储器。系统设计人员必须清楚的理解存储器数据流模式,以及芯片设计人员建立的端口。即使是存储器供应商也面临DDR的退出,要理解系统行为,以便找到持续发展的新方法。   曾经在斯坦福大学举办的热点芯片大会上,寻求带宽成为论文讨论的主题,设计人员介绍了很多方法来解决所面临的挑战。从这些文章中,以及从现场工作的设计人员的经验中,可以大概看出存储器系统体系结构今后会怎样发展。   存储器壁垒   基本问题很明显:现代SoC时钟频率高达吉赫兹,并且具有多个内核,与单通道DDR DRAM相比,每秒会发出更
[嵌入式]
浅谈<font color='red'>存储</font>器体系<font color='red'>结构</font>的未来发展趋势
STC8G系列存储结构
STC8G 系列单片机的程序存储器【RAM】和数据存储器【 Flash 类型的程序储存器ROM】是各自独立编址的。 备注:也就是他们的地址开始都是从0开始。但是对应不同的实体【区别与STM32统一编址的哈佛结构】 由于没有提供访问外部程序存储器的总线,单片机的所有程序存储器都是片上 Flash 存储器,不能访问外部程序存储器。 STC8G 系列单片机内部集成了大容量的数据存储器。STC8G 系列单片机内部的数据存储器在物理和逻辑上都分为两个地址空间:内部 RAM(256 字节)和内部扩展 RAM。其中内部 RAM 的高 128 字节的 数据存储器与特殊功能寄存器(SFRs)地址重叠,实际使用时通过不同的寻址方式加以区分。
[单片机]
PCIe®结构和RAID如何在GPUDirect存储中释放全部潜能
PCIe®结构和RAID如何在GPUDirect存储中释放全部潜能 随着更快的图形处理单元(GPU)能够提供明显更高的计算能力,存储设备和GPU存储器之间的数据路径瓶颈已经无法实现最佳应用程序性能。NVIDIA的Magnum IO GPUDirect存储解决方案通过在存储设备和GPU存储器之间实现直接路径,可以极大地帮助解决该问题。然而,同等重要的是要使用容错系统来优化其已经非常出色的能力,从而确保在发生灾难性故障时备份关键数据。该解决方案通过PCIe®结构连接逻辑RAID卷,在PCIe 4.0规范下,这可以将数据速率提高到26 GB/s。为了解如何实现这些优势,首先需要检查该解决方案的关键组件及其如何协同工作来提供结果。
[嵌入式]
PCIe®<font color='red'>结构</font>和RAID如何在GPUDirect<font color='red'>存储</font>中释放全部潜能
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved