A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/memory-types.html below:

Website Navigation


Memory Types - ESP32 - — ESP-IDF Programming Guide latest documentation

Memory Types

[中文]

ESP32 chip has multiple memory types and flexible memory mapping features. This section describes how ESP-IDF uses these features by default.

ESP-IDF distinguishes between instruction memory bus (IRAM, IROM, RTC FAST memory) and data memory bus (DRAM, DROM). Instruction memory is executable, and can only be read or written via 4-byte aligned words. Data memory is not executable and can be accessed via individual byte operations. For more information about the different memory buses consult the ESP32 Technical Reference Manual > System and Memory [PDF].

DRAM (Data RAM)

Non-constant static data (.data) and zero-initialized data (.bss) is placed by the linker into Internal SRAM as data memory. The remaining space in this region is used for the runtime heap.

By applying the EXT_RAM_BSS_ATTR macro, zero-initialized data can also be placed into external RAM. To use this macro, the CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY needs to be enabled. See Allow .bss Segment to Be Placed in External Memory.

The available size of the internal DRAM region is reduced by 64 KB (by shifting start address to 0x3FFC0000) if Bluetooth stack is used. Length of this region is also reduced by 16 KB or 32 KB if trace memory is used. Due to some memory fragmentation issues caused by ROM, it is also not possible to use all available DRAM for static allocations - however the remaining DRAM is still available as heap at runtime.

Note

There is 520 KB of available SRAM (320 KB of DRAM and 200 KB of IRAM) on the ESP32. However, due to a technical limitation, the maximum statically allocated DRAM usage is 160 KB. The remaining 160 KB (for a total of 320 KB of DRAM) can only be allocated at runtime as heap.

Constant data may also be placed into DRAM, for example if it is used in an non-flash-safe ISR (see explanation under How to Place Code in IRAM).

"noinit" DRAM

The macro __NOINIT_ATTR can be used as attribute to place data into .noinit section. The values placed into this section will not be initialized at startup and should keep its value after software restart.

By applying the EXT_RAM_NOINIT_ATTR macro, non-initialized value could also be placed in external RAM. To do this, the CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY needs to be enabled. See Allow .noinit Segment to Be Placed in External Memory. If the CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not enabled, EXT_RAM_NOINIT_ATTR will behave just as __NOINIT_ATTR, it will make data to be placed into .noinit segment in internal RAM.

Example:

__NOINIT_ATTR uint32_t noinit_data;
IRAM (Instruction RAM)

ESP-IDF allocates part of the Internal SRAM0 region for instruction RAM. The region is defined in ESP32 Technical Reference Manual > System and Memory > Embedded Memory [PDF]. Except for the first 64 KB block which is used for PRO and APP MMU caches, the rest of this memory range (i.e., from 0x40080000 to 0x400A0000) is used to store parts of the application which need to run from RAM.

When to Place Code in IRAM

Cases when parts of the application should be placed into IRAM:

How to Place Code in IRAM

Some code is automatically placed into the IRAM region using the linker script.

If some specific application code needs to be placed into IRAM, it can be done by using the Linker Script Generation feature and adding a linker script fragment file to your component that targets at the entire source files or functions with the noflash placement. See the Linker Script Generation docs for more information.

Alternatively, it is possible to specify IRAM placement in the source code using the IRAM_ATTR macro:

#include "esp_attr.h"

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

There are some possible issues with placement in IRAM, that may cause problems with IRAM-safe interrupt handlers:

Note that knowing which data should be marked with DRAM_ATTR can be hard, the compiler will sometimes recognize that a variable or expression is constant (even if it is not marked const) and optimize it into flash, unless it is marked with DRAM_ATTR.

Jump table optimizations can be re-enabled for individual source files that do not need to be placed in IRAM. For instructions on how to add the -fno-jump-tables -fno-tree-switch-conversion options when compiling individual source files, see Controlling Component Compilation.

IROM (Code Executed from flash)

If a function is not explicitly placed into IRAM (Instruction RAM) or RTC memory, it is placed into flash. As IRAM is limited, most of an application's binary code must be placed into IROM instead.

The mechanism by which Flash MMU is used to allow code execution from flash is described in ESP32 Technical Reference Manual > Memory Management and Protection Units (MMU, MPU) [PDF].

During Application Startup Flow, the bootloader (which runs from IRAM) configures the MMU flash cache to map the app's instruction code region to the instruction space. Flash accessed via the MMU is cached using some internal SRAM and accessing cached flash data is as fast as accessing other types of internal memory.

DROM (Data Stored in flash)

By default, constant data is placed by the linker into a region mapped to the MMU flash cache. This is the same as the IROM (Code Executed from flash) section, but is for read-only data not executable code.

The only constant data not placed into this memory type by default are literal constants which are embedded by the compiler into application code. These are placed as the surrounding function's executable instructions.

The DRAM_ATTR attribute can be used to force constants from DROM into the DRAM (Data RAM) section (see above).

RTC Slow Memory

Global and static variables used by code which runs from RTC memory must be placed into RTC Slow memory. For example deep sleep variables can be placed here instead of RTC FAST memory, or code and variables accessed by the Ultra Low Power (ULP) coprocessor.

The attribute macro named RTC_NOINIT_ATTR can be used to place data into this type of memory. The values placed into this section keep their value after waking from deep sleep.

Example:

RTC_NOINIT_ATTR uint32_t rtc_noinit_data;
RTC FAST Memory

The same region of RTC FAST memory can be accessed as both instruction and data memory. Code which has to run after wake-up from deep sleep mode has to be placed into RTC memory. Please check detailed description in deep sleep documentation.

In single core mode (CONFIG_FREERTOS_UNICORE), remaining RTC FAST memory is added to the heap, unless the option CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP is disabled. This memory can be used interchangeably with DRAM (Data RAM), but is slightly slower to access and not DMA-capable.

This option is not available in dual core mode, because on ESP32, RTC FAST memory can only be accessed by the PRO CPU.

DMA-Capable Requirement

Most peripheral DMA controllers (e.g., SPI, sdmmc, etc.) have requirements that sending/receiving buffers should be placed in DRAM and word-aligned. We suggest to place DMA buffers in static variables rather than in the stack. Use macro DMA_ATTR to declare global/local static variables like:

DMA_ATTR uint8_t buffer[]="I want to send something";

void app_main()
{
    // initialization code...
    spi_transaction_t temp = {
        .tx_buffer = buffer,
        .length = 8 * sizeof(buffer),
    };
    spi_device_transmit(spi, &temp);
    // other stuff
}

Or:

void app_main()
{
    DMA_ATTR static uint8_t buffer[] = "I want to send something";
    // initialization code...
    spi_transaction_t temp = {
        .tx_buffer = buffer,
        .length = 8 * sizeof(buffer),
    };
    spi_device_transmit(spi, &temp);
    // other stuff
}

It is also possible to allocate DMA-capable memory buffers dynamically by using the MALLOC_CAP_DMA capabilities flag.

DMA Buffer in the Stack

Placing DMA buffers in the stack is possible but discouraged. If doing so, pay attention to the following:


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4