diff --git a/core/include/common_macros.h b/core/include/common_macros.h index 4aa6248..d4afe4f 100644 --- a/core/include/common_macros.h +++ b/core/include/common_macros.h @@ -37,15 +37,71 @@ #define VAL2FIELD_M(fieldname, value) (((value) & fieldname##_M) << fieldname##_S) #define SET_FIELD_M(regbits, fieldname, value) (((regbits) & ~FIELD_MASK(fieldname)) | VAL2FIELD_M(fieldname, value)) -/* Use this macro to store constant values in IROM flash instead - of having them loaded into rodata (which resides in DRAM) +/* Use the IRAM macro to place functions into Instruction RAM (IRAM) + instead of flash (aka irom). - Unlike the ESP8266 SDK you don't need an attribute like this for - standard functions. They're stored in flash by default. But - variables need them. + (This is the opposite to the Espressif SDK, where functions default + to being placed in IRAM but the ICACHE_FLASH_ATTR attribute will + place them in flash.) - Important to note: IROM flash can only be accessed via 32-bit word - aligned reads. It's up to the user of this attribute to ensure this. + Use the IRAM attribute for functions which are called when the + flash may not be available (for example during NMI exceptions), or + for functions which are called very frequently and need high + performance. + + Usage example: + + void IRAM high_performance_function(void) + { + // do important thing here + } + + Bear in mind IRAM is limited (32KB), compared to up to 1MB of flash. +*/ +#define IRAM __attribute__((section(".iram1.text"))) + +/* Use the RAM macro to place constant data (rodata) into RAM (data + RAM) instead of the default placement in flash. This is useful for + constant data which needs high performance access. + + Usage example: + + const RAM uint8_t constants[] = { 1, 2, 3, 7 }; + + When placing string literals in RAM, they need to be declared with + the type "const char[]" not "const char *" + + Usage example: + + const RAM char hello_world[] = "Hello World"; +*/ +#define RAM __attribute__((section(".data"))) + +/* Use the IRAM_DATA macro to place data into Instruction RAM (IRAM) + instead of the default of flash (for constant data) or data RAM + (for non-constant data). + + This may be useful to free up data RAM. However all data read from + any instruction space (either IRAM or Flash) must be 32-bit aligned + word reads. Reading unaligned data stored with IRAM_DATA will be + slower than reading data stored in RAM. You can't perform unaligned + writes to IRAM. +*/ +#define IRAM_DATA __attribute__((section(".iram1.data"))) + +/* Use the IROM macro to store constant values in IROM flash. In + esp-open-rtos this is already the default location for most constant + data (rodata), so you don't need this attribute in 99% of cases. + + The exceptions are to mark data in the core & freertos libraries, + where the default for constant data storage is RAM. + + (Unlike the Espressif SDK you don't need to use an attribute like + ICACHE_FLASH_ATTR for functions, they go into flash by default.) + + Important to note: IROM flash is accessed via 32-bit word aligned + reads. esp-open-rtos does some magic to "fix" unaligned reads, but + performance is reduced. */ #ifdef __cplusplus #define IROM __attribute__((section(".irom0.literal"))) @@ -53,28 +109,5 @@ #define IROM __attribute__((section(".irom0.literal"))) const #endif -/* Use this macro to place functions into Instruction RAM (IRAM) - instead of flash memory (IROM). - - This is useful for functions which are called when the flash may - not be available (for example during NMI exceptions), or for - functions which are called very frequently and need high - performance. - - Bear in mind IRAM is limited (32KB), compared to up to 1MB of flash. -*/ -#define IRAM __attribute__((section(".iram1.text"))) - -/* Use this macro to place data into Instruction RAM (IRAM) - instead of loaded into rodata which resides in DRAM. - - (IRAM can also be written to as necessary.) - - This may be useful to free up data RAM. However all data read from - the instruction space must be 32-bit aligned word reads - (non-aligned reads will use an interrupt routine to "fix" them and - still work, but are very slow.. -*/ -#define IRAM_DATA __attribute__((section(".iram1.rodata"))) #endif diff --git a/examples/experiments/unaligned_load/unaligned_load.c b/examples/experiments/unaligned_load/unaligned_load.c index 4244804..ff6cab7 100644 --- a/examples/experiments/unaligned_load/unaligned_load.c +++ b/examples/experiments/unaligned_load/unaligned_load.c @@ -13,9 +13,9 @@ #define TESTSTRING "O hai there! %d %d %d" -const char *dramtest = TESTSTRING; -const __attribute__((section(".iram1.notrodata"))) char iramtest[] = TESTSTRING; -const __attribute__((section(".text.notrodata"))) char iromtest[] = TESTSTRING; +const RAM char dramtest[] = TESTSTRING; +const char *iromtest = TESTSTRING; +const IRAM_DATA char iramtest[] = TESTSTRING; static inline uint32_t get_ccount (void) {