My project builds fine with espressif8266 1.5.0. I tried using version 1.6.0 up to 2.0.4, but then I get this iram error. My guess is that starting with 1.6.0 all functions go to iram by default. When I use ICACHE_FLASH_ATTR for all my functions, it is linking without errors. But when I start using external libraries, these functions go to iram again.
Any ideas how to solve this / make functions go to flash by default?
I boiled my code down to a very simple test project:
platform.ini:
[env:nodemcuv2]
platform = espressif8266@1.5.0
board = nodemcuv2
framework = arduino
build_flags =
-DVTABLES_IN_FLASH
log.h
#ifndef LOG_H
#define LOG_H
#include <Arduino.h>
void logI(String msg, bool newLine = true);
#endif /* end of include guard: */
log.cc
#include "log.h"
void logI(String msg, bool newLine) {}
main.cc
#include <Arduino.h>
#include "log.h"
void test() {
// copy the following line 260 times to generate some code
logI(F("failed to mount FS."));
}
void setup() { test(); }
void loop() {}
Try adding the appropriate VTABLES option to your build_flags
… you probably want -DVTABLES_IN_FLASH
… although unless the docs are out of date it is the default …
The used linker script should decide in which region (IRAM or flash) some function code should be placed. But looking into .platformio\packages\framework-arduinoespressif8266\tools\sdk\ld\eagle.app.v6.common.ld.h
didn’t really make me smarter.
@pfeerick C++ virtual function tables are small compared to the classes’ actual code, so placing only them in flash only makes a small difference with the code still being in IRAM
1 Like
I tried adding “-DVTABLES_IN_FLASH”, but this did not help.
The different platform versions of espressif8266 seem to depend on different versions of framework-arduinoespressif8266 in .platformio\packages. The linker scripts differ. Right now I don’t understand what is going on there. But thanks for the hint in this direction.
I tried to use the 1.5.0 linker script using “-Wl,-Txxx.ld”. Again using espressif8266@1.5.0 the project builds fine. Using higher versions, I get the iram error. The default still seems to put the code to iram instead of flash. I boiled my project down to a very simple test project and edited the original post.
So finally I found the solution: The linker script is tries to put *.c.o and *.cpp.o to flash. However my files are .cc files. So if I either rename all my files or add a line to the linker script matching *.cc.o, then it works.
2 Likes