ESP32S3 esp_partition_write & irqs
Posted: Sun Oct 05, 2025 12:22 pm
I have an ESP32S3 project that emulates an old arcade game (I,Robot). To make sure anything keeps running all the time the different subsystems are all Interrupt triggered. All the code that runs within these interrupts is IRAM_ATTR and the data DRAM_ATTR flagged.
The original game had an NVRAM chip to store high scores and some statistics. To emulate this I am tracking changes and use esp_partition_write to store these to the flash chip. This all works great in general but after some more code changes to track down an issue I now have a reproducible Core 0 Panic
Guru Meditation Error: Core 0 panic'ed (Cache disabled but cached memory region accessed).
I know this happens if the cpu tries to execute code that is on the flash but based on the callstack I am getting this should not be the case
--- 0x40377a57: IRobotSystem::AudioOut(short*, unsigned long) at C:/projects/ESPIRobot/main/IRobotSystem.cpp:379
0x40377183: AudioCallback(short*, unsigned long) at C:/projects/ESPIRobot/main/main.cpp:169
0x40377e5d: AudioOutIrqFunc(void*) at C:/projects/ESPIRobot/main/AudioOutput.cpp:41
0x40382f0d: _xt_medint2 at C:/Users/ralfk/esp/v5.3.1/esp-idf/components/xtensa/xtensa_vectors.S:1329
0x403841e1: delay_us at C:/Users/ralfk/esp/v5.3.1/esp-idf/components/spi_flash/spi_flash_os_func_app.c:177
0x4038f63e: spi_flash_chip_generic_wait_idle at C:/Users/ralfk/esp/v5.3.1/esp-idf/components/spi_flash/spi_flash_chip_generic.c:409
0x40390237: spi_flash_chip_winbond_page_program at C:/Users/ralfk/esp/v5.3.1/esp-idf/components/spi_flash/spi_flash_chip_winbond.c:86
(inlined by) spi_flash_chip_winbond_page_program at C:/Users/ralfk/esp/v5.3.1/esp-idf/components/spi_flash/spi_flash_chip_winbond.c:73
0x4038f102: spi_flash_chip_generic_write at C:/Users/ralfk/esp/v5.3.1/esp-idf/components/spi_flash/spi_flash_chip_generic.c:295
0x40383e65: esp_flash_write at C:/Users/ralfk/esp/v5.3.1/esp-idf/components/spi_flash/esp_flash_api.c:1075
0x420092f1: esp_partition_write at C:/Users/ralfk/esp/v5.3.1/esp-idf/components/esp_partition/partition_target.c:78
0x420081f0: NVRam::Update() at C:/projects/ESPIRobot/main/NVRam.cpp:111
0x40377e33: IRobotSystem::UpdateNVRAM() at C:/projects/ESPIRobot/main/IRobotSystem.cpp:844
0x42006fde: RunIRobot(void*) at C:/projects/ESPIRobot/main/main.cpp:441
0x420070a9: app_main at C:/projects/ESPIRobot/main/main.cpp:483
0x42020d53: main_task at C:/Users/ralfk/esp/v5.3.1/esp-idf/components/freertos/app_startup.c:208
Line 379 is the third call in this block.
The function has the IRAM_ATTR
Based on the map file it has been placed there:
Is the error message here missleading for some reason?
I am a little bit surprised that the Interrupt is handled with the stack of the currently running task. Or is this only the case because it is the main task?
The original game had an NVRAM chip to store high scores and some statistics. To emulate this I am tracking changes and use esp_partition_write to store these to the flash chip. This all works great in general but after some more code changes to track down an issue I now have a reproducible Core 0 Panic
Guru Meditation Error: Core 0 panic'ed (Cache disabled but cached memory region accessed).
I know this happens if the cpu tries to execute code that is on the flash but based on the callstack I am getting this should not be the case
--- 0x40377a57: IRobotSystem::AudioOut(short*, unsigned long) at C:/projects/ESPIRobot/main/IRobotSystem.cpp:379
0x40377183: AudioCallback(short*, unsigned long) at C:/projects/ESPIRobot/main/main.cpp:169
0x40377e5d: AudioOutIrqFunc(void*) at C:/projects/ESPIRobot/main/AudioOutput.cpp:41
0x40382f0d: _xt_medint2 at C:/Users/ralfk/esp/v5.3.1/esp-idf/components/xtensa/xtensa_vectors.S:1329
0x403841e1: delay_us at C:/Users/ralfk/esp/v5.3.1/esp-idf/components/spi_flash/spi_flash_os_func_app.c:177
0x4038f63e: spi_flash_chip_generic_wait_idle at C:/Users/ralfk/esp/v5.3.1/esp-idf/components/spi_flash/spi_flash_chip_generic.c:409
0x40390237: spi_flash_chip_winbond_page_program at C:/Users/ralfk/esp/v5.3.1/esp-idf/components/spi_flash/spi_flash_chip_winbond.c:86
(inlined by) spi_flash_chip_winbond_page_program at C:/Users/ralfk/esp/v5.3.1/esp-idf/components/spi_flash/spi_flash_chip_winbond.c:73
0x4038f102: spi_flash_chip_generic_write at C:/Users/ralfk/esp/v5.3.1/esp-idf/components/spi_flash/spi_flash_chip_generic.c:295
0x40383e65: esp_flash_write at C:/Users/ralfk/esp/v5.3.1/esp-idf/components/spi_flash/esp_flash_api.c:1075
0x420092f1: esp_partition_write at C:/Users/ralfk/esp/v5.3.1/esp-idf/components/esp_partition/partition_target.c:78
0x420081f0: NVRam::Update() at C:/projects/ESPIRobot/main/NVRam.cpp:111
0x40377e33: IRobotSystem::UpdateNVRAM() at C:/projects/ESPIRobot/main/IRobotSystem.cpp:844
0x42006fde: RunIRobot(void*) at C:/projects/ESPIRobot/main/main.cpp:441
0x420070a9: app_main at C:/projects/ESPIRobot/main/main.cpp:483
0x42020d53: main_task at C:/Users/ralfk/esp/v5.3.1/esp-idf/components/freertos/app_startup.c:208
Line 379 is the third call in this block.
Code: Select all
m_Pokey[0].AudioTick(clkpersample);
m_Pokey[1].AudioTick(clkpersample);
m_Pokey[2].AudioTick(clkpersample);
m_Pokey[3].AudioTick(clkpersample);Code: Select all
void IRAM_ATTR Pokey::AudioTick(int clocks)Code: Select all
.iram1.8 0x4037b988 0x18e esp-idf/main/libmain.a(Pokey.cpp.obj)
0x1a6 (size before relaxing)
0x4037b988 Pokey::AudioTick(int)I am a little bit surprised that the Interrupt is handled with the stack of the currently running task. Or is this only the case because it is the main task?