diff --git a/tools/sdk/ld/eagle.app.v6.common.ld.h b/tools/sdk/ld/eagle.app.v6.common.ld.h index 2f5735fff7..383154e491 100644 --- a/tools/sdk/ld/eagle.app.v6.common.ld.h +++ b/tools/sdk/ld/eagle.app.v6.common.ld.h @@ -181,6 +181,9 @@ SECTIONS *libwps.a:(.literal.* .text.*) *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom0.text.* .irom.text .irom.text.*) + /* Constant strings in flash (PSTRs) */ + *(.irom0.pstr.*) + /* __FUNCTION__ locals */ *(.rodata._ZZ*__FUNCTION__) *(.rodata._ZZ*__PRETTY_FUNCTION__) diff --git a/tools/sdk/libc/xtensa-lx106-elf/include/sys/pgmspace.h b/tools/sdk/libc/xtensa-lx106-elf/include/sys/pgmspace.h index d74b8b000c..20512bed4c 100644 --- a/tools/sdk/libc/xtensa-lx106-elf/include/sys/pgmspace.h +++ b/tools/sdk/libc/xtensa-lx106-elf/include/sys/pgmspace.h @@ -23,6 +23,7 @@ extern "C" { // Ref: https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Variable-Attributes.html // Place each progmem object into its own named section, avoiding conflicts #define PROGMEM __attribute__((section( "\".irom.text." __FILE__ "." __STRINGIZE(__LINE__) "." __STRINGIZE(__COUNTER__) "\""))) + #define PROGMEM_PSTR "\".irom0.pstr." __FILE__ "." __STRINGIZE(__LINE__) "." __STRINGIZE(__COUNTER__) "\"" #endif #ifndef PGM_P #define PGM_P const char * @@ -34,7 +35,12 @@ extern "C" { // PSTR() macro modified to start on a 32-bit boundary. This adds on average // 1.5 bytes/string, but in return memcpy_P and strcpy_P will work 4~8x faster #ifndef PSTR - #define PSTR(s) (__extension__({static const char __c[] __attribute__((__aligned__(4))) PROGMEM = (s); &__c[0];})) + // Adapted from AVR-specific code at https://forum.arduino.cc/index.php?topic=194603.0 + #define PSTR(str) (__extension__({ \ + PGM_P ptr; \ + asm volatile ( ".pushsection " PROGMEM_PSTR ", \"aSM\", @progbits, 1 \n .align 4 \n 0: .string " __STRINGIZE(str) "\n .popsection \n" ); \ + asm volatile ( "movi %0, 0b" : "=r" (ptr) ); \ + ptr; })) #endif // Flash memory must be read using 32 bit aligned addresses else a processor