Discuss here different C compiler set ups, and compiling executables for the ESP8266

User avatar
By lfaustini
#28617 Hello,
I am using the Ardiono IDE to directly cross-compile
code to the ESP8266. I am having trouble as I have run
out of memory. I am looking at the error and thinking
that the code I have written has over-filled the internal
instruction-ram of the xtensa CPU.

I get the error '.text' will not fit in region 'iram1_0_seg'

(in successful compilation just before I added the code
to cause this error I was being told that the sketch was
using 34% of the available program space - so clearly
this is not an out of flash memory issue)

Now, as I understand it, the ESP's 32 bit CPU can run
code out of its internal ram (which is parallel and fast)
or it can be told to run code out of the much slower, but
much larger, serial flash chip that is on the board - right?

I see a lot of compiler directives in the example code
that people have written that use the GCC command line
route. directives like

LOCAL void ICACHE_FLASH_ATTR some_function(int a, char*c)


I assume these directives tell the linker to put the code in
a place where it is run the serial-flash, and not the precious
and fast on-chip ram?

Is there a list of compiler directives and their associated purposes?
Do these compiler directives work in the Arduino IDE?

Thank you.
User avatar
By dkinzer
#28663
lfaustini wrote:Is there a list of compiler directives and their associated purposes?
ICACHE_FLASH_ATTR is not a compiler directive. If you look in the SDK include files you'll find that it is defined thus:
Code: Select all#define ICACHE_FLASH_ATTR __attribute__((section(".irom0.text")))
However, that definition is surrounded by a conditional so that it isn't seen unless ICACHE_FLASH is also defined.

A description of the section attribute can be found in the standard gcc documentation but the basic idea is that ICACHE_FLASH_ATTR causes the function with which it is associated to be placed in the .irom0.text section. The linker script then places everything in that section in the Flash area.

If you're building your app with the Arduino IDE, turn on verbose mode so you can see the compile/link options and also look at the linker script that is used. Together, that should be enough information to determine why you're overflowing irom_1_seg.

I don't build my apps using the Arduino IDE. Instead. I use my own makefile that I've pieced together from several sources. One thing that I added was an additional command after compiling to rename the .text and .literal.text sections in the resulting .o file to .irom0.text and .irom0.literal.text. That way, I don't have to adorn functions with ICACHE_FLASH_ATTR nor compile with ICACHE_FLASH defined. If you do this, you also need to pay special attention to any interrupt service routines that you may have - you'll want to explicitly give those the __attribute__((section(".iram0.text"))) attribute so that they end up in iram_0_seg where they belong.
User avatar
By lfaustini
#29035 Ok,
I spent some (allot) of time using objdump on my various .o files,
and I now see what is going on -- but let me back up a bit.

I stated adding / using the ICACHE_FLASH_ATTR directive in
all of my functions, and used objdump on my .o files. I noted
that when I used the directive ICACHE_FLASH_ATTR the function
that followed was put in the .irom0.text section of the .o file, and
(more importantly) if I did not use that directive my code would
end up in the .text section (not .irom0.text) so, I -- think-- my code is
going to be put into the flash by the linker - which is where I want it.

BUT.... When I add just one more sprintf() on a line in my code
it breaks blows up saying it cant fit .text into section 'iram1_0_seg'

So i started to objdump the other .o files, and the first one I
looked at is WString.cpp.o - and guess what? it is entirely
compiled to in the .text section. Since I am in no hurry with
my string functions, how can I push the WString.cpp.o into
the .irom0.text section?


Any ideas?

Thanks!

---Lou
User avatar
By dkinzer
#30480
lfaustini wrote:how can I push the WString.cpp.o into the .irom0.text section?
I believe that ESP8266-Arduino IDE uses a special linker script that puts many functions that are marked for the .text section into .irom0.text. The excerpt below comes from esp8266/Arduino on GitHub:
Code: Select all  .irom0.text : ALIGN(4)
  {
    _irom0_text_start = ABSOLUTE(.);
    *core_esp8266_*.o(.literal*, .text*)
    *spiffs*.o(.literal*, .text*)
    *.cpp.o(.literal*, .text*)
    *libm.a:(.literal .text .literal.* .text.*)
    *libsmartconfig.a:(.literal .text .literal.* .text.*)
    *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
    _irom0_text_end = ABSOLUTE(.);
    _flash_code_end = ABSOLUTE(.);
  } >irom0_0_seg :irom0_0_phdr
In particular, note the fourth through seventh lines of the excerpt.