應用程序內存布局
ESP32芯片具有靈活的內存映射功能。本節介紹ESP-IDF在默認情況下如何使用這些功能。
ESP-IDF中的應用程序代碼可以放置在以下內存區域之一中。
IRAM(指令RAM)
ESP-IDF 為指令RAM 分配內部SRAM0區域的一部分(在技術參考手冊中定義)。除了用於PRO和APP CPU緩存的第一個64 kB塊之外,其余的內存范圍(即從0x40080000
到0x400A0000
)用於存儲需要從RAM運行的應用程序部分。
使用鏈接描述文件將ESP-IDF的幾個組件和WiFi堆棧的一部分放入該區域。
如果一些應用程序代碼需要放入IRAM,可以使用IRAM_ATTR
define 來完成:
#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 char
DRAM_ATTR
- 一些時序關鍵代碼可以被放置到IRAM中以減少與從flash加載代碼相關聯的懲罰。ESP32通過32 kB緩存從閃存讀取代碼和數據。在某些情況下,將功能放置到IRAM中可能會減少由高速緩存未命中引起的延遲。
IROM(從Flash執行的代碼)
如果功能未明確放置到IRAM或RTC內存中,則將其置於閃存中。技術參考手冊中描述了使用Flash MMU來允許從閃存執行代碼的機制。ESP-IDF從區域開始處放置從flash開始執行的代碼。啟動后,第二階段引導加載程序初始化Flash MMU,將代碼所在的閃存中的位置映射到該區域的開頭。這一地區的訪問中使用兩個32kB的塊透明緩存- 范圍。0x400D0000 — 0x40400000
0x40070000
0x40080000
需要注意的是外面的代碼區域可能不能到達與窗口ABI 如果指令,所以需要特別的照顧或區域被應用程序使用。默認情況下,ESP-IDF不使用這些區域。0x40000000 — 0x40400000
CALLx
0x40400000 — 0x40800000
0x40800000 — 0x40C00000
RTC快速記憶
從深度睡眠模式喚醒后必須運行的代碼必須放置到RTC存儲器中。請在深度睡眠文檔中查看詳細說明。
DRAM(數據RAM)
鏈接器將非常數靜態數據和零初始化數據放入256 kB 區域。請注意,如果使用藍牙堆棧,則該區域減少64kB(通過移位起始地址)。如果使用跟蹤記憶,該區域的長度也減少16 kB或32kB。將靜態數據放置在該區域后留下的所有空間用於運行時堆。0x3FFB0000 — 0x3FFF0000
0x3FFC0000
恆定數據也可以被放置到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慢速存儲器中。請在深度睡眠文檔中查看詳細說明。