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.textand.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
_Pfunctions? Any behavior differences?