Esp8266: section `.text' will not fit in region `iram1_0_seg'

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 :confused:

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