Quan Gan
Quan Gan

Reputation: 1

ESP32 sporadically crashing with multiple I2C devices, heap issue?

I have an ESP32 (M5Stack Core Grey) that is connected to a PMIC (custom IP5306 with I2C registers) and Accelerometer (MPU9250) via I2C. Both libraries work independently MOST of the time concurrently. Occasionally, I'd get one of 2 errors and I suspect it's some type of conflict in my code trying to call these two devices:

assertion "head != NULL" failed: file "/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/multi_heap_poisoning.c", line 245, function: multi_heap_realloc
Decoding stack results
0x4008d774: invoke_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 155
0x4008d9a5: abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 170
0x400ec7ef: __assert_func at ../../../.././newlib/libc/stdlib/assert.c line 63
0x4008d401: multi_heap_free at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/multi_heap_poisoning.c line 214
0x40085456: heap_caps_free at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/heap_caps.c line 268
0x40085c2d: _free_r at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib/syscalls.c line 42
0x400e24fb: i2cFlush at C:\users\quan\.platformio\packages\framework-arduinoespressif32\cores\esp32\esp32-hal-i2c.c line 1604
0x400e2e0c: i2cRead at C:\users\quan\.platformio\packages\framework-arduinoespressif32\cores\esp32\esp32-hal-i2c.c line 1649
0x400dc025: TwoWire::readTransmission(unsigned short, unsigned char*, unsigned short, bool, unsigned int*) at C:\users\quan\.platformio\packages\framework-arduinoespressif32\libraries\Wire\src\Wire.cpp line 139
0x400dc0d9: TwoWire::requestFrom(unsigned short, unsigned char, bool) at C:\users\quan\.platformio\packages\framework-arduinoespressif32\libraries\Wire\src\Wire.cpp line 193
0x400dc155: TwoWire::requestFrom(int, int) at C:\users\quan\.platformio\packages\framework-arduinoespressif32\libraries\Wire\src\Wire.cpp line 296
0x400dafcc: getBatteryGauge() at src\myPower.cpp line 16
0x400daff8: powerLoop(void*) at src\myPower.cpp line 37
0x40089eb1: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143

And then sometimes I'll get the following:

assertion "head != NULL" failed: file "/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/multi_heap_poisoning.c", line 245, function: multi_heap_realloc
Decoding stack results
0x4008d774: invoke_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 155
0x4008d9a5: abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 170
0x400ec7eb: __assert_func at ../../../.././newlib/libc/stdlib/assert.c line 59
0x4008d459: multi_heap_realloc at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/multi_heap_poisoning.c line 245
0x400854c6: heap_caps_realloc at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/heap_caps.c line 297
0x4008552a: heap_caps_realloc_default at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/heap_caps.c line 163
0x40085c3d: _realloc_r at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib/syscalls.c line 47
0x400e22ca: i2cAddQueue at C:\users\quan\.platformio\packages\framework-arduinoespressif32\cores\esp32\esp32-hal-i2c.c line 1057
0x400e234f: i2cAddQueueWrite at C:\users\quan\.platformio\packages\framework-arduinoespressif32\cores\esp32\esp32-hal-i2c.c line 1081
0x400e2d4c: i2cWrite at C:\users\quan\.platformio\packages\framework-arduinoespressif32\cores\esp32\esp32-hal-i2c.c line 1617
0x400dc001: TwoWire::writeTransmission(unsigned short, unsigned char*, unsigned short, bool) at C:\users\quan\.platformio\packages\framework-arduinoespressif32\libraries\Wire\src\Wire.cpp line 133
0x400dc055: TwoWire::endTransmission(bool) at C:\users\quan\.platformio\packages\framework-arduinoespressif32\libraries\Wire\src\Wire.cpp line 158
0x400dc558: CommUtil::readByte(unsigned char, unsigned char, unsigned char*) at C:\users\quan\.platformio\lib\M5Stack_ID1851\src\utility\CommUtil.cpp line 98
0x400dfcf6: MPU9250::readByte(unsigned char, unsigned char) at C:\users\quan\.platformio\lib\M5Stack_ID1851\src\utility\MPU9250.cpp line 438
0x400d1bce: readIMU(void*) at src\accelerometer.cpp line 75
0x40089eb1: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143

Both errors look similar but they're being called from different places. I've put the PMIC and IMU reads in separate FreeRTOS tasks. Do I need to make sure I take a semaphore before each I2C read and give it back after complete? I have put it in the code where I explicitly read the values but may have left out some places. Most of the M5Stack code only demonstrates one module at a time so I'm not sure of best-practice when you combine multiple sensors. Any guidance is much appreciated.

Upvotes: 0

Views: 824

Answers (1)

Yağızhan UĞUR
Yağızhan UĞUR

Reputation: 11

You need to use mutex for access hardware from different tasks.

  //GLOBAL
  SemaphoreHandle_t xI2CSemaphore;            //Shared I2C Resource Mutex
  
  //PROGRAM SETUP
  if ( xI2CSemaphore == NULL )
  {
    xI2CSemaphore = xSemaphoreCreateMutex();
    if ( ( xI2CSemaphore ) != NULL )
      xSemaphoreGive( ( xI2CSemaphore ) );
  }



 //WHEN USING IN A TASK...
 if ( xSemaphoreTake( xI2CSemaphore, ( TickType_t ) 250 ) == pdTRUE )
 {

 xSemaphoreGive( xI2CSemaphore ); // Now free or "Give" the Serial Port for others.
 }

Upvotes: 1

Related Questions