ESP32 Nes Emulator: Guru Meditation Error: Core 0 panic'ed (StoreProhibited). Exception was unhandled

I’m fixing an old project on platformio, a Nes emulator based on nofrendo. However, I came across an error that is causing my esp32 Dev kit 4 to reset.

NOTE: I tried resetting ESP_TASK_MAIN_STACK in my main.c for testing #define ESP_TASK_MAIN_STACK (CONFIG_ESP_MAIN_TASK_STACK_SIZE + 2048)

I’m having the following:

Guru Meditation Error: Core  0 panic'ed (StoreProhibited). Exception was unhandled.

Core  0 register dump:
PC      : 0x4000c46c  PS      : 0x00060630  A0      : 0x800d5af0  A1      : 0x3ffbd270
A2      : 0x00000028  A3      : 0x80808080  A4      : 0x00000100  A5      : 0x00000028  
A6      : 0x00000003  A7      : 0x00000010  A8      : 0x00060021  A9      : 0x3ffd17b0
A10     : 0x3ffd1a44  A11     : 0x00000000  A12     : 0x00000000  A13     : 0x18000000  
A14     : 0x00000003  A15     : 0x00060023  SAR     : 0x00000001  EXCCAUSE: 0x0000001d
EXCVADDR: 0x00000028  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x0000000f 

Backtrace: 0x4000c469:0x3ffbd270 0x400d5aed:0x3ffbd280 0x400d60da:0x3ffbd2c0 0x400d6909:0x3ffbd2e0 0x400d48b4:0x3ffbd300 0x400d4cbc:0x3ffbd320 0x400d285f:0x3ffbd350 0x400d2969:0x3ffbd370 0x400d3561:0x3ffbd3a0 0x400d290d:0x3ffbd3c0 0x400d23a0:0x3ffbd3e0 0x4010c0ff:0x3ffbd400 0x40088441:0x3ffbd430
  #0  0x400d5aed in ppu_renderbg at lib/nofrendo/src/nes/nes_ppu.c:709
  #1  0x400d60da in ppu_renderscanline at lib/nofrendo/src/nes/nes_ppu.c:1033
  #2  0x400d6909 in ppu_scanline at lib/nofrendo/src/nes/nes_ppu.c:1089
  #3  0x400d48b4 in nes_renderframe at lib/nofrendo/src/nes/nes.c:342 (discriminator 1)
  #4  0x400d4cbc in nes_emulate at lib/nofrendo/src/nes/nes.c:434
  #5  0x400d285f in internal_insert at lib/nofrendo/src/nofrendo.c:178
  #6  0x400d2969 in main_loop at lib/nofrendo/src/nofrendo.c:248
  #7  0x400d3561 in osd_main at lib/nofrendo/src/esp32/osd.c:40
  #8  0x400d290d in nofrendo_main at lib/nofrendo/src/nofrendo.c:218
  #9  0x400d23a0 in app_main at src/main.c:215
  #10 0x4010c0ff in main_task at C:\Users\paulo\.platformio\packages\framework-espidf@3.50300.0\components\freertos/app_startup.c:208
  #11 0x40088441 in vPortTaskWrapper at C:\Users\paulo\.platformio\packages\framework-espidf@3.50300.0\components\freertos\FreeRTOS-Kernel\portable\xtensa/port.c:134

ELF file SHA256: 987c77306

Rebooting...
ets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:7176
load:0x40078000,len:15564
ho 0 tail 12 room 4
load:0x40080400,len:4
load:0x40080404,len:3904
entry 0x40080638

In the file /nes_ppu.c:709 on this line, it is called memset(vidbuf, FULLBG, NES_SCREEN_WIDTH); The constant NES_SCREEN_WIDTH has a value of 256.

The FULLBG constant is defined as follows:

#define FULLBG (ppu.palette[0] | BG_TRANS)

Where ppu.palette is uint8 palette[32] and BG_TRANS is #define BG_TRANS 0x80

if (false == ppu.bg_on)
   {
      memset(vidbuf, FULLBG, NES_SCREEN_WIDTH);
      return;
   }

The vidbuf that’s used here seems to be allocated as this variable

which in term is just a malloc.

Meaning, that if you don’t have enough RAM / PSRAM on your board, then allocation of the video buffer would fail and vidbuf would be passed as NULL, leading memset(vidbuf, ..) to crash.

So, the very first thing you should do as add a

printf("VIDEO BUFFER: %p\n", primary_buffer);

after line 373 to check if the allocation has succeeded.

Thanks for your answer!!!

I changed the CONFIG_ESP_MAIN_TASK_STACK_SIZE to 12240 in my sdkconfig. The old value was 3584. The error stopped at that point in the code, however, it appears at another point now. I don’t know if it’s related, but now I’m having the following:

inside nes loop >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
inside nes loop >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
inside nes loop >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
inside nes loop >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
inside nes loop >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> memset vidbuf: 0x3ffc3f14,  FULLBG 128 NES_SCREEN_WIDTH 256 
memset vidbuf: 0x3ffc4014,  FULLBG 128 NES_SCREEN_WIDTH 256
memset vidbuf: 0x3ffc4114,  FULLBG 128 NES_SCREEN_WIDTH 256 
memset vidbuf: 0x3ffc4214,  FULLBG 12Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.

Core  1 register dump:
PC      : 0x4010afb1  PS      : 0x00060330  A0      : 0x800e020f  A1      : 0x3ffd5170  
A2      : 0x00000000  A3      : 0x00000000  A4      : 0x000000df  A5      : 0x000000e0
A6      : 0x00000003  A7      : 0x0000abab  A8      : 0x0000002c  A9      : 0x00000000  
A10     : 0x00000004  A11     : 0x00000028  A12     : 0x00060520  A13     : 0x3ffd5234
A14     : 0x00000001  A15     : 0x3ffbb920  SAR     : 0x0000001b  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x0000002c  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff


Backtrace: 0x4010afae:0x3ffd5170 0x400e020c:0x3ffd5190 0x400d3791:0x3ffd5220 0x40088441:0x3ffd5260
  #0  0x4010afae in calcCrc at lib/nofrendo/src/esp32/spi_lcd.c:641
  #1  0x400e020c in ili9341_write_frame at lib/nofrendo/src/esp32/spi_lcd.c:687
  #2  0x400d3791 in videoTask at lib/nofrendo/src/esp32/video_audio.c:277 (discriminator 1)
  #3  0x40088441 in vPortTaskWrapper at C:\Users\paulo\.platformio\packages\framework-espidf@3.50300.0\components\freertos\FreeRTOS-Kernel\portable\xtensa/port.c:134

And the problematic code is now:

#define ignore_border 4
static int calcCrc(const uint8_t *row)
{
    int crc = 0;
    int tmp;
    for (int i = ignore_border; i < 256 - ignore_border; i++)
    {
        tmp = ((crc >> 8) ^ row[i]) & 0xff; // <<<<<<<<<< here, probably row[i]
        tmp ^= tmp >> 4;
        crc = (crc << 8) ^ (tmp << 12) ^ (tmp << 5) ^ tmp;
        crc &= 0xffff;
    }
    return crc;
}

Now, probably row[i] is pointing to some invalid pointer. And I got lost in the code, it is huge to debug.

Maybe it’s the size of the vidbuf variable, as you mentioned previously. I’ll analyze it more calmly later.