0

While saving ESP8266 RAM spaces I am confused by the usage of PSTR(), PROGMEM, and lots of _P functions.

What I know now is PROGMEM only applies to global or static strings, while PSTR() can only be used in functions.

The definition of PROGMEM and PSTR() is like:

#define PROGMEM __attribute__((section( "\".irom.text." __FILE__ "." __STRINGIZE(__LINE__) "."  __STRINGIZE(__COUNTER__) "\"")))
#define PSTRN(s,n) (__extension__({static const char __pstr__[] __attribute__((__aligned__(n))) __attribute__((section( "\".irom0.pstr." __FILE__ "." __STRINGIZE(__LINE__) "."  __STRINGIZE(__COUNTER__) "\", \"aSM\", @progbits, 1 #"))) = (s); &__pstr__[0];}))

...and I see one stores strings in .irom.text and the other in .irom0.pstr. Seems like PSTR() is the "extended version" of PROGMEM.

I've tested them like this:

static PGM_P progfmt PROGMEM = "I'm PROGstr. %s\n";
PGM_P pstrfmt = PSTR("I'm PSTRstr. %s\n");

Serial.printf_P(progfmt, pstrfmt);
Serial.printf_P(pstrfmt, progfmt);

They work alike..?

...and this panics.

static PGM_P prog_pstr PROGMEM = PSTR("I'm both. %s\n");

My questions are:

  • What is the difference between them (or technically, .irom.text and .irom0.pstr) ? Do they all save RAM by storing strings in Flash? And when to use which?
  • What about type PGM_P (const char *)?
  • Is there anything to consider while using them with _P functions? Any behavior differences?
45gfg9
  • 1
  • The ESP8266 is a 32Bit CPU with a flat memory model. The answers given in https://arduino.stackexchange.com/questions/89159/is-there-a-good-reference-for-arduino-due-memory-architecture-and-usage/89163#89163 should apply 1:1. Bottom line: Neither of this is necessary. – PMF Apr 09 '22 at 11:25
  • use `F()` to save RAM on ESPs. – dandavis Apr 10 '22 at 09:30
  • @dandavis The use of `F()` has no impact on the use of RAM whatsoever on these CPUs. – PMF Apr 10 '22 at 11:14
  • @PMF: I use it on web responses all the time. Compiling for nodemcu, I tested F() a 9693b string in one of my sketches with and without, with F(): `... leaving 24928 bytes...`, w/o F(): `...leaving 15232 bytes...`. Without it, i even get the ole _Low memory available, stability problems may occur._ It sure seems like it saved the RAM, how do you explain? Is the IDE and `ESP.getFreeHeap()` after boot wrong? – dandavis Apr 10 '22 at 16:49
  • @dandavis I tested (although with an ESP32) and for me the amount of RAM used did not change. Maybe it depends whether the compiler can otherwise make sure that the data is const. Except for maybe a slight performance improvement (because reading RAM is faster than reading Flash), there would be no reason on an ESP to copy constants to RAM at bootup. – PMF Apr 10 '22 at 18:19
  • I found [Guide to PROGMEM on ESP8266 and Arduino IDE](https://arduino-esp8266.readthedocs.io/en/latest/PROGMEM.html) especially helpful. – DWB May 15 '22 at 23:54
  • 1
    @PMF esp32 is different in this. on esp8266 PROGMEM is useful – Juraj May 20 '22 at 17:18
  • @Juraj Oh, good to know. I thought this would be implemented similarly for all 32 bit MCUs with a von-Neuman architecture. – PMF May 20 '22 at 17:27
  • @PMF On ESP32 the PROGMEM and PSTR() macros are all defined to empty macros. – 45gfg9 Jul 01 '22 at 02:41

0 Answers0