目录

一、MCU 内存的 “大框架”——32 位 CPU 的寻址能力

二、STM32 的内存映射(整体布局)

三、Flash 存储器的内存分布(程序存储区)

四、SRAM 的内存分布(运行时数据区)

五、多任务下的内存分布(以 FreeRTOS 为例)

六、上下文切换的内存细节(任务调度)

总结

拓展:


一、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。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐