RAM Loading for Development
Flash memory on ESP devices has a limited write endurance — typically 100,000 cycles. During active development, flashing dozens of times per day adds up. RAM loading bypasses flash entirely: you convert your ELF to a RAM binary, load it directly into the device’s SRAM, and it executes immediately. No flash wear, no erase cycles, faster iteration.
When to use RAM loading
Section titled “When to use RAM loading”RAM loading is a good fit when:
- You are iterating rapidly on application logic and want sub-second deploy cycles.
- You want to preserve the existing flash contents (e.g., NVS data, calibration values).
- You are testing on hardware that has already been through many flash cycles.
It is not a good fit when:
- Your application depends on flash-resident features: NVS, SPIFFS, LittleFS, or OTA partitions.
- Secure boot is enabled (RAM loading requires
CONFIG_SECURE_BOOT=n). - Your binary is too large to fit in available SRAM.
The edit-build-load-test cycle
Section titled “The edit-build-load-test cycle”-
Build your project with ESP-IDF as usual. The build produces an ELF file (typically
build/<project>.elf):Terminal window idf.py build -
Convert the ELF to a RAM binary using
esp_elf_to_ram_binary:esp_elf_to_ram_binary({"elf_path": "build/my_project.elf","chip": "esp32"})This produces a binary with RAM segments (IRAM/DRAM) placed first, suitable for direct loading. The output defaults to
build/my_project-ram.bin. -
Load to the device with
esp_load_ram:esp_load_ram({"binary_path": "build/my_project-ram.bin","port": "/dev/ttyUSB0"})The binary transfers to RAM and begins executing immediately.
-
Capture output with
esp_serial_monitor:esp_serial_monitor({"port": "/dev/ttyUSB0","baud_rate": 115200,"duration_seconds": 10,"reset_on_connect": false})Set
reset_on_connecttofalse— resetting the device would stop the RAM-loaded code. -
Iterate: edit your source, rebuild, convert, load again. Steps 2-4 typically complete in a few seconds.
sdkconfig requirements
Section titled “sdkconfig requirements”Your project must be configured to produce binaries compatible with RAM execution.
Specify an output path
Section titled “Specify an output path”By default, esp_elf_to_ram_binary writes the output next to the ELF file with a -ram.bin suffix. To control the output location:
esp_elf_to_ram_binary({ "elf_path": "build/my_project.elf", "output_path": "/tmp/test-ram.bin", "chip": "auto"})Setting chip to "auto" lets esptool detect the target from the ELF metadata. Specify "esp32", "esp32s3", or "esp32c3" explicitly if auto-detection fails.
Limitations
Section titled “Limitations”- No flash-dependent features: NVS, SPIFFS, LittleFS, and OTA all read from flash. Code that calls these APIs will fail or return errors when running from RAM.
- No persistence: the loaded code runs until the device is reset. A hardware reset or power cycle returns the device to whatever firmware is in flash (or the ROM bootloader if flash is blank).
- SRAM size limits: ESP32 has roughly 520KB of SRAM. Large applications or those with heavy static allocations may not fit. The
esp_elf_to_ram_binarytool reports the output file size — compare this against your chip’s available RAM. - Cannot stop remotely: once loaded, execution continues until a physical reset. There is no software-only stop mechanism through mcesptool.