嵌入式内存分区详解

嵌入式系统中的内存分布

在嵌入式系统中,内存的管理和组织对于系统的性能和稳定性至关重要。内存主要分为 FlashRAM 两大部分,它们各自存储着不同类型的数据,并且系统中还存在着代码区全局区堆区栈区这四个重要的内存区域。

Flash和RAM的数据存储

这个只是主要的部分,可能还有一些没算进去

Flash:Flash 存储器用于存储程序代码和一些只读数据,其存储内容可以表示为:Flash = Code + RO-data + RW-data

  • .text(code):即编译后的二进制文件,是程序执行的指令集合。
  • .rodata(RO-data):Read Only data,只读数据,例如只读常量字面量(字符串)等。
  • .data初值镜像(RW-data):Read Write data,可读写数据,这些数据在程序启动时需要从 Flash 搬运到 RAM的.data段中。

RAM:随机存取存储器,用于程序运行时的数据存储,其存储内容为:RAM = RW-data + ZI-data

  • .data段(RW-data):已初始化的可读写数据,如静态变量和全局变量中已初始化的部分。

  • .bss段(ZI-data):未初始化的全局变量和静态变量,在系统启动时会自动初始化为 0。

  • stack(栈区)

  • heap(堆区)

嵌入式系统内存四区

嵌入式C代码在编译运行后,其内存占用主要分为四个区域,地址由低到高分别为:

代码区-> 全局区-> 堆区-> 栈区

如果要说5个区域的话就要算上常量区,地址由低到高分别为

代码区->常量区 ->全局区-> 堆区-> 栈区

区域名 存放内容
栈区 局部变量、函数参数、返回地址等,编译器自动分配释放
堆区 动态分配的内存(如malloc/new),由程序员分配和释放
全局区 .bss段:存放未初始化的全局变量/静态变量
.data段:存放已初始化的全局变量/静态变量
常量区 存放const修饰的全局变量、字符串、数字等
代码区 存放程序编译的二进制可执行代码,只读

代码区(.text)

  • 存放内容:所有的程序指令代码(编译生成的二进制可执行文件.bin/.hex等)

  • 存储位置Flash

  • 特点:只读,掉电不丢失,空间一般在编译时固定

  • 常见用途:存放主程序、库函数、启动文件、硬件中断向量表等

常量区(.rodata)

  • 存放内容字符串const初始化的全局变量

  • 存储位置Flash

    • 主要在 Flash 的只读段(常与 .text 同属只读区域;有的链接脚本会把 .rodata 合并进 .text)。
    • 在操作系统上运行时映射为只读页面;在嵌入式 MCU 上通常直接从 Flash XIP 读取,不搬运到 SRAM。
  • 特点:只读,掉电不丢失;运行期不参与分配/释放,与.data段不同,上电不拷贝到 RAM

  • 常见用途:各类查找表、滤波/控制系数、校验表、协议常量字符串常量、日志格式串

全局区(静态区)

  • 分为两部分.data段和.bss段

  • 存放内容

    • .data(数据段):已初始化全局变量静态变量
    • .bss:未初始化的全局变量静态变量
  • 存储位置

    • 已初始化数据区(.data):初始值放在Flash(镜像值),运行时从Flash搬运到SRAM
    • 未初始化数据区(.bss):只放在SRAM
  • 特点:全局唯一,掉电丢失,系统启动时自动初始化

  • 常见用途:跨函数/全局使用的变量、需要多次访问的数据

启动流程(Reset后)

  • 将Flash中的.data段中的初始值搬运到SRAM(Flash->SRAM)
  • 然后对于在SRAM中的.bss段数据全部清零

堆区(Heap)

  • 存放内容:运行时动态分配(如malloc/freenew/delete)的内存块

  • 存储位置SRAM

  • 特点:大小灵活,手动分配释放,易碎片化,掉电丢失

  • 常见用途:需要动态申请的缓存、链表、队列、对象等数据结构

栈区(Stack)

  • 存放内容:函数调用现场(局部变量、参数、返回地址、保存的寄存器等)
  • 存储位置SRAM
  • 特点:自动分配和回收,先进后出,容量有限,掉电丢失
  • 常见用途:函数内的临时数据、递归调用、保存中断现场

内存分布示意图

image-20250829201659133