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

User avatar
By tve
#38991 Looks at stats.c:
Code: Select allstatic const char *flash_map[] =
{
       "4 Mb map 256/256",
       "2 Mb no map",
       "8 Mb map 512/512",
       "16 Mb map 512/512",
       "32 Mb map 512/512",
       "16 Mb map 1024/1024",
       "32 Mb map 1024/1024",
       "unknown map",
       "unknown",
};

and then:
Code: Select all$ xtensa-lx106-elf-objdump -j .rodata.str1.4 -s stats.o | tail -15
 0350 00000000 68617264 77617265 20776174  ....hardware wat
 0360 6368646f 67000000 65786365 7074696f  chdog...exceptio
 0370 6e000000 736f6674 77617265 20776174  n...software wat
 0380 6368646f 67000000 75736572 20726573  chdog...user res
 0390 65740000 64656570 20736c65 65702061  et..deep sleep a
 03a0 77616b65 00000000 34204d62 206d6170  wake....4 Mb map
 03b0 20323536 2f323536 00000000 32204d62   256/256....2 Mb
 03c0 206e6f20 6d617000 38204d62 206d6170   no map.8 Mb map
 03d0 20353132 2f353132 00000000 3136204d   512/512....16 M
 03e0 62206d61 70203531 322f3531 32000000  b map 512/512...
 03f0 3332204d 62206d61 70203531 322f3531  32 Mb map 512/51
 0400 32000000 3136204d 62206d61 70203130  2...16 Mb map 10
 0410 32342f31 30323400 3332204d 62206d61  24/1024.32 Mb ma
 0420 70203130 32342f31 30323400 756e6b6e  p 1024/1024.unkn
 0430 6f776e20 6d617000                    own map.

These strings are going straight into .rodata
User avatar
By eriksl
#39006 And rodata goes to dram0, as checked with the linker script, point taken.

Actually it's ridiculous. The esp8266 isn't a strict Harvard chip like an ATmega, the SPI flash can be used for storing both code and data. So the only thing that's holding us back is the strict alignment requirements, of 32 bits. So if one could take care of strings and other read-only data to always be aligned to 32 bits, there would, imho no reason to leave them in flash, right? Can't gcc be instructed to do so?

I am not really waiting for constructions like we know from ATmega, where you have ugly #defines to read from "prog_mem" that compile into special machine code, so you never get generic pointers to them.
User avatar
By eriksl
#39032 I just realise some things, because I have had a look at this before (long time ago).

- 4 byte alignment by the compiler won't do because strings are typically iterated over byte by byte
- you can't use the irom0_text section for storing data, because the linker won't allow it to be used for data
- but afaics you can create an additional section and store that in a segment following the irom segment and then it shouldn't (?) end up in the part of the flash that gets copied on start
- the guys from nodemcu have found a workaround for all of this, I believe they catch the "not aligned" trap, emulate the command in software and then return to the instruction after the one that caused it; smart but slow and complex

I have thought of a few ways to do the same, less complex but also less efficient:

- create a set of *_P functions just like ATmel does, that take a string from flash instead of out of dram
- make a function that temporarily "ramifies" a pointer to a string in flash

Using the latter it may be necessary to implement something with multiple slots, so more than one string can be manipulated at the same time. That way you have access to them in ram, but at least not all of them at once, so only a limited amount of ram is used.

Just my $0.02 ;)
User avatar
By martinayotte
#39043 Hi Erik,
eriksl wrote:so only a limited amount of ram is used.

Isn't what the ESP8266WebServer is doing in sendContent_P(), by using memcpy_P() which is calling pgm_read_byte() macro ?
It only bring 1460 bytes chunk in RAM at a time from "const PROGMEM", send it to network client and looping until the whole web page been sent.