如何解决ESP32 与多个 I2C 设备偶尔崩溃,堆问题?
我有一个 ESP32(M5Stack Core Grey),它通过 I2C 连接到 PMIC(带有 I2C 寄存器的定制 IP5306)和加速度计 (MPU9250)。两个库大部分时间同时独立工作。有时,我会遇到 2 个错误之一,我怀疑这是我尝试调用这两个设备的代码中的某种类型的冲突:
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
然后有时我会得到以下信息:
assertion "head != NULL" failed: file "/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/multi_heap_poisoning.c",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,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*) 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
这两个错误看起来很相似,但它们是从不同的地方调用的。我已将 PMIC 和 IMU 读取放在单独的 FreeRTOS 任务中。我是否需要确保在每次 I2C 读取之前获取一个信号量并在完成后将其返回?我已经把它放在我显式读取值的代码中,但可能遗漏了一些地方。大多数 M5Stack 代码一次仅演示一个模块,因此当您组合多个传感器时,我不确定最佳实践。非常感谢任何指导。
解决方法
您需要使用互斥锁来访问来自不同任务的硬件。
//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.
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。