ESP32应用程序的内存布局

应用程序内存布局

ESP32芯片具有灵活的内存映射功能。本节介绍ESP-IDF在默认情况下如何使用这些功能。

ESP-IDF中的应用程序代码可以放置在以下内存区域之一中。

IRAM(指令RAM)

ESP-IDF 为指令RAM 分配内部SRAM0区域的一部分(在技术参考手册中定义)。除了用于PRO和APP CPU缓存的第一个64 kB块之外,其余的内存范围(即从0x400800000x400A0000)用于存储需要从RAM运行的应用程序部分。

使用链接描述文件将ESP-IDF的几个组件和WiFi堆栈的一部分放入该区域。

如果一些应用程序代码需要放入IRAM,可以使用IRAM_ATTRdefine 来完成

#include“esp_attr.h”

void  IRAM_ATTR  gpio_isr_handler void *  arg { 
        //  ... 
}

以下是应用程序的部分可能被放置到IRAM中的情况。

  • 如果ESP_INTR_FLAG_IRAM在注册中断处理程序时使用中断处理程序,则必须将其置于IRAM中在这种情况下,ISR只能调用放置在IRAM中的功能或ROM中存在的功能。注1:所有的FreeRTOS API都被放置到IRAM中,所以可以安全地从中断处理程序调用。如果将ISR置于IRAM中,ISR使用的所有常数数据和ISR(包括但不限于数组)调用的函数都必须放入DRAM中const charDRAM_ATTR
  • 一些时序关键代码可以被放置到IRAM中以减少与从flash加载代码相关联的惩罚。ESP32通过32 kB缓存从闪存读取代码和数据。在某些情况下,将功能放置到IRAM中可能会减少由高速缓存未命中引起的延迟。

IROM(从Flash执行的代码)

如果功能未明确放置到IRAM或RTC内存中,则将其置于闪存中。技术参考手册中描述了使用Flash MMU来允许从闪存执行代码的机制。ESP-IDF从区域开始处放置从flash开始执行的代码启动后,第二阶段引导加载程序初始化Flash MMU,将代码所在的闪存中的位置映射到该区域的开头。这一地区的访问中使用两个32kB的块透明缓存范围。0x400D0000 — 0x404000000x400700000x40080000

需要注意的是外面的代码区域可能不能到达与窗口ABI 如果指令,所以需要特别的照顾区域被应用程序使用。默认情况下,ESP-IDF不使用这些区域。0x40000000 — 0x40400000CALLx0x40400000 — 0x408000000x40800000 — 0x40C00000

RTC快速记忆

从深度睡眠模式唤醒后必须运行的代码必须放置到RTC存储器中。请在深度睡眠文档中查看详细说明

DRAM(数据RAM)

链接器将非常数静态数据和零初始化数据放入256 kB 区域。请注意,如果使用蓝牙堆栈,则该区域减少64kB(通过移位起始地址)。如果使用跟踪记忆,该区域的长度也减少16 kB或32kB。将静态数据放置在该区域后留下的所有空间用于运行时堆。0x3FFB0000 — 0x3FFF00000x3FFC0000

恒定数据也可以被放置到DRAM中,例如,如果它在ISR中使用(参见上面的IRAM部分中的注释)。要做到这一点,DRAM_ATTR可以使用定义:

DRAM_ATTR  const  char []  format_string  =  “%p %x ; 
char  缓冲区[ 64 ]; 
sprintf buffer format_string ptr val );

不用说,不建议printf在ISR中使用和其他输出功能。为了调试目的,ESP_EARLY_LOGx在从ISR登录时使用宏。确保在这种情况下TAG两个和格式的字符串放在DRAM一起。

DROM(数据存储在Flash中)

默认情况下,链接器将常量数据放入4 MB区域(),用于通过Flash MMU和缓存访问外部闪存。例外是编译器嵌入到应用程序代码中的文字常量。0x3F400000 — 0x3F800000

RTC缓慢记忆

从RTC存储器运行的代码使用的全局和静态变量(即深度休眠存根代码)必须放置到RTC慢速存储器中。请在深度睡眠文档中查看详细说明

原文地址:https://www.cnblogs.com/noticeable/p/7458475.html