深入理解 Xtensa 架构 ESP32 内存架构(SRAM、IRAM、IROM、DRAM、DROM详解)

ESP32 及其他 Xtensa 架构 MCU 中,内存被划分为不同的区域,以优化性能和存储管理。这些内存区域包括 SRAM, IRAM, DRAM, IROM, DROM,它们各有用途。


1. 内存区域总览

ESP32 的内存架构主要由:

  • SRAM(Static RAM)
  • IRAM(Instruction RAM)
  • IROM(Instruction ROM)
  • DRAM(Data RAM)
  • DROM(Data ROM)

组成,每个部分有特定的用途。

名称 作用 存储内容 特性
SRAM(Static RAM) 片上 RAM IRAM + DRAM 速度快,供 CPU 使用
IRAM(Instruction RAM) 指令 RAM 存放可执行代码(运行时加载) 运行时可修改
DRAM(Data RAM) 数据 RAM 存放 .bss(未初始化数据)、.data(已初始化数据) 运行时可修改
IROM(Instruction ROM) 指令 ROM 存放 Flash 里的 .text(程序代码) 运行时不可修改
DROM(Data ROM) 数据 ROM 存放 Flash 里的 .rodata(只读数据) 运行时不可修改

2. 详细解析

2.1 SRAM(Static RAM,片上静态 RAM)

  • SRAM 是 MCU 内部的 RAM,供 CPU 使用
  • IRAM(存放指令)+ DRAM(存放数据) 组成
  • 运行速度快(比外部 Flash 快很多)

SRAM 的划分

SRAM0 + SRAM1(用于 IRAM 和 DRAM)

  • IRAM:指令 RAM ,存放 可执行代码
  • DRAM:数据 RAM ,存放 数据(变量、堆、栈)

SRAM2(仅用于 DRAM)

  • 仅存放 数据

2.2 IRAM(Instruction RAM,指令 RAM)

  • 存放 可执行代码
  • 用于高实时性任务 ,比如 中断处理
  • 代码必须从 Flash 加载到 IRAM 才能运行
  • IRAM 里的代码可以被修改

🔹 示例:

ESP-IDF 里,想要让某个函数运行在 IRAM ,需要使用 IRAM_ATTR 修饰符:

c 复制代码
void IRAM_ATTR gpio_isr_handler(void *arg) {
    // GPIO 中断处理(放入 IRAM,提高执行速度)
}

2.3 DRAM(Data RAM,数据 RAM)

  • 存放 数据(变量、栈、堆)
  • DRAM 里的数据 可读可写
  • 运行时 CPU 从 DRAM 读取变量数据

DRAM 里存放的内容:

  • .data(已初始化的全局变量)
  • .bss(未初始化的全局变量)
  • 堆(Heap)
  • 栈(Stack)

简单理解DRAM 里存放的是程序运行时需要用的数据,比如全局变量、栈、堆等


2.4 IROM(Instruction ROM,指令 ROM)

  • 存放 Flash 里的程序代码(.text)
  • 代码不能被修改,只能执行
  • 运行时,CPU 从 Flash 直接取指令执行

IROM 是存放在 Flash 里的代码,只有一部分需要提高执行速度的代码会被拷贝到 IRAM 执行


2.5 DROM(Data ROM,数据 ROM)

  • 存放 Flash 里的只读数据(.rodata)
  • 运行时 CPU 直接从 Flash 读取
  • 不能修改

DROM 里存放的内容:

  • .rodata(只读数据,如 const char[] 字符串)
  • 其他只读配置数据

简单理解DROM 是存放在 Flash 里的只读数据(比如 const char *string = "Hello"


3. ESP32 内存架构示意图

plaintext 复制代码
+-------------------------+  0x40000000  (IROM)
|  Flash (代码)           |  存放 .text(程序代码)
+-------------------------+
|  Flash (只读数据)       |  存放 .rodata(只读数据)  <--- DROM
+-------------------------+
|  IRAM (指令 RAM)       |  运行时加载的代码  <--- IRAM
+-------------------------+  0x3F800000  (SRAM)
|  DRAM (数据 RAM)       |  存放变量、堆、栈  <--- DRAM
+-------------------------+

4. 什么时候用 IRAM?

需要高实时性,避免 Flash 访问延迟

  • 中断处理(ISR)
  • WiFi、蓝牙实时任务
  • 定时器回调

方法:使用 IRAM_ATTR

c 复制代码
void IRAM_ATTR gpio_isr_handler(void *arg) {
    // 高速执行的 GPIO 中断
}

5. 什么时候用 DRAM?

存放变量

  • 全局变量
  • 堆(malloc 分配)
  • 栈(局部变量、函数参数)

方法:直接使用全局变量

c 复制代码
int counter = 0;  // 存放在 DRAM

6.总结

为什么有 IRAM 和 IROM? 👉 IROM 在 Flash,CPU 取指令慢,所以部分代码(中断、WiFi 任务)需要拷贝到 IRAM 加速执行。

为什么有 DRAM 和 DROM? 👉 DRAM 是可变数据,DROM 是 Flash 里的只读数据。

如何让代码运行在 IRAM? 👉 使用 IRAM_ATTR 修饰符:

c 复制代码
void IRAM_ATTR gpio_isr_handler(void *arg) { ... }

如何减少 RAM 占用? 👉 const 变量存放在 Flash

c 复制代码
const char *string = "Hello";  // 存入 DROM,节省 DRAM
相关推荐
AI服务老曹12 小时前
架构实战:如何构建支持X86/ARM及异构GPU/NPU的跨平台企业级AI视频管理系统?
arm开发·人工智能·架构
万岳科技系统开发12 小时前
小程序直播架构调整指南:H5嵌套模式的优化与替代方案
小程序·架构
roman_日积跬步-终至千里13 小时前
【系统架构师案例题-知识点】云原生与大数据架构
大数据·云原生·系统架构
迷藏49413 小时前
# 发散创新:用Locust实现高并发场景下的精准压力测试与性能调优实战在现代微服务架构中,**接口稳定性与响应速度**已成为衡量
java·python·微服务·架构·压力测试
147API13 小时前
Claude 工具调用场景梳理:从 MCP 到企业落地链路
人工智能·架构·api·claude
MaxCode-113 小时前
Chapter 9:企业实战案例与架构沉淀
人工智能·spring·架构
舒一笑13 小时前
我筛了 30+ 个高质量技术/商业网站,真正值得架构师长期看的只有这 10 个
架构
ai产品老杨13 小时前
【架构深研】如何构建兼容X86/ARM与异构算力的AI视频中台?基于GB28181与边缘计算的源码交付实践
arm开发·人工智能·架构
jiangbo_dev13 小时前
.NET 微服务监控避坑指南:告别盲翻日志,10 分钟搞定 OpenTelemetry 全链路追踪
架构
米高梅狮子14 小时前
07.基于LNMP架构部署blog应用和DaemonSet、Job
架构