Meaning of ICACHE_FLASH_ATTR

geo.espressif
Posts: 28
Joined: Tue Mar 31, 2015 7:27 pm

Meaning of ICACHE_FLASH_ATTR

Postby geo.espressif » Fri Oct 02, 2015 4:55 pm

Could someone point me in the direction of where 'ICACHE_FLASH_ATTR' is described in the documentation please? I can't find it in either the SDK or HDK user guides.

eriksl
Posts: 159
Joined: Fri May 22, 2015 6:22 pm

Re: Meaning of ICACHE_FLASH_ATTR

Postby eriksl » Fri Oct 02, 2015 5:32 pm

You are completely right. It's a shame this #define is never explained, as is the whole concept behind it, which the community how has had to guess. For one it's still not 100% sure if the esp does any instruction caching and if the upper 32k iram (if it even exists) is used for that. I am not talking about the execution of code in iram (lower 32k iram), which the above macro refers to.

geo.espressif
Posts: 28
Joined: Tue Mar 31, 2015 7:27 pm

Re: Meaning of ICACHE_FLASH_ATTR

Postby geo.espressif » Fri Oct 02, 2015 5:41 pm

That's disappointing, never mind.

Any rough ideas? I have no idea and I've been using it roughly at random. Something to do with the memory the function is compiled to / speed of calling?

eriksl
Posts: 159
Joined: Fri May 22, 2015 6:22 pm

Re: Meaning of ICACHE_FLASH_ATTR

Postby eriksl » Fri Oct 02, 2015 5:55 pm

It has been explained here and there, but never explicitly, so I'll take the shot on doing it simple & good (one time).

The esp8266 has 32k (maybe 64k, that's not completely clear) of IRAM. That means RAM for instructions, code. This is different from the ~80k of DRAM (which means data ram, not dynamic ram, it's all dynamic ram, the iram too). One cannot be use for the other and v.v.

Programs are stored in the flash memory and due to the fast interface (SPI-quad) instructions can be fetched and executed "in place", in other words, without copying them to ram first. In some occasions you cannot execute your code from SPI flash memory directly, mostly because it needs to be maximum fast or because it handles the flash memory itself (e.g. writing to it). In that case, you can have some code, 32k in total, have copied from the flash at startup, to the IRAM. This code will run from IRAM, not from FLASH.

The forementioned #define, which has an ugly, completely wrong name, if applied to a function, takes care that the function is output to the .irom0_text section, which tells the linker to put the function in FLASH memory segment. The default is to output to .text segment which will put the function into the IRAM segment.

A lot of the SDK-code, which you must link to your firmware to have it working, also output their code to the IRAM segment. So there is actually not a lot left, from the 32k for your own application, about 2k, maybe 3k. So use it very sparingly. Also many functions if not all, from libc, are placed into the IRAM segment. So it is very easy to run out of IRAM space. Even though you may have 512k or even 4m of FLASH memory (depening on the chip used). I had to reimplement some functions from libc in my own code, simply because they take up too much space in IRAM.

So always, unless impossible, add this #define to all of your functions.

I think that should cover most of it.

User avatar
kolban
Posts: 131
Joined: Tue Jun 16, 2015 1:09 pm
Location: Fort Worth, Texas, USA

Re: Meaning of ICACHE_FLASH_ATTR

Postby kolban » Fri Oct 02, 2015 8:38 pm

@eriksl ... I think you have posted a VITAL report here. This should be a blog post somewhere as opposed to a forum post that might get lost :-(

One technique I have seen used is to not include the ICACHE_FLASH_ATTR modification of each of the source functions ... but instead, when the compilation of a .c to a .o has completed, rename the .text section to be .irom0.text

For example ...:

objcopy --rename-section .text=.irom0.text --rename-section .literal=.irom0.literal myObjectFile.o

Do you have any thoughts on the wisdom of that notion?

Neil

geo.espressif
Posts: 28
Joined: Tue Mar 31, 2015 7:27 pm

Re: Meaning of ICACHE_FLASH_ATTR

Postby geo.espressif » Fri Oct 02, 2015 8:40 pm

That's a great response and very helpful, thanks eriksl.

eriksl
Posts: 159
Joined: Fri May 22, 2015 6:22 pm

Re: Meaning of ICACHE_FLASH_ATTR

Postby eriksl » Fri Oct 02, 2015 8:54 pm

Neil, that's also a good method. Doesn't work for me though, because I always have a few functions that need to be in IRAM.

This is what I did: forget about the whole ICACHE_FLASH_ATTR thing and #define my own, similar replacement, with the simple name "irom" which exactly describes what it does and also is so much easier to type.

The other way around, default everything in IROM and only exceptions in IRAM would be even better, but I appreciate that that is not possible because then you would need to scan ALL library sources (including libc) for functions that possibly might need to end up in IRAM. This decision is non-trivial, it depends on what code calls the function.

dkinzer
Posts: 52
Joined: Fri Jul 31, 2015 7:37 am

Re: Meaning of ICACHE_FLASH_ATTR

Postby dkinzer » Fri Oct 02, 2015 10:41 pm

eriksl wrote:Neil, that's also a good method. Doesn't work for me though, because I always have a few functions that need to be in IRAM.
For those few functions that need to be in IRAM (e.g. interrupt service handlers), use a different attribute that puts them in the .iram0 section.

Code: Select all

#define IRAM0     __attribute__((section(".iram0.text")))
void IRAM0 myISR(void)
{
}
Since this function will be in .iram0.text it won't be among those whose section name is modified by

Code: Select all

objcopy --rename-section .text=.irom0.text --rename-section .literal=.irom0.literal myObjectFile.o


It should also be noted how the SDK include files define ICACHE_FLASH_ATTR (in c_types.h):

Code: Select all

#ifdef ICACHE_FLASH
#define ICACHE_FLASH_ATTR __attribute__((section(".irom0.text")))
#define ICACHE_RODATA_ATTR __attribute__((section(".irom.text")))
#else
#define ICACHE_FLASH_ATTR
#define ICACHE_RODATA_ATTR
#endif /* ICACHE_FLASH */
This means that even if you adorn your functions with ICACHE_FLASH_ATTR, they will still not be in .irom0.text unless ICACHE_FLASH is defined when the files are compiled. This is usually accomplished by using -DICACHE_FLASH on the compiler command line.

Another useful technique can be found in the ESP8266-Arduino linker script. 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

Note, particularly, the fourth and seventh lines. The fourth line causes all of the core esp8266/Arduino code .literal and .text sections to be put in .irom0.text. This accomplishes exactly the same purpose as does using objcopy to rename the sections. (The fifth line does the same for SPIFFS code.) The seventh line causes all .literal and .text sections in the libm.a to be put in .irom0.text. This works around a problem where using sqrt() in an application would cause the cache RAM size to be exceeded.
Don Kinzer
Beaverton, OR, USA

eriksl
Posts: 159
Joined: Fri May 22, 2015 6:22 pm

Re: Meaning of ICACHE_FLASH_ATTR

Postby eriksl » Fri Oct 02, 2015 11:19 pm

This is a dangerous technique. You never know what IRAM-bound functions (including in the SDK!) call these functions and cause unexpected crashes. I've been there... If you want sqrt in your program, the best option imho still is to write/copy your version and include it in your program, in IROM.

dkinzer
Posts: 52
Joined: Fri Jul 31, 2015 7:37 am

Re: Meaning of ICACHE_FLASH_ATTR

Postby dkinzer » Sat Oct 03, 2015 5:54 am

eriksl wrote:You never know what IRAM-bound functions (including in the SDK!) call these functions and cause unexpected crashes. I've been there.
What were the circumstances? What ISR and what function(s)?
Don Kinzer
Beaverton, OR, USA

Who is online

Users browsing this forum: No registered users and 284 guests