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

User avatar
By someother
#44100 Hello folks!
Excuse me for posting a new topic for this well-known problem, but I couldn’t solve my problem even if I read most of the previous posts about the case.

Here is what I know and what I’ve tried until now:
1. ESP8266 has 32KB of instruction RAM and it couldn’t be increased just by modifying the linker script (I have had some MCUs with 16KB of RAM for example, but actually they did have 32KB, so I was able to modify the memory regions w/o problem).
2. ICACHE_FLASH_ATTR will decrease RAM memory used by functions. (I’ve used it almost everywhere in my code).
3. –Os will optimize for size.
4. -ffunction-sections and -Wl,--gc-sections will decrease the memory usage too (I am using that and it works very well! Thanks to the guy that posted this info!). viewtopic.php?f=9&t=3272&start=16
5. Modifying the linker script some libs could be moved to ROM, but attention should be paid to exclude libraries with interrupt driven functions inside (libpp occupies most of the memory, but it isn’t a good idea to move it. The same applies for libgcc, libmain (and what else?). liblwip and libphy are good to move to ROM. (viewtopic.php?f=9&t=3796&start=4).

Since I’ve tried almost everything from the above mentioned, could you have a look over my compiler flags and linker script (because I think I’m missing something) and of course if you have some other ideas on how to decrease the iram1 consumption, please feel free to give me an advice!

Code: Select allCFLAGS = -I. -mlongcalls -ffunction-sections
LDLIBS = -nostdlib -Wl,--start-group -lmain -lnet80211 -lwpa -llwip -lpp -lphy -Wl,--end-group -lgcc –lcirom
LDFLAGS = -DICACHE_FLASH -Tlinker.ld -Wl,--gc-sections -Wl,-Map=output.map -Wl,--cref



Just to try it out, I’ve added the following line to .irom0.text : ALIGN(4) section

Code: Select all*libgcc.a:(.literal .text .literal*, .text*)


But it doesn’t make any difference. The section is again overflowed by the same size.

Possibly you’ll notice that I’m missing the –Os flag, but it doesn’t give me too much additional memory. I would like to secure another 1-2KB of iram1 because I have to write some additional functions. Currently I’ve added and I’m using successfully the SPI driver, UART driver and nRF24 driver that I’m porting.

Thanks!
User avatar
By someother
#44132 Okay, It seems that I've made a mistake (I'm new to Makefiles and linker scripts).

First I'll explain how I caught the problem.

Analyzing the map file I noticed that all my functions go to iram1
Code: Select alliram1_0_seg      0x0000000040100000 0x0000000000008000


The line
Code: Select all.text           0x0000000040100000     0x6ac8

in the same (ex. output.map) file shows the size reserved for the iram1 section, in this case 27336 bytes (hex 0x6ac8). If you scroll down you'll see how much memory each functions uses.

Keep in mind that you'll see here functions that do NOT have ICACHE_FLASH_ATTR.

Code: Select all .text          0x0000000040100178      0x5b6 /opt/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/sysroot/usr/lib/libmain.a(app_main.o)
                                        0x616 (size before relaxing)
                0x00000000401001b0                Cache_Read_Enable_New
                0x00000000401001ec                NmiTimSetFunc
                0x0000000040100214                NMI_Handler
                0x000000004010026c                call_user_start_local
                0x00000000401003cc                wdt_feed
 *fill*         0x000000004010072e        0x2


Okay, I am not sure how to check the memory usage for the function itself, but you get the idea.
The functions' addresses are the same as in the output file
Code: Select all$ nm GCC/Exe/nrf24bridge | grep NMI_Handler
40100214 T NMI_Handler


(Please make sure that you're observing the latest output.map file, because I've changed the names and I was observing an older file. It took me few hours to notice that, therefore I say that the addresses from the map file and the output file should be the same :)).

If you continue scrolling down you'll see the section irom0, starting at address 0x40240000.
There should be all ICACHE_FLASH_ATTR functions.

And if you're curious what I've missed, it is the -DICACHE_FLASH option, that goes to CFLAGS at compile time, and not to LDFLAGS at link time!

Here are the corected flags:
Code: Select allCFLAGS = -I. -mlongcalls -ffunction-sections -Os
LDLIBS = -nostdlib -Wl,--start-group -lmain -lnet80211 -lwpa -llwip -lpp -lphy -Wl,--end-group -lgcc -lcirom
LDFLAGS = -T linker.ld -g -O2 -Wl,-EL -mtext-section-literals -mlongcalls -Wl,--gc-sections -Wl,--cref -Wl,-Map=output.map -Wl,-N


Whew!
User avatar
By cnlohr
#44664 Don't forget -flto!!!

-rw-r--r-- 1 cnlohr cnlohr 37200 Apr 2 03:31 0x00000.bin
-rw-r--r-- 1 cnlohr cnlohr 204067 Apr 2 03:31 0x40000.bin

to

-rw-r--r-- 1 cnlohr cnlohr 36672 Apr 2 03:31 0x00000.bin
-rw-r--r-- 1 cnlohr cnlohr 202531 Apr 2 03:31 0x40000.bin

with that, alone!
User avatar
By eriksl
#50950 I did some experimenting with flto just now and I didn't get very excited.

I added -flto to both compiler and linker invocations (as is suggested) and added -fuser-linker-plugin as well. The linking stage become very very slow (20 seconds compared to the usual 1 second) and the code size in the IRAM segment only increased, both with -Os and -O3.

So I guess your mileage may vary. I'll leave it out.