Support ESP32-S3 - Heap corruption after migration from ESP32-S2

I have an application which runs an edge-impulse model on an ESP32-S2 (IDF-version v5.0-rc1). I expect that this would also work on an ESP32-S3-WROOM-1 N8R8, but it doesn’t. (completely the same application)

In an attempt to mitigate this, I upgraded to the latest ESP-IDF v5.1 and downloaded the C++ library again from the edge impulse website, but the same error occurs.

The error I get is a corrupted heap when calling “run_classifier()”. Not always, but most of the time…

I (5263) analyser: Trying to take mutex for InferencingTask...
I (5683) analyser: Running classifier...
I (5683) analyser: heap integrety 1
I (5683) analyser: FreeHeapSize: 159276
I (5693) analyser: Bytes free in stack: 5580
I (6043) analyser: Inference results off/on: 1.00/0.00
I (6043) analyser: Entering InferencingTask FOR-loop...
I (6043) analyser: Trying to take mutex for InferencingTask...
I (6053) analyser: Running classifier...
I (6053) analyser: heap integrety 1
I (6063) analyser: FreeHeapSize: 159012
I (6063) analyser: Bytes free in stack: 5372
CORRUPT HEAP: Bad head at 0x3fcd1954. Expected 0xabba1234 got 0x0018fff3

assert failed: multi_heap_free multi_heap_poisoning.c:276 (head != NULL)

Is this a known issue?

Any pointers/ideas are very welcome :slight_smile:

Some details:

  • ESP-IDF V5.1
  • C++ library implementation
  • Interference is running in a FreeRTOS task (as it is with the ESP32-S2)

I had following section in my CMakeList:

if(NOT CMAKE_BUILD_EARLY_EXPANSION)
add_definitions(-DEI_CLASSIFIER_TFLITE_ENABLE_ESP_NN=1) # enables ESP-NN optimizations by Espressif
endif()

Replacing this by:

if(NOT CMAKE_BUILD_EARLY_EXPANSION)
add_definitions(-DEI_CLASSIFIER_TFLITE_ENABLE_ESP_NN=0)  
endif()

Fixed the issue, not completely sure why though…

The original post shows heap problems at runtime so the program is consuming to much RAM and crashes. Setting -DEI_CLASSIFIER_TFLITE_ENABLE_ESP_NN=0 forces the compiler to include generic NN optimizations that appear to be smaller in code size than when setting -DEI_CLASSIFIER_TFLITE_ENABLE_ESP_NN=1.

You can try these commands to see what is happening on the heap:

  • ESP.getFreeHeap()
  • ESP.getMinFreeHeap()
  • ESP.getHeapSize()
  • ESP.getMaxAllocHeap()

The ESP object is documented here.

Hi MMarcial,
Thank you for your reply. This is also something that came to mind and I tried to expand the memory allocated for the FreeRTOS task multiple times, but nothing changed.

I’ve also added logging before calling the crashing function (which is config->model_reset), but it always indicated enough free heap in my opinion, for example:

Heap integrety 1
FreeHeapSize: 142416
CORRUPT HEAP: Bad head at 0x3fcd3c80. Expected 0xabba1234 got 0xfffeffab

If it was a RAM issue, shouldn’t the same code on the ESP32-S2 (which has less RAM) also crash?

A big difference between ESP32-S2 and ESP32-S3 is that the ESP32-S2 is single core and the ESP32-S3 is dual core. But I would suspect that if I pin the task to a single core, this shouldn’t matter (but I’m no expert here).