Guru Meditation Error: Core 1 panic'ed (StoreProhibited) (only crashes when function invoked from ISR)

RacerX10
Posts: 4
Joined: Tue Jul 25, 2023 3:20 pm

Guru Meditation Error: Core 1 panic'ed (StoreProhibited) (only crashes when function invoked from ISR)

Postby RacerX10 » Thu Sep 14, 2023 6:17 pm

When I call the function below from an ISR, I'm randomly getting

Guru Meditation Error: Core 1 panic'ed (StoreProhibited)

It might run fine for 30 seconds, or 10 minutes before I get the crash.

When I call it from loop(), it appears to work fine.

I need to call it from my ISR because I'm doing a median filter on some timing values from an external interrupt.

Backtrace info and function are below.

Thank you for any assistance you can offer !


  1. Guru Meditation Error: Core  1 panic'ed (StoreProhibited). Exception was unhandled.
  2.  
  3. Core  1 register dump:
  4. PC      : 0x4008f748  PS      : 0x00060e33  A0      : 0x8008ff32  A1      : 0x3ffb2610
  5. A2      : 0x3ffb8014  A3      : 0x3ffb1408  A4      : 0x3ffc3514  A5      : 0x00060c23  
  6. A6      : 0x00060c20  A7      : 0x00000001  A8      : 0x00000014  A9      : 0x00000000
  7. A10     : 0x3ffb8064  A11     : 0x00000018  A12     : 0xa5a5a5a5  A13     : 0xa5a5a5a5
  8. A14     : 0x3ffb8014  A15     : 0xa5a5a5a4  SAR     : 0x0000001a  EXCCAUSE: 0x0000001d  
  9. EXCVADDR: 0xa5a5a5b1  LBEG    : 0x40086f38  LEND    : 0x40086f43  LCOUNT  : 0x00000000  
  10.  
  11.  
  12. Backtrace: 0x4008f745:0x3ffb2610 0x4008ff2f:0x3ffb2630 0x400901a4:0x3ffb2650 0x40083d16:0x3ffb2670 0x40083d29:0x3ffb26a0 0x40083d56:0x3ffb26c0 0x4009055d:0x3ffb26e0 0x400d7127:0x3ffb2700 0x400d8401:0x3ffb2720 0x400d859a:0x3ffb2780 0x400d198a:0x3ffb27c0 0x400d2285:0x3ffb2800 0x400daf6d:0x3ffb2820
  13.  
  14.   #0  0x4008f745:0x3ffb2610 in remove_free_block at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/heap/heap_tlsf.c:212
  15.       (inlined by) block_locate_free at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/heap/heap_tlsf.c:448
  16.       (inlined by) tlsf_malloc at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/heap/heap_tlsf.c:779
  17.   #1  0x4008ff2f:0x3ffb2630 in multi_heap_malloc_impl at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/heap/multi_heap.c:197
  18.   #2  0x400901a4:0x3ffb2650 in multi_heap_malloc at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/heap/multi_heap_poisoning.c:230
  19.       (inlined by) multi_heap_malloc at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/heap/multi_heap_poisoning.c:219
  20.   #3  0x40083d16:0x3ffb2670 in heap_caps_malloc_base at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/heap/heap_caps.c:154
  21.       (inlined by) heap_caps_malloc_base at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/heap/heap_caps.c:99
  22.   #4  0x40083d29:0x3ffb26a0 in heap_caps_malloc at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/heap/heap_caps.c:174
  23.   #5  0x40083d56:0x3ffb26c0 in heap_caps_malloc_default at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/heap/heap_caps.c:199
  24.   #6  0x4009055d:0x3ffb26e0 in malloc at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/newlib/heap.c:24
  25.   #7  0x400d7127:0x3ffb2700 in TFT_eSPI::loadMetrics() at .pio/libdeps/esp32dev_default_16MB/TFT_eSPI/Extensions/Smooth_font.cpp:173
  26.   #8  0x400d8401:0x3ffb2720 in TFT_eSPI::loadFont(String, bool) at .pio/libdeps/esp32dev_default_16MB/TFT_eSPI/Extensions/Smooth_font.cpp:144
  27.   #9  0x400d859a:0x3ffb2780 in TFT_eSPI::loadFont(unsigned char const*) at .pio/libdeps/esp32dev_default_16MB/TFT_eSPI/Extensions/Smooth_font.cpp:17
  28.   #10 0x400d198a:0x3ffb27c0 in readTach() at src/main.cpp:343
  29.   #11 0x400d2285:0x3ffb2800 in loop() at src/main.cpp:283
  30.   #12 0x400daf6d:0x3ffb2820 in loopTask(void*) at C:/Users/Dave/.platformio/packages/framework-arduinoespressif32/cores/esp32/main.cpp:50





  1. int IRAM_ATTR MedianFilter::in(const int & value)
  2. {
  3.    // sort sizeMap
  4.    // small vaues on the left (-)
  5.    // larger values on the right (+)
  6.  
  7.    boolean dataMoved = false;
  8.    const uint8_t rightEdge = medFilterWin - 1;  // adjusted for zero indexed array
  9.  
  10.    totalSum += value - data[oldestDataPoint];  // add new value and remove oldest value
  11.  
  12.    data[oldestDataPoint] = value;  // store new data in location of oldest data in ring buffer
  13.  
  14.    // SORT LEFT (-) <======(n) (+)
  15.    if(locationMap[oldestDataPoint] > 0) // don't check left neighbours if at the extreme left
  16.    {
  17.       for(uint8_t i = locationMap[oldestDataPoint]; i > 0; i--)   //index through left adjacent data
  18.       {
  19.          uint8_t n = i - 1;   // neighbour location
  20.  
  21.          if(data[oldestDataPoint] < data[sizeMap[n]]) // find insertion point, move old data into position
  22.          {
  23.             sizeMap[i] = sizeMap[n];   // move existing data right so the new data can go left
  24.             locationMap[sizeMap[n]]++;
  25.  
  26.             sizeMap[n] = oldestDataPoint; // assign new data to neighbor position
  27.             locationMap[oldestDataPoint]--;
  28.  
  29.             dataMoved = true;
  30.          }
  31.          else
  32.          {
  33.             break; // stop checking once a smaller value is found on the left
  34.          }
  35.       }
  36.    }
  37.  
  38.    // SORT RIGHT (-) (n)======> (+)
  39.    if(!dataMoved && locationMap[oldestDataPoint] < rightEdge) // don't check right if at right border, or the data has already moved
  40.    {
  41.       for(int i = locationMap[oldestDataPoint]; i < rightEdge; i++)   //index through left adjacent data
  42.       {
  43.          int n = i + 1;   // neighbour location
  44.  
  45.          if(data[oldestDataPoint] > data[sizeMap[n]]) // find insertion point, move old data into position
  46.          {
  47.             sizeMap[i] = sizeMap[n];   // move existing data left so the new data can go right
  48.             locationMap[sizeMap[n]]--;
  49.  
  50.             sizeMap[n] = oldestDataPoint; // assign new data to neighbor position
  51.             locationMap[oldestDataPoint]++;
  52.          }
  53.          else
  54.          {
  55.             break; // stop checking once a smaller value is found on the right
  56.          }
  57.       }
  58.    }
  59.    oldestDataPoint++;       // increment and wrap
  60.    if(oldestDataPoint == medFilterWin) oldestDataPoint = 0;
  61.  
  62.    return data[sizeMap[medDataPointer]];
  63. }

lbernstone
Posts: 831
Joined: Mon Jul 22, 2019 3:20 pm

Re: Guru Meditation Error: Core 1 panic'ed (StoreProhibited) (only crashes when function invoked from ISR)

Postby lbernstone » Fri Sep 15, 2023 4:43 pm

Not enough info to make a good diagnosis. You are either trying to use psram for this allocation (which happens automatically on allocation >4K), or your isr is trying to access heap memory that is simply not available in the context.
The more appropriate way to handle this is to have the ISR drop the needed data into a queue, with a separate process to pull data from the queue, process it, and return the result where it is needed. This can either be triggered by a queue event, a suspended process which gets notified, or in your normal processing loop.

RacerX10
Posts: 4
Joined: Tue Jul 25, 2023 3:20 pm

Re: Guru Meditation Error: Core 1 panic'ed (StoreProhibited) (only crashes when function invoked from ISR)

Postby RacerX10 » Sat Sep 16, 2023 7:54 pm

lbernstone wrote:
Fri Sep 15, 2023 4:43 pm

The more appropriate way to handle this is to have the ISR drop the needed data into a queue, with a separate process to pull data from the queue, process it, and return the result where it is needed. This can either be triggered by a queue event, a suspended process which gets notified, or in your normal processing loop.
My ISR event frequency is around 1ms at the top end. My main loop isn't processing fast enough to service the array and pull out the median value at that rate. That's why I left it all in the ISR, because it's a critical task that has to be handled above all other operations.

I tried a different Median function (just a straight-c function) that I found; it seems to be behaving quite a bit better than the arduino-specific library that I was using here. The total processing time on the ISR is generally under 5us so I wasn't too worried about it all being in the ISR. I might be wrong on that, however. I am still getting the occasional div by zero crash, but that's a much easier problem to track down than arcane memory allocation issues :)

Thanks !

Who is online

Users browsing this forum: No registered users and 48 guests