一篇文章看懂stm32的FLASH,RAM(SRAM),寻址空间

avatar
作者
猴君
阅读量:0

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:本文介绍stm32的FLASH,RAM,以及为什么说stm32有4G的寻址空间,我们先来看一下stm32的寻址空间,具体的储存空间结构;

STM32F103 的寻址空间

以STM32F103为例,它的内存映射如下:

  • 0x0000 0000 - 0x1FFF FFFF:代码区域,包括主Flash存储器和系统存储器。
  • 0x2000 0000 - 0x3FFF FFFF:SRAM区域。
  • 0x4000 0000 - 0x5FFF FFFF:外设区域,包括各种外设寄存器。
  • 0x6000 0000 - 0x9FFF FFFF:外部存储器区域。
  • 0xA000 0000 - 0xDFFF FFFF:外设寄存器别名。
  • 0xE000 0000 - 0xFFFF FFFF:系统控制空间,包括核心外设寄存器(如NVIC、SysTick等)。

STM32F407 的寻址空间

STM32F407的内存映射和STM32F103类似,但其Flash和SRAM容量较大:

  • 0x0000 0000 - 0x1FFF FFFF:代码区域,包括主Flash存储器和系统存储器。
  • 0x2000 0000 - 0x3FFF FFFF:SRAM区域。
  • 0x4000 0000 - 0x5FFF FFFF:外设区域,包括各种外设寄存器。
  • 0x6000 0000 - 0x9FFF FFFF:外部存储器区域。
  • 0xA000 0000 - 0xDFFF FFFF:外设寄存器别名。
  • 0xE000 0000 - 0xFFFF FFFF:系统控制空间,包括核心外设寄存器(如NVIC、SysTick等)。

内存映射示意图

STM32F103
+----------------------+-----------+ | Address Range        | Description| +----------------------+-----------+ | 0x0000 0000 - 0x0800 0000 | Main Flash Memory | | 0x1FFF F000 - 0x1FFF F7FF | System Memory (Bootloader) | | 0x2000 0000 - 0x2000 5000 | SRAM | | 0x4000 0000 - 0x5006 3FFF | Peripheral Registers | | 0x6000 0000 - 0x9FFF FFFF | External Memory | | 0xE000 0000 - 0xE00F FFFF | Core Peripheral Registers | +----------------------+-----------+ 
STM32F407
+----------------------+-----------+ | Address Range        | Description| +----------------------+-----------+ | 0x0000 0000 - 0x0800 0000 | Main Flash Memory | | 0x1FFF 0000 - 0x1FFF 77FF | System Memory (Bootloader) | | 0x2000 0000 - 0x2001 BFFF | SRAM1 | | 0x2001 C000 - 0x2001 FFFF | SRAM2 | | 0x4000 0000 - 0x5006 3FFF | Peripheral Registers | | 0x6000 0000 - 0x9FFF FFFF | External Memory | | 0xE000 0000 - 0xE00F FFFF | Core Peripheral Registers | +----------------------+-----------+ 

内存类型

  1. Flash Memory:用于存储程序代码和常量数据。STM32F103通常有64KB到128KB的Flash,而STM32F407通常有256KB到1MB的Flash。
  2. SRAM:用于存储运行时数据,如变量和堆栈。STM32F103通常有20KB的SRAM,而STM32F407有192KB的SRAM1和64KB的SRAM2。
  3. 外设寄存器:用于控制和配置各种外设,如GPIO、USART、I2C等。
  4. 系统控制空间:包括核心外设,如SysTick计时器和NVIC(嵌套向量中断控制器)。

一、FLASH

它主要用于存储代码,FLASH 存储器的内容在掉电后不会丢失,STM32 芯片在运行的时候,也能对自身的内部 FLASH 进行读写,因此,若内部 FLASH 存储了应用程序后还有剩余的空间,我们可以把它像外部 SPI-FLASH 那样利用起来,存储一些程序运行时产生的需要掉电保存的数据。并且访问内部 FLASH 的速度要比外部的 SPI-FLASH 快得多。

  • 类型:非易失性存储器
  • 用途:主要用于存储程序代码和常量数据
  • 特点
    • 非易失性:即使在断电后数据也不会丢失。
    • 读写速度:读取速度较快,但写入速度较慢,并且写入次数有限(通常为1万到10万次)。
    • 容量:容量较大,适合存储程序代码。
应用
  • 在STM32微控制器上,编写的固件程序通常存储在FLASH中。启动时,微控制器从FLASH中读取程序并执行。
  • (1)主存储器
        一般我们说 STM32 内部 FLASH 的时候,都是指这个主存储器区域,它是存储用户应用程序的空间,芯片型号说明中的 1M FLASH、 2M FLASH 都是指这个区域的大小。
        主存储器分为两块,共 2MB,每块内分 12 个扇区,其中包含 4 个 16KB扇区、 1 个 64KB 扇区和 7 个 128KB 的扇区。如STM32F429IGT6 型号芯片,它的主存储区域大小为 1MB,所以它只包含有表中的扇区 0-扇区 11。
        与其它 FLASH 一样,在写入数据前,要先按扇区擦除,而有的时候我们希望能以小规格操纵存储单元,所以 STM32 针对 1MB FLASH 的产品还提供了一种双块的存储格式,见下表:

    通过配置 FLASH 选项控制寄存器 FLASH_OPTCR 的 DB1M 位,可以切换这两种格式,切换成双块模式后,扇区 8-11 的空间被转移到扇区 12-19 中,扇区细分了,总容量不变。
        
        注意如果您使用的是 STM32F40x 系列的芯片, 它没有双块存储格式,也不存在扇区 12-23,仅 STM32F42x/43x 系列产品才支持扇区 12-23。
        
      (2)系统存储区
        系统存储区是用户不能访问的区域,它在芯片出厂时已经固化了启动代码,它负责实现串口、 USB 以及 CAN 等 ISP 烧录功能。
        
      (3)OTP 区域
        OTP(One Time Program),指的是只能写入一次的存储区域,容量为 512 字节,写入后数据就无法再更改, OTP 常用于存储应用程序的加密密钥。
        
      (4)选项字节
        选项字节用于配置 FLASH 的读写保护、电源管理中的 BOR 级别、软件/硬件看门狗等功能,这部分共 32 字节。可以通过修改 FLASH 的选项控制寄存器修改。

    三、注意事项
    32位的M3有4GB的寻址空间,STM32的存储器地址映射,地址范围为:0x0000_0000-0xFFFF_FFFF;其中代码区的地址是从0x0800_0000开始的,结束于0x0800_0000+芯片的Flash的大小;

    所以就必须在MDK里设置Flash地址为0x0800 0000,
    这样就还有一个问题,理论上,CM3中规定上电后CPU是从0地址开始执行,但是这里中断向量表却被烧写在0x0800 0000地址里,那启动时不就找不到中断向量表了?既然CM3定下的规矩是从0地址启动,SMT32当然不能破坏ARM定下的“规矩”,所以它做了一个启动映射的过程,就是和芯片上总能见到的BOOT0和BOOT1有关了,当选择从主Flash启动模式后,芯片一上电,Flash的0x0800 0000地址被映射到0地址处,不影响CM3内核的读取,所以这时的CM3既可以在0地址处访问中断向量表,也可以在0x0800 0000地址处访问中断向量表,而代码还是在0x0800 0000地址处存储的。这就是最难理解的地方,其实,这是基本上所有ARM芯片采用的启动映射方法。ARM7,ARM9没有内部Flash的通常都是这样做的。这个过程出自STM32 referenc manual手册,里面是有说明的。
    值得注意的是 ,这个中断向量表是可以在程序中再次被映射的。控制它的就是CM3已经规定的NVIC寄存器SCB->VTOR。在STM32库中给出的启动代码里,startup_stm32f10x_hd.s文件里,第146行,是上电后读取中断向量表中的复位中断位置,并执行复位中断处理代码,代码如下:

    ; Reset handler Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT __main IMPORT SystemInit LDR R0, =SystemInit BLX R0 LDR R0, =__main BX R0 ENDP



    注意复位后第一个被执行的是SystemInit代码,这个代码在库目录下的system_stm32f10x.c文件里,它初始化了时钟,NVIC等一系列操作,这里摘要与中断向量有关的代码:

    void SystemInit (void)  {  #ifdef VECT_TAB_SRAM SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. / #else SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; / Vector Table Relocation in Internal FLASH. */ #endif }



    可以看出中断向量重映射是一个选择性编译,通常宏定义VECT_TAB_SRAM都没有被定义,所以这里执行结束后,SCB->VTOR就是FLASH_BASE了,值为0x0800 0000。以后CM3再取中断向量里,就会根据SCB->VTOR的设置,从这里取向量执行了。中断向量自此终于转正。

二、RAM

RAM(Random Access Memory) :掉电之后就丢失数据,读写速度块
ROM (Read Only Memory) :掉电之后仍然可以保持数据

  • 类型:静态随机存储器,是一种RAM
  • 用途:在STM32中,SRAM一般与RAM指的是同一种存储器,用于存储运行时的数据。
  • 特点
    • 易失性:断电后数据会丢失。
    • 读写速度:速度快。
    • 结构:采用触发器存储单元,不需要定期刷新,功耗低。
应用
  • 在STM32微控制器中,SRAM通常用作系统运行时的工作内存。
  • #include "stm32f1xx.h"  // 全局变量,存储在SRAM中 int global_var = 0;  // 常量数据,存储在FLASH中 const char flash_data[] = "Hello, FLASH!";  int main(void) {     // 本地变量,存储在SRAM中     int local_var = 0;          // 使用全局变量     global_var = 10;          // 使用本地变量     local_var = global_var + 1;          // 使用FLASH中的数据     printf("%s\n", flash_data);          while (1) {         // 主循环     } } 


寻址空间

在STM32微控制器中,寻址空间(Address Space)指的是微控制器能够访问的内存地址范围。每个存储器单元(如RAM、ROM、寄存器等)都有一个唯一的地址,CPU通过这些地址来访问和操作存储器单元。STM32微控制器的寻址空间通常由其内存映射(Memory Map)定义。

寻址空间的基本概念

  1. 地址宽度:STM32微控制器使用32位地址总线,这意味着它能够访问的地址范围是4GB(2^32个地址)。
  2. 内存映射:STM32的内存映射定义了不同类型的存储器(如Flash、SRAM、外设寄存器等)在整个地址空间中的位置。

STM32F103 的寻址空间

以STM32F103为例,它的内存映射如下:

  • 0x0000 0000 - 0x1FFF FFFF:代码区域,包括主Flash存储器和系统存储器。
  • 0x2000 0000 - 0x3FFF FFFF:SRAM区域。
  • 0x4000 0000 - 0x5FFF FFFF:外设区域,包括各种外设寄存器。
  • 0x6000 0000 - 0x9FFF FFFF:外部存储器区域。
  • 0xA000 0000 - 0xDFFF FFFF:外设寄存器别名。
  • 0xE000 0000 - 0xFFFF FFFF:系统控制空间,包括核心外设寄存器(如NVIC、SysTick等)。

STM32F407 的寻址空间

STM32F407的内存映射和STM32F103类似,但其Flash和SRAM容量较大:

  • 0x0000 0000 - 0x1FFF FFFF:代码区域,包括主Flash存储器和系统存储器。
  • 0x2000 0000 - 0x3FFF FFFF:SRAM区域。
  • 0x4000 0000 - 0x5FFF FFFF:外设区域,包括各种外设寄存器。
  • 0x6000 0000 - 0x9FFF FFFF:外部存储器区域。
  • 0xA000 0000 - 0xDFFF FFFF:外设寄存器别名。
  • 0xE000 0000 - 0xFFFF FFFF:系统控制空间,包括核心外设寄存器(如NVIC、SysTick等)。

内存映射示意图

STM32F103
+----------------------+-----------+ | Address Range        | Description| +----------------------+-----------+ | 0x0000 0000 - 0x0800 0000 | Main Flash Memory | | 0x1FFF F000 - 0x1FFF F7FF | System Memory (Bootloader) | | 0x2000 0000 - 0x2000 5000 | SRAM | | 0x4000 0000 - 0x5006 3FFF | Peripheral Registers | | 0x6000 0000 - 0x9FFF FFFF | External Memory | | 0xE000 0000 - 0xE00F FFFF | Core Peripheral Registers | +----------------------+-----------+ 
STM32F407
+----------------------+-----------+ | Address Range        | Description| +----------------------+-----------+ | 0x0000 0000 - 0x0800 0000 | Main Flash Memory | | 0x1FFF 0000 - 0x1FFF 77FF | System Memory (Bootloader) | | 0x2000 0000 - 0x2001 BFFF | SRAM1 | | 0x2001 C000 - 0x2001 FFFF | SRAM2 | | 0x4000 0000 - 0x5006 3FFF | Peripheral Registers | | 0x6000 0000 - 0x9FFF FFFF | External Memory | | 0xE000 0000 - 0xE00F FFFF | Core Peripheral Registers | +----------------------+-----------+ 

内存类型

  1. Flash Memory:用于存储程序代码和常量数据。STM32F103通常有64KB到128KB的Flash,而STM32F407通常有256KB到1MB的Flash。
  2. SRAM:用于存储运行时数据,如变量和堆栈。STM32F103通常有20KB的SRAM,而STM32F407有192KB的SRAM1和64KB的SRAM2。
  3. 外设寄存器:用于控制和配置各种外设,如GPIO、USART、I2C等。
  4. 系统控制空间:包括核心外设,如SysTick计时器和NVIC(嵌套向量中断控制器)。

STM32F4系列微控制器的寻址空间被认为是4GB的原因主要在于其32位的地址总线。以下是详细的解释:

1. 32位地址总线

STM32F4微控制器使用32位的地址总线,这意味着它可以生成和使用32位的地址。这些地址表示的范围是从0x00000000到0xFFFFFFFF,总共有2^32个地址,即4,294,967,296个地址。

2. 地址空间的大小

每个地址通常对应1个字节的存储空间,因此总的寻址空间为:

232 字节=4,294,967,296 字节=4 GB232字节=4,294,967,296字节=4GB

3. 内存映射(Memory Map)

虽然STM32F4有一个4GB的寻址空间,但实际使用中,并不是所有的空间都分配给RAM或Flash存储器。STM32F4的内存映射将不同的地址范围分配给不同的用途,包括内部存储器、外设、系统控制空间等。以下是STM32F407内存映射的一部分示例:

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!