mcu的存储模块

mcu的存储空间就两个模块:1. rom; 2. ram;

'rom' 的作用主要就是存储code和一些不需更改的常量,**掉电不丢失**。而 'ram' 则是用于存储运行code的中间变量,**掉电丢失**。'rom'  'ram' 打引号是因为,目前因为更新换代,它们已经不是严格意义上的rom和ram了。而是用于表示其掉电不丢失,和掉电丢失的特性。

存储空间布局示例(以 ARM Cortex-M 为例)

+---------------------+
|      ROM (Flash)     |
+---------------------+
| 中断向量表          | <- 0x0000_0000
| 代码区(.text)     |
| 常量区(.rodata)   |
| 初始化数据(.data) | -> 运行时拷贝到 RAM
+---------------------+
|      RAM             |
+---------------------+
| 已初始化数据(.data)| <- 拷贝自 ROM
| BSS 段(.bss)      | <- 未初始化变量(清零)
| 堆(Heap)           | -> 向高地址增长
| ...(空闲内存)      |
| 栈(Stack)          | <- 向低地址增长
+---------------------+
| 特殊功能寄存器(SFR)| <- 固定地址(如 0x4000_0000)
+---------------------+

rom(只读存储器)

  • 作用:存储 不可变数据,掉电后数据保留。

  • 具体分区

  • 代码区(Text/Code Segment)

  • 存放编译后的机器代码(函数、指令)。

  • 通常位于 Flash 或 ROM 的起始地址。

  • 常量区(Constant Data)

  • 存储 const 修饰的全局或静态常量(如 const int a = 10;)。

  • 部分 MCU 会将常量直接嵌入代码区。

  • 初始化数据区(Initialized Data)

  • 存储全局变量和静态变量的初始值(如 int global_var = 100;)。

  • 注意:这些变量的初始值存储在 ROM 中,但运行时会被拷贝到 RAM 的对应区域。

  • ram(随机存取存储器)

  • 作用:存储 可变数据,掉电后数据丢失。

  • 根据变量的存储周期分为静态区和动态区,1.静态区的变量在程序初始化被创建,且不会被中途释放,随着程序存在。2.动态区的变量会随着程序的运行被创建或者释放。具体分区,

  • 静态区(Static Storage)

  • BSS段(.bss)

  • 存储类型全局变量和静态变量(包括 static 修饰的局部变量)。

  • 生命周期:从程序启动到结束。

  • 注意:初始化后的该变量区域,通常会被起始文件清零,以保证变量的默认值为0。

  • 已初始化数据(.data):

  • 存储类型全局变量和静态变量(包括 static 修饰的局部变量)。

  • 生命周期:从程序启动到结束。

  • 注意:初始化后的变量初始值从 rom 拷贝到 ram的该区域。

  • 动态区(Dynamic Storage)
  • 堆(Heap)

  • 存储类型:用于动态内存分配(如 mallocnew)。

  • 手动管理:需开发者分配和释放,否则可能导致内存泄漏。

  • 生长方向:通常向高地址扩展(与栈相反)。

  • 栈(Stack)

  • 存储类型:用于存储函数调用时的局部变量、参数、返回地址等。

  • 自动管理:由编译器自动分配和释放。

  • 生长方向:通常向低地址扩展(与堆相反)。

  • 其他特殊区域

  • 特殊功能寄存器(SFR):用于控制外设(如 GPIO、定时器)的寄存器,位于固定 RAM 地址。

  • 保留区域(Reserved):MCU 厂商预留的 RAM 空间(如 Bootloader 专用)。

  • 注意

    1. ROM 中的“初始化数据”

    2. 初始化全局变量的初始值存储在 ROM 中,程序启动时会被拷贝到 RAM 的静态区。例如:

      int initialized_var = 100; // 初始值 100 存储在 ROM,运行时拷贝到 RAM

    3. 堆和栈的动态性

    4. 堆和栈的分配是动态的,但 栈空间通常由编译器预先分配固定大小(如通过链接脚本指定),而非运行时动态扩展。

    5. 堆的碎片化问题:频繁的 malloc/free 可能导致内存碎片,需谨慎使用。

    6. 未初始化的静态区(BSS 段)

    7. 未初始化的全局变量和静态变量(如 int uninit_var;)默认值为 0,存储在 RAM 的 BSS 段(Block Started by Symbol)

    8. 程序启动时,BSS 段会被清零(通常由启动代码完成)。

    9. 代码区的特殊内容

    10. 中断向量表:通常位于 ROM 的起始位置,存储中断服务程序(ISR)的入口地址。

    11. 启动代码(Startup Code):负责初始化 RAM(拷贝初始化数据、清零 BSS 段)、设置堆栈指针等。

    12. 存储映射的硬件特性

    13. 哈佛架构 vs 冯·诺依曼架构

    14. 哈佛架构(如多数 MCU):代码(ROM)和数据(RAM)使用独立总线,可并行访问。

    15. 冯·诺依曼架构:代码和数据共享总线,效率较低。

    作者:bastarddd

    物联沃分享整理
    物联沃-IOTWORD物联网 » MCU存储空间布局详解

    发表回复