揭秘STM32内存布局:从Flash到SRAM全解析
STM32作为32位MCU,其4GB寻址空间被划分为Flash程序存储区(0x08000000起)和SRAM运行时数据区。Flash存储程序代码和常量,包括.text、.rodata、.rwdata等段;SRAM则分为数据段(.data/.bss)、堆区(动态内存分配)和栈区(函数调用上下文)。
目录
一、MCU 内存的 “大框架”——32 位 CPU 的寻址能力
一、MCU 内存的 “大框架”——32 位 CPU 的寻址能力
STM32 是32 位 CPU,32 位地址总线意味着它的理论寻址能力是 4GB,地址范围是 0x0000 0000 ~ 0xFFFF FFFF。

二、STM32 的内存映射(整体布局)
从第一张图的 “Memory map” 可以看到,STM32 的 4GB 寻址空间被划分成多个功能区块:

三、Flash 存储器的内存分布(程序存储区)
Flash 是 MCU 的 “程序硬盘”,用于永久存储程序代码和常量数据。
-
地址范围:0x0800 0000 ~ 0x0807 FFFF(示例中为 512KB 容量的 Flash)。
-
区域划分:
-
用户代码区:存储我们编写的程序代码,包含多个段:
-
.text段:存放程序的指令代码(函数、指令序列等)。
-
.rodata段:存放只读常量(如字符串常量、const 修饰的变量)。
-
.rwdata段:存放需要初始化的可读写数据(运行时会被复制到 SRAM 的.data 段)。
-
-
空闲空间:Flash 中未被用户代码占用的区域。
-

四、SRAM 的内存分布(运行时数据区)
SRAM 是程序运行时的 “临时内存”,所有动态数据都在这儿折腾。SRAM 的布局可以拆解为以下几个核心部分:

1.数据段区域
-
.data 段:存放 “初始化了特定值的可修改变量”(如
int counter_3 = 1; static int counter_4 = 2;)。这些数据在程序启动时会从 Flash 的.rwdata 段复制到 SRAM 的.data 段。 -
.bss 段:存放 “未初始化或初始化为 0 的可修改变量”(如
int counter = 0; int counter_1; static int counter_2;)。程序启动时,系统会自动将这块区域清零。
2.堆(Heap)区域
-
功能:用于动态内存分配(如 C 语言中的
malloc、C++ 中的new)。 -
分布:有普通堆(
HEAP_SIZE 0X800,即 2KB)和 FreeRTOS 的堆(FreeRTOS_HEAP_SIZE15Kbytes)。堆的生长方向是地址增大的方向。
3.栈(Stack)区域
-
功能:用于存储函数调用的上下文(局部变量、函数参数、返回地址等),以及中断发生时的现场保护。
-
生长方向:地址减小的方向(从栈顶向栈底生长)。

-
类型:
-
系统栈(MSP):用于中断处理、内核级操作。
-
任务栈(PSP,结合 FreeRTOS):每个任务有自己的栈空间,用于存储任务的运行上下文(如图中 Task1、Task2、Task5 的栈)。
-
其他区域
-
未定义数据区(other undefine data):SRAM 中未被上述段明确划分的区域。
-
FreeRTOS 相关区域:如任务控制块(TCB,用于管理任务的状态、栈指针等)、FreeRTOS 的堆空间(ucHeap)。
五、多任务下的内存分布(以 FreeRTOS 为例)
在嵌入式实时操作系统(如 FreeRTOS)中,内存分布会更复杂,核心是 “任务的独立栈和 TCB”:
-
任务控制块(TCB):每个任务都有一个 TCB,用于保存任务的基本信息(如栈指针、优先级、状态等),如第四张图中 Task1、Task2、Task5 的 TCB。
-
任务栈:每个任务有独立的栈空间,用于存储任务运行时的局部变量、函数调用信息等。任务切换时,栈中的上下文会被保存 / 恢复(这就是 “上下文切换” 的核心)。
-
内存回收:已释放的任务空间会被合并(如第四张图中 “已释放的任务空间(TASK3 和 TASK4 的空间已合并)”)。
六、上下文切换的内存细节(任务调度)
第五张图展示了任务调度时 “上下文切换” 的内存操作,核心是寄存器的入栈和出栈:

-
硬件压栈:当任务切换触发时,硬件会自动将核心寄存器(xPSR、PC、LR、R12、R3-R0)压入栈中。
-
软件压栈:软件会将剩余寄存器(R11-R4)压入任务栈,并将栈指针(PSP)保存到 TCB 中。
-
恢复过程:切换到新任务时,从 TCB 中取出 PSP,再从栈中恢复寄存器,从而让新任务 “接着运行”。
总结
MCU 的内存分布是 “分层且分工明确” 的:
-
Flash 负责永久存储程序和常量;
-
SRAM 负责运行时的动态数据、函数调用、任务调度;
-
外设区负责硬件资源的访问。
拓展:
芯片的地址总线是 32 位(支持 4GB 寻址),但实际硬件资源(Flash、SRAM、外设)的容量远小于 4GB。剩余的地址空间中,大部分会被标记为 Reserved,这是硬件架构设计的自然结果。
-
STM32 是 32 位 CPU,理论寻址范围是
0x0000 0000 ~ 0xFFFF FFFF(共 4GB)。 -
但实际硬件中,Flash 通常是几十 KB 到几 MB(如常见的 512KB、1MB),SRAM 是几 KB 到几百 KB(如 128KB),外设寄存器的地址范围也很有限。
-
这种 “理论寻址能力” 和 “实际硬件容量” 的巨大差距,导致剩余的大部分地址空间只能被标记为 Reserved。
更多推荐



所有评论(0)