嵌入式内存分区详解

嵌入式内存分区详解
THEDI嵌入式系统中的内存分布
在嵌入式系统中,内存的管理和组织对于系统的性能和稳定性至关重要。内存主要分为 Flash
和 RAM
两大部分,它们各自存储着不同类型的数据,并且系统中还存在着代码区
、全局区
、堆区
和栈区
这四个重要的内存区域。
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(数据段):已初始化
存储位置:
- 已初始化数据区(.data):初始值放在
Flash
(镜像值),运行时从Flash
搬运到SRAM
- 未初始化数据区(.bss):只放在
SRAM
,
- 已初始化数据区(.data):初始值放在
特点:全局唯一,掉电丢失,系统启动时自动初始化
常见用途:跨函数/全局使用的变量、需要多次访问的数据
启动流程(Reset后):
- 将Flash中的.data段中的初始值搬运到SRAM(Flash->SRAM)
- 然后对于在SRAM中的.bss段数据全部清零
堆区(Heap)
存放内容:运行时动态分配(如
malloc
/free
、new
/delete
)的内存块存储位置:
SRAM
特点:大小灵活,手动分配释放,易碎片化,掉电丢失
常见用途:需要动态申请的缓存、链表、队列、对象等数据结构
栈区(Stack)
- 存放内容:函数调用现场(局部变量、参数、返回地址、保存的寄存器等)
- 存储位置:
SRAM
- 特点:自动分配和回收,先进后出,容量有限,掉电丢失
- 常见用途:函数内的临时数据、递归调用、保存中断现场