Files
esp-idf/examples/system/xip_from_psram
Michael.B c961738157 fix(examples): count periodic IRQs during xip_from_psram flash erase
Replace the oneshot latency assumption with a 1ms periodic timer that
runs only across a forced dirty-partition erase, and fail if irq_count
falls below 80% of the expected count from erase duration.
2026-08-12 17:11:00 +08:00
..

Supported Targets ESP32-C5 ESP32-C61 ESP32-H4 ESP32-P4 ESP32-S2 ESP32-S3 ESP32-S31

XIP (Execute-In-Place) From PSRAM Example

This example illustrates a typical usage of XIP (Execute-In-Place) From PSRAM. With this feature:

  • You can optimize internal RAM usage
  • System can avoid disabling the Cache during an SPI1 Flash operation.

Overview

Here we define two sets of operations related to external memory: SET1: Operations where CPU fetches data and instructions from external memory. SET2: ESP Flash driver operations and other operations from drivers based on ESP Flash (NVS, Partition drivers, etc.).

By default, during SET2 operations, concurrent access requests to the Flash and PSRAM (SET1 operations) will be disabled otherwise both the SET1 and SET2 operations are not guaranteed to be safe (this is an undefined behaviour).

Only ISRs in internal RAM will get executed during SET2 operations. Besides, if any functions or data are accessed in these ISRs (usually this happens in ISR callbacks), they need to be placed into internal RAM as well. For interrupt handlers which need to execute when the cache is disabled (e.g., for low latency operations), you need to set the ESP_INTR_FLAG_IRAM flag when the interrupt handler is registered.

When CONFIG_SPIRAM_XIP_FROM_PSRAM is enabled, the flash.text sections (for instructions) and the .rodata section (read only data) will be moved to PSRAM. Corresponding virtual memory range will be mapped to PSRAM. Under this condition, ESP-IDF won't disable concurrent accesses to external memory (SET1 operations) anymore.

By using this feature, during SET2 operations, placement of ISRs, ISR callbacks, and related data are no longer limited to internal RAM.

Example Process

To show this feature, in this example we go through the following steps:

General Steps:

  1. Create a partition for Flash Erase Operation
  2. Create an ISR-dispatched periodic esp_timer with a 1 ms interval. Overdue events are skipped so callbacks delayed by the erase are not counted afterward.

PSRAM Steps: 3. Program the partition with non-erased data, then start the periodic timer 4. Erase the partition while timer callbacks call a function in PSRAM 5. Stop the timer and wait for any in-flight callback to finish 6. Verify that at least 80% of the expected callbacks ran during the erase

IRAM Steps: 7. Repeat the same process with timer callbacks calling a function in IRAM 8. Verify the callback count during the erase

Timeline

Initialization and config -> Start periodic timer -> Flash erase with callbacks in PSRAM -> Stop timer -> Start periodic timer -> Flash erase with callbacks in IRAM -> Stop timer

                   ISR         CPU
                    |           |
                    |           |
                    |           |
                    |           * <----flash operation starts
                    |           *
  callback starts   * --------> *
     (in PSRAM)     *           *
  callback finishes * <-------- *
                    |           *
                    |           *
                    |           * <----flash operation finishes
                    |           |
                    |           |
                    |           |
                    |           |
                    |           |
                    |           |
                    |           * <----flash operation starts
                    |           *
  callback starts   * --------> *
     (in IRAM)      *           *
  callback finishes * <-------- *
                    |           *
                    |           *
                    |           * <----flash operation finishes
                    |           |
                    |           |

Example Result

The example verifies that ISR-dispatched periodic timer callbacks can continue to run during flash erase operations when they call functions in either PSRAM or IRAM. It reports the erase duration, timer interval, actual callback count, and expected callback count for each case.

Configure the project

Open the project configuration menu (idf.py menuconfig).

  1. Set the Partition Table -> Custom partition table CSV to y.
  2. Set the Component config -> High resolution timer -> Support ISR dispatch method to y.
  3. Set the Component config -> ESP PSRAM -> SPI RAM config to y then set Cache fetch instructions from SPI RAM and Cache load read only data from SPI RAM to y.

Build and Flash

Run idf.py -p PORT flash monitor to build and flash the project..

(To exit the serial monitor, type Ctrl-].)

See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.

Example Output

I (742) esp_psram: Reserving pool of 32K of internal memory for DMA/internal allocations
I (742) example: found partition 'storage1' at offset 0x110000 with size 0x10000

I (...) example: erase with callback in PSRAM: duration_ms=..., interval_ms=1.000, irq_count=..., expected=...
I (...) example: erase with callback in IRAM: duration_ms=..., interval_ms=1.000, irq_count=..., expected=...

Troubleshooting

For any technical queries, please open an issue on GitHub. We will get back to you soon.