Reputation: 1
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
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