From 0bf1c903721e9f0ec6690befbedc88c72876b6bb Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Sun, 14 Mar 2021 11:14:41 -0700 Subject: [PATCH] BREAKING - Use IRAM_ATTR in place of ICACHE_RAM_ATTR Update the core to use the define that the ESP32 uses, IRAM_ATTR, for placing code in DRAM. --- cores/esp8266/FunctionalInterrupt.cpp | 2 +- cores/esp8266/cbuf.cpp | 6 ++-- cores/esp8266/cont_util.cpp | 4 +-- cores/esp8266/core_esp8266_i2s.cpp | 8 ++--- cores/esp8266/core_esp8266_phy.cpp | 6 ++-- cores/esp8266/core_esp8266_si2c.cpp | 30 ++++++++-------- cores/esp8266/core_esp8266_timer.cpp | 22 ++++++------ cores/esp8266/core_esp8266_waveform.h | 2 +- cores/esp8266/core_esp8266_waveform_phase.cpp | 10 +++--- cores/esp8266/core_esp8266_waveform_pwm.cpp | 20 +++++------ cores/esp8266/core_esp8266_wiring.cpp | 10 +++--- cores/esp8266/core_esp8266_wiring_digital.cpp | 8 ++--- cores/esp8266/gdb_hooks.cpp | 2 +- cores/esp8266/heap.cpp | 34 +++++++++---------- cores/esp8266/libc_replacements.cpp | 20 +++++------ cores/esp8266/reboot_uart_dwnld.cpp | 2 +- cores/esp8266/uart.cpp | 8 ++--- cores/esp8266/umm_malloc/umm_malloc_cfg.h | 14 ++++---- doc/faq/a02-my-esp-crashes.rst | 4 +-- doc/reference.rst | 6 ++-- libraries/GDBStub/src/internal/gdbstub-cfg.h | 2 +- libraries/SPISlave/src/hspi_slave.c | 4 +-- .../device/test_millis_mm/test_millis_mm.ino | 12 +++---- tests/host/common/c_types.h | 6 ++-- tools/sdk/include/c_types.h | 8 ++--- tools/sizes.py | 2 +- 26 files changed, 126 insertions(+), 126 deletions(-) diff --git a/cores/esp8266/FunctionalInterrupt.cpp b/cores/esp8266/FunctionalInterrupt.cpp index 665d8043b3..f468595787 100644 --- a/cores/esp8266/FunctionalInterrupt.cpp +++ b/cores/esp8266/FunctionalInterrupt.cpp @@ -10,7 +10,7 @@ typedef void (*voidFuncPtrArg)(void*); extern "C" void __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtr userFunc, void*fp, int mode, bool functional); -void ICACHE_RAM_ATTR interruptFunctional(void* arg) +void IRAM_ATTR interruptFunctional(void* arg) { ArgStructure* localArg = (ArgStructure*)arg; if (localArg->functionInfo->reqScheduledFunction) diff --git a/cores/esp8266/cbuf.cpp b/cores/esp8266/cbuf.cpp index b9a2880e30..3a9e33a8a2 100644 --- a/cores/esp8266/cbuf.cpp +++ b/cores/esp8266/cbuf.cpp @@ -67,7 +67,7 @@ size_t cbuf::resize(size_t newSize) { return _size; } -size_t ICACHE_RAM_ATTR cbuf::available() const { +size_t IRAM_ATTR cbuf::available() const { if(_end >= _begin) { return _end - _begin; } @@ -108,7 +108,7 @@ size_t cbuf::peek(char *dst, size_t size) { return size_read; } -int ICACHE_RAM_ATTR cbuf::read() { +int IRAM_ATTR cbuf::read() { if(empty()) return -1; @@ -133,7 +133,7 @@ size_t cbuf::read(char* dst, size_t size) { return size_read; } -size_t ICACHE_RAM_ATTR cbuf::write(char c) { +size_t IRAM_ATTR cbuf::write(char c) { if(full()) return 0; diff --git a/cores/esp8266/cont_util.cpp b/cores/esp8266/cont_util.cpp index d21a064e35..8fa4421802 100644 --- a/cores/esp8266/cont_util.cpp +++ b/cores/esp8266/cont_util.cpp @@ -42,7 +42,7 @@ void cont_init(cont_t* cont) { } } -int ICACHE_RAM_ATTR cont_check(cont_t* cont) { +int IRAM_ATTR cont_check(cont_t* cont) { if(cont->stack_guard1 != CONT_STACKGUARD || cont->stack_guard2 != CONT_STACKGUARD) return 1; return 0; @@ -62,7 +62,7 @@ int cont_get_free_stack(cont_t* cont) { return freeWords * 4; } -bool ICACHE_RAM_ATTR cont_can_yield(cont_t* cont) { +bool IRAM_ATTR cont_can_yield(cont_t* cont) { return !ETS_INTR_WITHINISR() && cont->pc_ret != 0 && cont->pc_yield == 0; } diff --git a/cores/esp8266/core_esp8266_i2s.cpp b/cores/esp8266/core_esp8266_i2s.cpp index eb1d7d7e2f..eb13ee0b7f 100644 --- a/cores/esp8266/core_esp8266_i2s.cpp +++ b/cores/esp8266/core_esp8266_i2s.cpp @@ -61,7 +61,7 @@ typedef struct i2s_state { uint32_t * curr_slc_buf; // Current buffer for writing uint32_t curr_slc_buf_pos; // Position in the current buffer void (*callback) (void); - // Callback function should be defined as 'void ICACHE_RAM_ATTR function_name()', + // Callback function should be defined as 'void IRAM_ATTR function_name()', // and be placed in IRAM for faster execution. Avoid long computational tasks in this // function, use it to set flags and process later. bool driveClocks; @@ -139,7 +139,7 @@ uint16_t i2s_rx_available(){ } // Pop the top off of the queue and return it -static uint32_t * ICACHE_RAM_ATTR i2s_slc_queue_next_item(i2s_state_t *ch) { +static uint32_t * IRAM_ATTR i2s_slc_queue_next_item(i2s_state_t *ch) { uint8_t i; uint32_t *item = ch->slc_queue[0]; ch->slc_queue_len--; @@ -150,7 +150,7 @@ static uint32_t * ICACHE_RAM_ATTR i2s_slc_queue_next_item(i2s_state_t *ch) { } // Append an item to the end of the queue from receive -static void ICACHE_RAM_ATTR i2s_slc_queue_append_item(i2s_state_t *ch, uint32_t *item) { +static void IRAM_ATTR i2s_slc_queue_append_item(i2s_state_t *ch, uint32_t *item) { // Shift everything up, except for the one corresponding to this item for (int i=0, dest=0; i < ch->slc_queue_len; i++) { if (ch->slc_queue[i] != item) { @@ -164,7 +164,7 @@ static void ICACHE_RAM_ATTR i2s_slc_queue_append_item(i2s_state_t *ch, uint32_t } } -static void ICACHE_RAM_ATTR i2s_slc_isr(void) { +static void IRAM_ATTR i2s_slc_isr(void) { ETS_SLC_INTR_DISABLE(); uint32_t slc_intr_status = SLCIS; SLCIC = 0xFFFFFFFF; diff --git a/cores/esp8266/core_esp8266_phy.cpp b/cores/esp8266/core_esp8266_phy.cpp index 3fb027f4fb..9291d35fca 100644 --- a/cores/esp8266/core_esp8266_phy.cpp +++ b/cores/esp8266/core_esp8266_phy.cpp @@ -300,10 +300,10 @@ static const uint8_t ICACHE_FLASH_ATTR phy_init_data[128] = static bool spoof_init_data = false; extern int __real_spi_flash_read(uint32_t addr, uint32_t* dst, size_t size); -extern int ICACHE_RAM_ATTR __wrap_spi_flash_read(uint32_t addr, uint32_t* dst, size_t size); +extern int IRAM_ATTR __wrap_spi_flash_read(uint32_t addr, uint32_t* dst, size_t size); extern int __get_adc_mode(); -extern int ICACHE_RAM_ATTR __wrap_spi_flash_read(uint32_t addr, uint32_t* dst, size_t size) +extern int IRAM_ATTR __wrap_spi_flash_read(uint32_t addr, uint32_t* dst, size_t size) { if (!spoof_init_data || size != 128) { return __real_spi_flash_read(addr, dst, size); @@ -354,6 +354,6 @@ void user_rf_pre_init() } -void ICACHE_RAM_ATTR user_spi_flash_dio_to_qio_pre_init() {} +void IRAM_ATTR user_spi_flash_dio_to_qio_pre_init() {} }; diff --git a/cores/esp8266/core_esp8266_si2c.cpp b/cores/esp8266/core_esp8266_si2c.cpp index fa6d164342..e4bb1c2b07 100644 --- a/cores/esp8266/core_esp8266_si2c.cpp +++ b/cores/esp8266/core_esp8266_si2c.cpp @@ -103,23 +103,23 @@ class Twi ETSTimer timer; // Event/IRQ callbacks, so they can't use "this" and need to be static - static void ICACHE_RAM_ATTR onSclChange(void); - static void ICACHE_RAM_ATTR onSdaChange(void); + static void IRAM_ATTR onSclChange(void); + static void IRAM_ATTR onSdaChange(void); static void eventTask(ETSEvent *e); - static void ICACHE_RAM_ATTR onTimer(void *unused); + static void IRAM_ATTR onTimer(void *unused); // Allow not linking in the slave code if there is no call to setAddress bool _slaveEnabled = false; // Internal use functions - void ICACHE_RAM_ATTR busywait(unsigned int v); + void IRAM_ATTR busywait(unsigned int v); bool write_start(void); bool write_stop(void); bool write_bit(bool bit); bool read_bit(void); bool write_byte(unsigned char byte); unsigned char read_byte(bool nack); - void ICACHE_RAM_ATTR onTwipEvent(uint8_t status); + void IRAM_ATTR onTwipEvent(uint8_t status); // Handle the case where a slave needs to stretch the clock with a time-limited busy wait inline void WAIT_CLOCK_STRETCH() @@ -149,8 +149,8 @@ class Twi uint8_t transmit(const uint8_t* data, uint8_t length); void attachSlaveRxEvent(void (*function)(uint8_t*, size_t)); void attachSlaveTxEvent(void (*function)(void)); - void ICACHE_RAM_ATTR reply(uint8_t ack); - void ICACHE_RAM_ATTR releaseBus(void); + void IRAM_ATTR reply(uint8_t ack); + void IRAM_ATTR releaseBus(void); void enableSlave(); }; @@ -229,7 +229,7 @@ void Twi::enableSlave() } } -void ICACHE_RAM_ATTR Twi::busywait(unsigned int v) +void IRAM_ATTR Twi::busywait(unsigned int v) { unsigned int i; for (i = 0; i < v; i++) // loop time is 5 machine cycles: 31.25ns @ 160MHz, 62.5ns @ 80MHz @@ -472,9 +472,9 @@ void Twi::attachSlaveTxEvent(void (*function)(void)) } // DO NOT INLINE, inlining reply() in combination with compiler optimizations causes function breakup into -// parts and the ICACHE_RAM_ATTR isn't propagated correctly to all parts, which of course causes crashes. +// parts and the IRAM_ATTR isn't propagated correctly to all parts, which of course causes crashes. // TODO: test with gcc 9.x and if it still fails, disable optimization with -fdisable-ipa-fnsplit -void ICACHE_RAM_ATTR Twi::reply(uint8_t ack) +void IRAM_ATTR Twi::reply(uint8_t ack) { // transmit master read ready signal, with or without ack if (ack) @@ -492,7 +492,7 @@ void ICACHE_RAM_ATTR Twi::reply(uint8_t ack) } -void ICACHE_RAM_ATTR Twi::releaseBus(void) +void IRAM_ATTR Twi::releaseBus(void) { // release bus //TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT); @@ -505,7 +505,7 @@ void ICACHE_RAM_ATTR Twi::releaseBus(void) } -void ICACHE_RAM_ATTR Twi::onTwipEvent(uint8_t status) +void IRAM_ATTR Twi::onTwipEvent(uint8_t status) { twip_status = status; switch (status) @@ -612,7 +612,7 @@ void ICACHE_RAM_ATTR Twi::onTwipEvent(uint8_t status) } } -void ICACHE_RAM_ATTR Twi::onTimer(void *unused) +void IRAM_ATTR Twi::onTimer(void *unused) { (void)unused; twi.releaseBus(); @@ -662,7 +662,7 @@ void Twi::eventTask(ETSEvent *e) // Shorthand for if the state is any of the or'd bitmask x #define IFSTATE(x) if (twip_state_mask & (x)) -void ICACHE_RAM_ATTR Twi::onSclChange(void) +void IRAM_ATTR Twi::onSclChange(void) { unsigned int sda; unsigned int scl; @@ -860,7 +860,7 @@ void ICACHE_RAM_ATTR Twi::onSclChange(void) } } -void ICACHE_RAM_ATTR Twi::onSdaChange(void) +void IRAM_ATTR Twi::onSdaChange(void) { unsigned int sda; unsigned int scl; diff --git a/cores/esp8266/core_esp8266_timer.cpp b/cores/esp8266/core_esp8266_timer.cpp index af15de7fa9..02bd4aa470 100644 --- a/cores/esp8266/core_esp8266_timer.cpp +++ b/cores/esp8266/core_esp8266_timer.cpp @@ -31,7 +31,7 @@ extern "C" { static volatile timercallback timer1_user_cb = NULL; -void ICACHE_RAM_ATTR timer1_isr_handler(void *para, void *frame) { +void IRAM_ATTR timer1_isr_handler(void *para, void *frame) { (void) para; (void) frame; if ((T1C & ((1 << TCAR) | (1 << TCIT))) == 0) TEIE &= ~TEIE1;//edge int disable @@ -45,32 +45,32 @@ void ICACHE_RAM_ATTR timer1_isr_handler(void *para, void *frame) { } } -void ICACHE_RAM_ATTR timer1_isr_init(){ +void IRAM_ATTR timer1_isr_init(){ ETS_FRC_TIMER1_INTR_ATTACH(timer1_isr_handler, NULL); } -void ICACHE_RAM_ATTR timer1_attachInterrupt(timercallback userFunc) { +void IRAM_ATTR timer1_attachInterrupt(timercallback userFunc) { timer1_user_cb = userFunc; ETS_FRC1_INTR_ENABLE(); } -void ICACHE_RAM_ATTR timer1_detachInterrupt() { +void IRAM_ATTR timer1_detachInterrupt() { timer1_user_cb = 0; TEIE &= ~TEIE1;//edge int disable ETS_FRC1_INTR_DISABLE(); } -void ICACHE_RAM_ATTR timer1_enable(uint8_t divider, uint8_t int_type, uint8_t reload){ +void IRAM_ATTR timer1_enable(uint8_t divider, uint8_t int_type, uint8_t reload){ T1C = (1 << TCTE) | ((divider & 3) << TCPD) | ((int_type & 1) << TCIT) | ((reload & 1) << TCAR); T1I = 0; } -void ICACHE_RAM_ATTR timer1_write(uint32_t ticks){ +void IRAM_ATTR timer1_write(uint32_t ticks){ T1L = ((ticks)& 0x7FFFFF); if ((T1C & (1 << TCIT)) == 0) TEIE |= TEIE1;//edge int enable } -void ICACHE_RAM_ATTR timer1_disable(){ +void IRAM_ATTR timer1_disable(){ T1C = 0; T1I = 0; } @@ -80,7 +80,7 @@ void ICACHE_RAM_ATTR timer1_disable(){ static volatile timercallback timer0_user_cb = NULL; -void ICACHE_RAM_ATTR timer0_isr_handler(void *para, void *frame) { +void IRAM_ATTR timer0_isr_handler(void *para, void *frame) { (void) para; (void) frame; if (timer0_user_cb) { @@ -92,16 +92,16 @@ void ICACHE_RAM_ATTR timer0_isr_handler(void *para, void *frame) { } } -void ICACHE_RAM_ATTR timer0_isr_init(){ +void IRAM_ATTR timer0_isr_init(){ ETS_CCOMPARE0_INTR_ATTACH(timer0_isr_handler, NULL); } -void ICACHE_RAM_ATTR timer0_attachInterrupt(timercallback userFunc) { +void IRAM_ATTR timer0_attachInterrupt(timercallback userFunc) { timer0_user_cb = userFunc; ETS_CCOMPARE0_ENABLE(); } -void ICACHE_RAM_ATTR timer0_detachInterrupt() { +void IRAM_ATTR timer0_detachInterrupt() { timer0_user_cb = NULL; ETS_CCOMPARE0_DISABLE(); } diff --git a/cores/esp8266/core_esp8266_waveform.h b/cores/esp8266/core_esp8266_waveform.h index 119af4181c..d863fa6709 100644 --- a/cores/esp8266/core_esp8266_waveform.h +++ b/cores/esp8266/core_esp8266_waveform.h @@ -112,7 +112,7 @@ int stopWaveform(uint8_t pin); // to determine whether or not to perform an operation. // Pass in NULL to disable the callback and, if no other waveforms being // generated, stop the timer as well. -// Make sure the CB function has the ICACHE_RAM_ATTR decorator. +// Make sure the CB function has the IRAM_ATTR decorator. void setTimer1Callback(uint32_t (*fn)()); diff --git a/cores/esp8266/core_esp8266_waveform_phase.cpp b/cores/esp8266/core_esp8266_waveform_phase.cpp index f15d3c9598..5f81c52ff3 100644 --- a/cores/esp8266/core_esp8266_waveform_phase.cpp +++ b/cores/esp8266/core_esp8266_waveform_phase.cpp @@ -111,7 +111,7 @@ namespace { } // Interrupt on/off control -static ICACHE_RAM_ATTR void timer1Interrupt(); +static IRAM_ATTR void timer1Interrupt(); // Non-speed critical bits #pragma GCC optimize ("Os") @@ -125,7 +125,7 @@ static void initTimer() { timer1_write(IRQLATENCYCCYS); // Cause an interrupt post-haste } -static void ICACHE_RAM_ATTR deinitTimer() { +static void IRAM_ATTR deinitTimer() { ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL); timer1_disable(); timer1_isr_init(); @@ -218,7 +218,7 @@ int startWaveformClockCycles_weak(uint8_t pin, uint32_t highCcys, uint32_t lowCc } // Stops a waveform on a pin -ICACHE_RAM_ATTR int stopWaveform_weak(uint8_t pin) { +IRAM_ATTR int stopWaveform_weak(uint8_t pin) { // Can't possibly need to stop anything if there is no timer active if (!waveform.timer1Running) { return false; @@ -252,7 +252,7 @@ ICACHE_RAM_ATTR int stopWaveform_weak(uint8_t pin) { // For dynamic CPU clock frequency switch in loop the scaling logic would have to be adapted. // Using constexpr makes sure that the CPU clock frequency is compile-time fixed. -static inline ICACHE_RAM_ATTR int32_t scaleCcys(const int32_t ccys, const bool isCPU2X) { +static inline IRAM_ATTR int32_t scaleCcys(const int32_t ccys, const bool isCPU2X) { if (ISCPUFREQ160MHZ) { return isCPU2X ? ccys : (ccys >> 1); } @@ -261,7 +261,7 @@ static inline ICACHE_RAM_ATTR int32_t scaleCcys(const int32_t ccys, const bool i } } -static ICACHE_RAM_ATTR void timer1Interrupt() { +static IRAM_ATTR void timer1Interrupt() { const uint32_t isrStartCcy = ESP.getCycleCount(); int32_t clockDrift = isrStartCcy - waveform.nextEventCcy; const bool isCPU2X = CPU2X & 1; diff --git a/cores/esp8266/core_esp8266_waveform_pwm.cpp b/cores/esp8266/core_esp8266_waveform_pwm.cpp index 7cbdabd89f..b33a657ba1 100644 --- a/cores/esp8266/core_esp8266_waveform_pwm.cpp +++ b/cores/esp8266/core_esp8266_waveform_pwm.cpp @@ -93,7 +93,7 @@ static WVFState wvfState; #pragma GCC optimize ("Os") // Interrupt on/off control -static ICACHE_RAM_ATTR void timer1Interrupt(); +static IRAM_ATTR void timer1Interrupt(); static bool timerRunning = false; static __attribute__((noinline)) void initTimer() { @@ -107,7 +107,7 @@ static __attribute__((noinline)) void initTimer() { } } -static ICACHE_RAM_ATTR void forceTimerInterrupt() { +static IRAM_ATTR void forceTimerInterrupt() { if (T1L > microsecondsToClockCycles(10)) { T1L = microsecondsToClockCycles(10); } @@ -144,7 +144,7 @@ static uint32_t _pwmPeriod = microsecondsToClockCycles(1000000UL) / _pwmFreq; // If there are no more scheduled activities, shut down Timer 1. // Otherwise, do nothing. -static ICACHE_RAM_ATTR void disableIdleTimer() { +static IRAM_ATTR void disableIdleTimer() { if (timerRunning && !wvfState.waveformEnabled && !pwmState.cnt && !wvfState.timer1CB) { ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL); timer1_disable(); @@ -155,7 +155,7 @@ static ICACHE_RAM_ATTR void disableIdleTimer() { // Notify the NMI that a new PWM state is available through the mailbox. // Wait for mailbox to be emptied (either busy or delay() as needed) -static ICACHE_RAM_ATTR void _notifyPWM(PWMState *p, bool idle) { +static IRAM_ATTR void _notifyPWM(PWMState *p, bool idle) { p->pwmUpdate = nullptr; pwmState.pwmUpdate = p; MEMBARRIER(); @@ -237,7 +237,7 @@ static void _cleanAndRemovePWM(PWMState *p, int pin) { // Disable PWM on a specific pin (i.e. when a digitalWrite or analogWrite(0%/100%)) extern bool _stopPWM_weak(uint8_t pin) __attribute__((weak)); -ICACHE_RAM_ATTR bool _stopPWM_weak(uint8_t pin) { +IRAM_ATTR bool _stopPWM_weak(uint8_t pin) { if (!((1<st_mode = S_IFCHR; return 0; } -int ICACHE_RAM_ATTR _lseek_r(struct _reent* unused, int file, int ptr, int dir) { +int IRAM_ATTR _lseek_r(struct _reent* unused, int file, int ptr, int dir) { (void)unused; (void)file; (void)ptr; @@ -75,7 +75,7 @@ int ICACHE_RAM_ATTR _lseek_r(struct _reent* unused, int file, int ptr, int dir) return 0; } -int ICACHE_RAM_ATTR _read_r(struct _reent* unused, int file, char *ptr, int len) { +int IRAM_ATTR _read_r(struct _reent* unused, int file, char *ptr, int len) { (void)unused; (void)file; (void)ptr; @@ -83,7 +83,7 @@ int ICACHE_RAM_ATTR _read_r(struct _reent* unused, int file, char *ptr, int len) return 0; } -int ICACHE_RAM_ATTR _write_r(struct _reent* r, int file, char *ptr, int len) { +int IRAM_ATTR _write_r(struct _reent* r, int file, char *ptr, int len) { (void) r; int pos = len; if (file == STDOUT_FILENO) { @@ -95,9 +95,9 @@ int ICACHE_RAM_ATTR _write_r(struct _reent* r, int file, char *ptr, int len) { return len; } -int ICACHE_RAM_ATTR _putc_r(struct _reent* r, int c, FILE* file) __attribute__((weak)); +int IRAM_ATTR _putc_r(struct _reent* r, int c, FILE* file) __attribute__((weak)); -int ICACHE_RAM_ATTR _putc_r(struct _reent* r, int c, FILE* file) { +int IRAM_ATTR _putc_r(struct _reent* r, int c, FILE* file) { (void) r; if (file->_file == STDOUT_FILENO) { ets_putc(c); @@ -106,7 +106,7 @@ int ICACHE_RAM_ATTR _putc_r(struct _reent* r, int c, FILE* file) { return EOF; } -int ICACHE_RAM_ATTR puts(const char * str) { +int IRAM_ATTR puts(const char * str) { char c; while((c = *str) != 0) { ets_putc(c); @@ -117,7 +117,7 @@ int ICACHE_RAM_ATTR puts(const char * str) { } #undef putchar -int ICACHE_RAM_ATTR putchar(int c) { +int IRAM_ATTR putchar(int c) { ets_putc(c); return c; } diff --git a/cores/esp8266/reboot_uart_dwnld.cpp b/cores/esp8266/reboot_uart_dwnld.cpp index dce4cf0ae3..ce9f52d14d 100644 --- a/cores/esp8266/reboot_uart_dwnld.cpp +++ b/cores/esp8266/reboot_uart_dwnld.cpp @@ -52,7 +52,7 @@ static inline void __wsr_vecbase(uint32_t vector_base) { asm volatile("wsr.vecbase %0" :: "r" (vector_base)); } -[[noreturn]] void ICACHE_RAM_ATTR esp8266UartDownloadMode() +[[noreturn]] void IRAM_ATTR esp8266UartDownloadMode() { /* reverse engineered from system_restart_core() */ /* Before disabling instruction cache and restoring instruction RAM to a diff --git a/cores/esp8266/uart.cpp b/cores/esp8266/uart.cpp index 47e7243abf..736dbae2de 100644 --- a/cores/esp8266/uart.cpp +++ b/cores/esp8266/uart.cpp @@ -115,7 +115,7 @@ struct uart_ // called by ISR -inline size_t ICACHE_RAM_ATTR +inline size_t IRAM_ATTR uart_rx_fifo_available(const int uart_nr) { return (USS(uart_nr) >> USRXC) & 0xFF; @@ -144,7 +144,7 @@ uart_rx_available_unsafe(uart_t* uart) // Copy all the rx fifo bytes that fit into the rx buffer // called by ISR -inline void ICACHE_RAM_ATTR +inline void IRAM_ATTR uart_rx_copy_fifo_to_buffer_unsafe(uart_t* uart) { struct uart_rx_buffer_ *rx_buffer = uart->rx_buffer; @@ -289,7 +289,7 @@ uart_read(uart_t* uart, char* userbuffer, size_t usersize) // instead of the uart_isr...uart_rx_copy_fifo_to_buffer_unsafe() // Since we've already read the bytes from the FIFO, can't use that // function directly and need to implement it bytewise here -static void ICACHE_RAM_ATTR uart_isr_handle_data(void* arg, uint8_t data) +static void IRAM_ATTR uart_isr_handle_data(void* arg, uint8_t data) { uart_t* uart = (uart_t*)arg; if(uart == NULL || !uart->rx_enabled) { @@ -370,7 +370,7 @@ uart_get_rx_buffer_size(uart_t* uart) } // The default ISR handler called when GDB is not enabled -void ICACHE_RAM_ATTR +void IRAM_ATTR uart_isr(void * arg, void * frame) { (void) frame; diff --git a/cores/esp8266/umm_malloc/umm_malloc_cfg.h b/cores/esp8266/umm_malloc/umm_malloc_cfg.h index 4fc059a49c..4c14c8eb12 100644 --- a/cores/esp8266/umm_malloc/umm_malloc_cfg.h +++ b/cores/esp8266/umm_malloc/umm_malloc_cfg.h @@ -793,11 +793,11 @@ extern "C" { #include // Reuse pvPort* calls, since they already support passing location information. // Specificly the debug version (heap_...) that does not force DRAM heap. -void* ICACHE_RAM_ATTR heap_pvPortMalloc(size_t size, const char* file, int line); -void* ICACHE_RAM_ATTR heap_pvPortCalloc(size_t count, size_t size, const char* file, int line); -void* ICACHE_RAM_ATTR heap_pvPortRealloc(void *ptr, size_t size, const char* file, int line); -void* ICACHE_RAM_ATTR heap_pvPortZalloc(size_t size, const char* file, int line); -void ICACHE_RAM_ATTR heap_vPortFree(void *ptr, const char* file, int line); +void* IRAM_ATTR heap_pvPortMalloc(size_t size, const char* file, int line); +void* IRAM_ATTR heap_pvPortCalloc(size_t count, size_t size, const char* file, int line); +void* IRAM_ATTR heap_pvPortRealloc(void *ptr, size_t size, const char* file, int line); +void* IRAM_ATTR heap_pvPortZalloc(size_t size, const char* file, int line); +void IRAM_ATTR heap_vPortFree(void *ptr, const char* file, int line); #define malloc(s) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; heap_pvPortMalloc(s, mem_debug_file, __LINE__); }) #define calloc(n,s) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; heap_pvPortCalloc(n, s, mem_debug_file, __LINE__); }) @@ -811,10 +811,10 @@ void ICACHE_RAM_ATTR heap_vPortFree(void *ptr, const char* file, int line); #elif defined(UMM_POISON_CHECK) || defined(UMM_POISON_CHECK_LITE) #include -void* ICACHE_RAM_ATTR heap_pvPortRealloc(void *ptr, size_t size, const char* file, int line); +void* IRAM_ATTR heap_pvPortRealloc(void *ptr, size_t size, const char* file, int line); #define realloc(p,s) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; heap_pvPortRealloc(p, s, mem_debug_file, __LINE__); }) -void ICACHE_RAM_ATTR heap_vPortFree(void *ptr, const char* file, int line); +void IRAM_ATTR heap_vPortFree(void *ptr, const char* file, int line); //C - to be discussed /* Problem, I would like to report the file and line number with the umm poison diff --git a/doc/faq/a02-my-esp-crashes.rst b/doc/faq/a02-my-esp-crashes.rst index c2433b5931..a000bd0f79 100644 --- a/doc/faq/a02-my-esp-crashes.rst +++ b/doc/faq/a02-my-esp-crashes.rst @@ -247,8 +247,8 @@ Interrupt Service Routines cache may kick in for that code. However, the cache currently can't be used during hardware interrupts. That means that, if you use a hardware ISR, such as attachInterrupt(gpio, myISR, CHANGE) for a GPIO change, the ISR must have the - ICACHE_RAM_ATTR attribute declared. Not only that, but the entire function tree - called from the ISR must also have the ICACHE_RAM_ATTR declared. + IRAM_ATTR attribute declared. Not only that, but the entire function tree + called from the ISR must also have the IRAM_ATTR declared. Be aware that every function that has this attribute reduces available memory. In addition, it is not possible to execute delay() or yield() from an ISR, diff --git a/doc/reference.rst b/doc/reference.rst index 32f5987f85..666ccd5743 100644 --- a/doc/reference.rst +++ b/doc/reference.rst @@ -9,13 +9,13 @@ and have several limitations: * Interrupt callback functions must be in IRAM, because the flash may be in the middle of other operations when they occur. Do this by adding - the ``ICACHE_RAM_ATTR`` attribute on the function definition. If this + the ``IRAM_ATTR`` attribute on the function definition. If this attribute is not present, the sketch will crash when it attempts to ``attachInterrupt`` with an error message. .. code:: cpp - ICACHE_RAM_ATTR void gpio_change_handler(void *data) {... + IRAM_ATTR void gpio_change_handler(void *data) {... * Interrupts must not call ``delay()`` or ``yield()``, or call any routines which internally use ``delay()`` or ``yield()`` either. @@ -69,7 +69,7 @@ Pin interrupts are supported through ``attachInterrupt``, ``detachInterrupt`` functions. Interrupts may be attached to any GPIO pin, except GPIO16. Standard Arduino interrupt types are supported: ``CHANGE``, ``RISING``, ``FALLING``. ISRs need to have -``ICACHE_RAM_ATTR`` before the function definition. +``IRAM_ATTR`` before the function definition. Analog input ------------ diff --git a/libraries/GDBStub/src/internal/gdbstub-cfg.h b/libraries/GDBStub/src/internal/gdbstub-cfg.h index be40ab98f6..c6adfda010 100644 --- a/libraries/GDBStub/src/internal/gdbstub-cfg.h +++ b/libraries/GDBStub/src/internal/gdbstub-cfg.h @@ -67,7 +67,7 @@ likely crash. #define ATTR_GDBINIT ICACHE_FLASH_ATTR #endif #ifndef ATTR_GDBFN -#define ATTR_GDBFN ICACHE_RAM_ATTR +#define ATTR_GDBFN IRAM_ATTR #endif #ifndef ATTR_GDBEXTERNFN #define ATTR_GDBEXTERNFN ICACHE_FLASH_ATTR diff --git a/libraries/SPISlave/src/hspi_slave.c b/libraries/SPISlave/src/hspi_slave.c index 8462b84146..c9df941dcd 100644 --- a/libraries/SPISlave/src/hspi_slave.c +++ b/libraries/SPISlave/src/hspi_slave.c @@ -28,7 +28,7 @@ static void (*_hspi_slave_rx_status_cb)(void * arg, uint32_t data) = NULL; static void (*_hspi_slave_tx_status_cb)(void * arg) = NULL; static uint8_t _hspi_slave_buffer[33]; -void ICACHE_RAM_ATTR _hspi_slave_isr_handler(void *arg, void *frame) +void IRAM_ATTR _hspi_slave_isr_handler(void *arg, void *frame) { (void) frame; uint32_t status; @@ -124,7 +124,7 @@ void hspi_slave_end() SPI1P = B110; } -void ICACHE_RAM_ATTR hspi_slave_setStatus(uint32_t status) +void IRAM_ATTR hspi_slave_setStatus(uint32_t status) { SPI1WS = status; } diff --git a/tests/device/test_millis_mm/test_millis_mm.ino b/tests/device/test_millis_mm/test_millis_mm.ino index c5e25bdcdc..6138000578 100644 --- a/tests/device/test_millis_mm/test_millis_mm.ino +++ b/tests/device/test_millis_mm/test_millis_mm.ino @@ -109,7 +109,7 @@ void view_accsum ( const char *desc, uint16_t *acc, uint16_t *itrm ) //--------------------------------------------------------------------------- // FOR BENCHTEST // Original millis() function -unsigned long ICACHE_RAM_ATTR millis_orig ( void ) +unsigned long IRAM_ATTR millis_orig ( void ) { // Get usec system time, usec overflow conter uint32_t m = system_get_time(); @@ -123,7 +123,7 @@ unsigned long ICACHE_RAM_ATTR millis_orig ( void ) // FOR DEBUG // Corrected millis(), 64-bit arithmetic gold standard // truncated to 32-bits by return -unsigned long ICACHE_RAM_ATTR millis_corr_DEBUG( void ) +unsigned long IRAM_ATTR millis_corr_DEBUG( void ) { // Get usec system time, usec overflow conter uint32_t m = system_get_timeA(); // DEBUG @@ -135,7 +135,7 @@ unsigned long ICACHE_RAM_ATTR millis_corr_DEBUG( void ) //--------------------------------------------------------------------------- // FOR BENCHMARK -unsigned long ICACHE_RAM_ATTR millis_corr ( void ) +unsigned long IRAM_ATTR millis_corr ( void ) { // Get usec system time, usec overflow conter uint32_t m = system_get_time(); @@ -229,7 +229,7 @@ unsigned long ICACHE_RAM_ATTR millis_corr ( void ) // // Reference function: corrected millis(), 64-bit arithmetic, // truncated to 32-bits by return -// unsigned long ICACHE_RAM_ATTR millis_corr_DEBUG( void ) +// unsigned long IRAM_ATTR millis_corr_DEBUG( void ) // { // // Get usec system time, usec overflow conter // ...... @@ -246,7 +246,7 @@ unsigned long ICACHE_RAM_ATTR millis_corr ( void ) #define MAGIC_1E3_wLO 0x4bc6a7f0 // LS part #define MAGIC_1E3_wHI 0x00418937 // MS part, magic multiplier -unsigned long ICACHE_RAM_ATTR millis_test_DEBUG ( void ) +unsigned long IRAM_ATTR millis_test_DEBUG ( void ) { union { uint64_t q; // Accumulator, 64-bit, little endian @@ -300,7 +300,7 @@ unsigned long ICACHE_RAM_ATTR millis_test_DEBUG ( void ) //--------------------------------------------------------------------------- // FOR BENCHTEST -unsigned long ICACHE_RAM_ATTR millis_test ( void ) +unsigned long IRAM_ATTR millis_test ( void ) { union { uint64_t q; // Accumulator, 64-bit, little endian diff --git a/tests/host/common/c_types.h b/tests/host/common/c_types.h index 867f2f7726..a4c784c7fb 100644 --- a/tests/host/common/c_types.h +++ b/tests/host/common/c_types.h @@ -94,16 +94,16 @@ typedef enum { #define __ICACHE_STRINGIZE_NX(A) #A #define __ICACHE_STRINGIZE(A) __ICACHE_STRINGIZE_NX(A) #define ICACHE_FLASH_ATTR __attribute__((section("\".irom0.text." __FILE__ "." __ICACHE_STRINGIZE(__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\""))) -#define ICACHE_RAM_ATTR __attribute__((section("\".iram.text." __FILE__ "." __ICACHE_STRINGIZE(__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\""))) +#define IRAM_ATTR __attribute__((section("\".iram.text." __FILE__ "." __ICACHE_STRINGIZE(__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\""))) #define ICACHE_RODATA_ATTR __attribute__((section("\".irom.text." __FILE__ "." __ICACHE_STRINGIZE(__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\""))) #else #define ICACHE_FLASH_ATTR -#define ICACHE_RAM_ATTR +#define IRAM_ATTR #define ICACHE_RODATA_ATTR #endif /* ICACHE_FLASH */ // counterpart https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp8266-compat.h -#define IRAM_ATTR ICACHE_RAM_ATTR +#define ICACHE_RAM_ATTR IRAM_ATTR #define STORE_ATTR __attribute__((aligned(4))) diff --git a/tools/sdk/include/c_types.h b/tools/sdk/include/c_types.h index 88dc147213..0bb7c6df06 100644 --- a/tools/sdk/include/c_types.h +++ b/tools/sdk/include/c_types.h @@ -86,15 +86,15 @@ typedef enum { #ifdef ICACHE_FLASH #define __ICACHE_STRINGIZE_NX(A) #A #define __ICACHE_STRINGIZE(A) __ICACHE_STRINGIZE_NX(A) -#define ICACHE_FLASH_ATTR __attribute__((section("\".irom0.text." __FILE__ "." __ICACHE_STRINGIZE(__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\""))) -#define ICACHE_RAM_ATTR __attribute__((section("\".iram.text." __FILE__ "." __ICACHE_STRINGIZE(__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\""))) +#define ICACHE_FLASH_ATTR __attribute__((section("\".irom0.text." __FILE__ "." __ICACHE_STRINGIZE(__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\""))) +#define IRAM_ATTR __attribute__((section("\".iram.text." __FILE__ "." __ICACHE_STRINGIZE(__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\""))) #else #define ICACHE_FLASH_ATTR -#define ICACHE_RAM_ATTR +#define IRAM_ATTR #endif /* ICACHE_FLASH */ // counterpart https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp8266-compat.h -#define IRAM_ATTR ICACHE_RAM_ATTR +#define ICACHE_RAM_ATTR IRAM_ATTR __attribute__((deprecated("Use IRAM_ATTR in place of ICACHE_RAM_ATTR to move functions into IRAM"))) #define STORE_ATTR __attribute__((aligned(4))) diff --git a/tools/sizes.py b/tools/sizes.py index 470e526c7a..7ce4ff1d99 100755 --- a/tools/sizes.py +++ b/tools/sizes.py @@ -27,7 +27,7 @@ def get_segment_hints(iram): hints = {} hints['ICACHE'] = ' - flash instruction cache' hints['IROM'] = ' - code in flash (default or ICACHE_FLASH_ATTR)' - hints['IRAM'] = ' / ' + str(iram) + ' - code in IRAM (ICACHE_RAM_ATTR, ISRs...)' + hints['IRAM'] = ' / ' + str(iram) + ' - code in IRAM (IRAM_ATTR, ISRs...)' hints['DATA'] = ') - initialized variables (global, static) in RAM/HEAP' hints['RODATA'] = ') / 81920 - constants (global, static) in RAM/HEAP' hints['BSS'] = ') - zeroed variables (global, static) in RAM/HEAP'