STM32中的Flash、ROM与RAM全解析

目录

[1. flash、ROM、RAM](#1. flash、ROM、RAM)

[RAM(Random Access Memory)](#RAM(Random Access Memory))

[ROM(Read-Only Memory)](#ROM(Read-Only Memory))

[FLASH(FLASH EEPROM)](#FLASH(FLASH EEPROM))

[2. 在stm32中,.text段、.data段和.bss段都在哪里?flash上?还是SRAM?](#2. 在stm32中,.text段、.data段和.bss段都在哪里?flash上?还是SRAM?)

[1. .text 段 (代码段)](#1. .text 段 (代码段))

[2. .data 段 (已初始化数据段)](#2. .data 段 (已初始化数据段))

[3. .bss 段 (未初始化或初始化为0的数据段)](#3. .bss 段 (未初始化或初始化为0的数据段))

总结与类比

STM32启动流程回顾

如何查看?


1. flash、ROM、RAM

在计算机硬件中,RAM (随机存取存储器)和ROM(只读存储器)是两种基本的存储技术,它们在数据存储和处理方面有着根本的区别。

RAM Random Access Memory

RAM是计算机的主存储器,用于临时存储正在运行的程序和数据。它允许数据被随机访问,意味着可以直接读取或写入任何位置的数据,而不需要按顺序进行。RAM的特点包括:

  • 易失性:当电源关闭时,存储在RAM中的数据会丢失。

  • 快速读写:RAM可以快速地读取和写入数据,这对于计算机运行程序和处理任务是非常重要的。

  • 容量和速度:RAM的容量通常从几MB到数百GB不等,速度非常快,能够通过高速总线迅速访问数据。

常见的RAM类型包括DRAM (动态随机存取存储器)、SRAM (静态随机存取存储器)、SDRAM (同步动态随机存取存储器)和DDR SDRAM(双倍数据率同步动态随机存取存储器)。

ROM (Read-Only Memory)

ROM是一种只读存储器,通常用于存储固定的程序指令和数据,如启动程序和固件。ROM的特点包括:

  • 非易失性:即使在断电的情况下,ROM中的数据也不会丢失。

  • 只读 :ROM中的数据通常在制造过程中预先写入,用户无法修改。

FLASH(FLASH EEPROM)

  • Flash 存储器(FLASH EEPROM)又称闪存,快闪。它是EEPROM的一种。它结合了ROM和RAM的长处。不仅具备电子可擦除可编辑(EEPROM)的性能,还不会断电丢失数据同时可以快速读取数据。它于EEPROM的最大区别是,FLASH按扇区(block)操作,而EEPROM按照字节操作。FLASH的电路结构较简单,同样容量占芯片面积较小,成本自然比EEPROM低,因此适合用于做程序存储器。

  • FLASH 可以说就是 ROM 的子集。

我们再来看看STM32中flash、ROM、RAM三者的关系:

堆、栈、flash、ROM、RAM、bss段、data段、text段、Code、Ro-data ZI-data、RW-data的区别_栈是在flash-CSDN博客

综合上述种种,我们可以总结出:在STM32中,flash 就是 ROM ,而STM32中的 RAM ,就是 SRAM

2. 在stm32中,.text段、.data段和.bss段都在哪里?flash上?还是SRAM?

简单直接的答案是:这些段同时存在于Flash和 SRAM 中,但它们的"存在"方式不同。

更准确的说法是:

  • 编译和链接后,所有段的原始数据都存储在Flash中。

  • 程序运行时.text段仍在Flash中被CPU读取执行,而.data.bss段则位于SRAM中。

下面我们来详细分解每一个段,并解释STM32的启动过程是如何实现这一点的。


1. .text 段 (代码段)

  • 内容 :存放程序的执行代码(机器指令)、常量字符串以及只读的常量数据(例如被const关键字修饰的全局变量)。

  • 位置

    • Flash ( ROM ) :这是.text段的永久存储位置。单片机掉电后,代码不会丢失。

    • SRAM:.text段通常不复制到SRAM。CPU通过称为I-Bus (Instruction Bus) 的系统总线直接从Flash中读取指令并执行。这样做是为了节省宝贵的SRAM空间。

结论: .text段始终在Flash中,运行时也从Flash直接读取。


2. .data 段 (已初始化数据段)

  • 内容:存放已初始化且初始值不为零的全局变量和静态变量(static)。

    • 例如:int global_var = 100;static int static_var = 5;
  • 位置

    • Flash ( ROM ) :存储这些变量的初始值(例如1005)。这些值是程序映像的一部分,掉电不丢失。

    • SRAM:这是这些变量运行时真正被存放和操作的地方。

关键过程:启动时的"数据拷贝"

单片机启动时,一段特殊的启动代码(通常是Startup文件中的代码,会调用__main,其中包含拷贝操作)会自动将.data段在Flash中的初始值复制到SRAM中为其分配好的地址空间。之后,程序的所有读写操作都是针对SRAM中的副本。


3. .bss 段 (未初始化或初始化为0的数据段)

  • 内容:存放未初始化或初始化为0的全局变量和静态变量。

    • 例如:int uninit_var; static int static_zero_var = 0; int big_array[1024] = {0};
  • 位置

    • Flash ( ROM ):.bss段在Flash中不占用存储变量的空间,它只占用了"描述信息"(记录了这块内存的起始地址和大小)。没有必要开空间,这会浪费Flash空间。

    • SRAM:这是.bss变量运行时存在的地方。系统在启动时需要在SRAM中为它们分配空间。

关键过程:启动时的" 内存 清零"

启动代码在执行完.data段的拷贝后,会紧接着对.bss段对应的SRAM区域进行清零初始化。这就是为什么你没有给全局变量赋值,它默认是0的原因。


总结与类比

  • Flash ( ROM ) 就像是你的硬盘。它存储了所有的"原始材料":

    • 程序指令(.text

    • 已初始化变量的初始值(.data的初始值)

    • .bss段的大小信息(一个"需要准备多少空位"的清单)

  • SRAM 就像是你的电脑内存。程序运行时:

    • CPU从Flash(硬盘)读取指令(.text)来执行。

    • 把已初始化变量的值(.data)从Flash(硬盘)加载到SRAM(内存)中操作。

    • 在SRAM(内存)中为未初始化变量(.bss)开辟一片空间并清零。

STM32启动流程回顾

  1. 上电或复位后,CPU从Flash的复位中断向量表找到复位处理函数的地址,并开始执行启动代码。

  2. 启动代码调用__main,它主要做两件事:

    1. 数据拷贝 (Copy .data) :将.data段从Flash复制到SRAM。

    2. 清零初始化 (Zero .bss) :将.bss段对应的SRAM区域全部清零。

  3. 上述初始化完成后,才跳转到用户的main()函数开始执行。

如何查看?

在IDE(如Keil MDK或STM32CubeIDE)编译项目后,在构建输出窗口 (Build Output) 中可以看到一个类似下面的内存分布报告,它清楚地展示了各个段在Flash和RAM中占用了多少空间:

cpp 复制代码
Program Size: Code=6320 RO-data=432 RW-data=52 ZI-data=1024
  • Code + RO-data 属于 .text 段(在Flash中)。

  • RW-data 属于 .data 段(初始值在Flash,运行时在SRAM)。

  • ZI-data 属于 .bss 段(运行时在SRAM)。

我们也可以通过查看项目生成的链接脚本(.ld文件或是.map文件)来精确了解每个段被链接到了哪个地址(Flash地址通常以0x08000000开始,SRAM地址以0x20000000开始)。

相关推荐
BT-BOX1 天前
普中开发板基于51单片机贪吃蛇游戏设计
单片机·游戏·51单片机
驴友花雕1 天前
【花雕动手做】CanMV K230 AI视觉识别模块之使用CanMV IDE调试运行人脸代码
ide·人工智能·单片机·嵌入式硬件·canmv k230 ai视觉·canmv ide 人脸代码
Bigan(安)1 天前
【奶茶Beta专项】【LVGL9.4源码分析】09-core-obj_class对象类系统
linux·c语言·mcu·arm·unix
点灯小铭1 天前
基于单片机的酒驾报警刹车系统设计
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
Bigan(安)1 天前
【奶茶Beta专项】【LVGL9.4源码分析】08-theme主题管理
linux·c语言·mcu·arm·unix
boneStudent1 天前
Day29:I2C 高级应用
stm32·单片机·嵌入式硬件
Shawn_CH1 天前
epoll_wait 及相关函数原理详解
嵌入式
Shawn_CH1 天前
Linux 进程冻结机制原理详解
嵌入式
@good_good_study1 天前
STM32 I2C配置函数及实验
stm32·单片机
芯联智造1 天前
【stm32简单外设篇】- 28BYJ-48 步进电机(配 ULN2003 驱动板)
c语言·stm32·单片机·嵌入式硬件