Description
Platform
- Hardware: ESP8285
- Core Version: framework-arduinoespressif8266 3.20704.0 (2.7.4)
- Development Env: Platformio
- Operating System: MacOS
- Module: Wemos D1 mini r2
Problem Description
Hi,
I'm trying to use interruptions in a class and use std::bind(&...::..., this)
for this purpose.
Unfortunately, when I try to access to the flash using LittleFS, the ESP crashes:
Exception (0):
epc1=0x40209474 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
Here is the decoded stack trace:
0x401005e9: interrupt_handler at ??:?
0x40100528: interrupt_handler at ??:?
0x401059f8: Cache_Read_Enable_2 at ??:?
0x40105fc1: spi_flash_read at ??:?
0x4010243b: rcReachRetryLimit at ??:?
0x4010261c: rcReachRetryLimit at ??:?
0x40102ade: wDev_ProcessFiq at ??:?
0x40105fbc: spi_flash_read at ??:?
0x40100fa1: __wrap_spi_flash_read at ??:?
0x40208f0d: EspClass::flashRead(unsigned int, unsigned int*, unsigned int) at ??:?
0x402081c4: flash_hal_read(unsigned int, unsigned int, unsigned char*) at ??:?
0x40102b18: wDev_ProcessFiq at ??:?
0x402057be: littlefs_impl::LittleFSImpl::lfs_flash_read(lfs_config const*, unsigned int, unsigned int, void*, unsigned int) at ??:?
0x4020132c: lfs_bd_read$isra$12 at lfs.c:?
0x4020130c: lfs_bd_read$isra$12 at lfs.c:?
0x402014c2: lfs_dir_fetchmatch at lfs.c:?
0x40100601: interrupt_handler at ??:?
0x40201e0a: lfs_dir_find at lfs.c:?
0x40202ae0: lfs_dir_find_match at lfs.c:?
0x40204a18: lfs_file_opencfg at ??:?
0x4020c1b4: _strdup_r at /home/earle/src/esp-quick-toolchain/repo/newlib/newlib/libc/string/strdup_r.c:11
0x40100ce6: malloc at ??:?
0x40100a27: umm_free_core at umm_malloc.cpp:?
0x40204c50: lfs_file_open at ??:?
0x402062ff: littlefs_impl::LittleFSImpl::open(char const*, fs::OpenMode, fs::AccessMode) at ??:?
0x40201c90: lfs_dir_getgstate at lfs.c:?
0x4020530b: std::_Function_base::_Base_manager<std::_Bind<std::_Mem_fn<void (Sandbox::*)()> (Sandbox*)> >::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) at ??:?
0x402069a8: fs::FS::open(char const*, char const*) at ??:?
0x40100100: interruptFunctional(void*) at ??:?
0x40100caf: free at ??:?
0x4020fddd: operator delete(void*) at /workdir/repo/gcc/libstdc++-v3/libsupc++/del_op.cc:48
0x40205401: loop at ??:?
0x40205384: Sandbox::init() at ??:?
0x4010048d: digitalWrite at ??:?
0x402053d8: setup at ??:?
0x4020773c: loop_wrapper() at core_esp8266_main.cpp:?
0x401002e5: cont_wrapper at ??:?
Here is a MCVE:
#include "Arduino.h"
#include <LittleFS.h>
#include <FunctionalInterrupt.h>
// ---------
class Sandbox {
public:
void init();
private:
void ICACHE_RAM_ATTR interruptHandler();
};
// ---------
void Sandbox::init() {
// Note: use a pin where there is a lot data (I have 8000 changes/second)
pinMode(D7, INPUT);
attachInterrupt(D7, std::bind(&Sandbox::interruptHandler, this), CHANGE);
}
void ICACHE_RAM_ATTR Sandbox::interruptHandler() {
}
// ---------
Sandbox sandbox;
void setup() {
Serial.begin(74880);
LittleFS.begin();
sandbox.init();
}
void loop() {
// noInterrupts();
File fd = LittleFS.open("/test", "w");
fd.close();
// interrupts();
delay(1000);
}
Note that it happens when I have some interruptions (8000/seconds in my case but it should crashed with less I suppose).
When I suspend interrupts during the FS access, the ESP doesn't crash.
When I declare interruptHandler
as static and don't use std::bind
it works too (but I'll have to declare all my variables as static which I would like to avoid).
I tried a lot of things to find a solution but nothing worked and I would like to avoid to use a plain classical function as a callback to attachInterrupt
.
If you have any idea... 🙏