1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-06 05:21:22 +03:00

BREAKING - Use IRAM_ATTR in place of ICACHE_RAM_ATTR (#7921)

Update the core to use the define that the ESP32 uses, IRAM_ATTR, for
placing code in DRAM.
This commit is contained in:
Earle F. Philhower, III 2021-03-14 16:56:47 -07:00 committed by GitHub
parent 6743a65987
commit 656a33e6f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 126 additions and 126 deletions

View File

@ -10,7 +10,7 @@ typedef void (*voidFuncPtrArg)(void*);
extern "C" void __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtr userFunc, void*fp, int mode, bool functional); 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; ArgStructure* localArg = (ArgStructure*)arg;
if (localArg->functionInfo->reqScheduledFunction) if (localArg->functionInfo->reqScheduledFunction)

View File

@ -67,7 +67,7 @@ size_t cbuf::resize(size_t newSize) {
return _size; return _size;
} }
size_t ICACHE_RAM_ATTR cbuf::available() const { size_t IRAM_ATTR cbuf::available() const {
if(_end >= _begin) { if(_end >= _begin) {
return _end - _begin; return _end - _begin;
} }
@ -108,7 +108,7 @@ size_t cbuf::peek(char *dst, size_t size) {
return size_read; return size_read;
} }
int ICACHE_RAM_ATTR cbuf::read() { int IRAM_ATTR cbuf::read() {
if(empty()) if(empty())
return -1; return -1;
@ -133,7 +133,7 @@ size_t cbuf::read(char* dst, size_t size) {
return size_read; return size_read;
} }
size_t ICACHE_RAM_ATTR cbuf::write(char c) { size_t IRAM_ATTR cbuf::write(char c) {
if(full()) if(full())
return 0; return 0;

View File

@ -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; if(cont->stack_guard1 != CONT_STACKGUARD || cont->stack_guard2 != CONT_STACKGUARD) return 1;
return 0; return 0;
@ -62,7 +62,7 @@ int cont_get_free_stack(cont_t* cont) {
return freeWords * 4; 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() && return !ETS_INTR_WITHINISR() &&
cont->pc_ret != 0 && cont->pc_yield == 0; cont->pc_ret != 0 && cont->pc_yield == 0;
} }

View File

@ -61,7 +61,7 @@ typedef struct i2s_state {
uint32_t * curr_slc_buf; // Current buffer for writing uint32_t * curr_slc_buf; // Current buffer for writing
uint32_t curr_slc_buf_pos; // Position in the current buffer uint32_t curr_slc_buf_pos; // Position in the current buffer
void (*callback) (void); 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 // and be placed in IRAM for faster execution. Avoid long computational tasks in this
// function, use it to set flags and process later. // function, use it to set flags and process later.
bool driveClocks; bool driveClocks;
@ -139,7 +139,7 @@ uint16_t i2s_rx_available(){
} }
// Pop the top off of the queue and return it // 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; uint8_t i;
uint32_t *item = ch->slc_queue[0]; uint32_t *item = ch->slc_queue[0];
ch->slc_queue_len--; 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 // 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 // Shift everything up, except for the one corresponding to this item
for (int i=0, dest=0; i < ch->slc_queue_len; i++) { for (int i=0, dest=0; i < ch->slc_queue_len; i++) {
if (ch->slc_queue[i] != item) { 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(); ETS_SLC_INTR_DISABLE();
uint32_t slc_intr_status = SLCIS; uint32_t slc_intr_status = SLCIS;
SLCIC = 0xFFFFFFFF; SLCIC = 0xFFFFFFFF;

View File

@ -300,10 +300,10 @@ static const uint8_t ICACHE_FLASH_ATTR phy_init_data[128] =
static bool spoof_init_data = false; static bool spoof_init_data = false;
extern int __real_spi_flash_read(uint32_t addr, uint32_t* dst, size_t size); 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 __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) { if (!spoof_init_data || size != 128) {
return __real_spi_flash_read(addr, dst, size); 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() {}
}; };

View File

@ -103,23 +103,23 @@ private:
ETSTimer timer; ETSTimer timer;
// Event/IRQ callbacks, so they can't use "this" and need to be static // Event/IRQ callbacks, so they can't use "this" and need to be static
static void ICACHE_RAM_ATTR onSclChange(void); static void IRAM_ATTR onSclChange(void);
static void ICACHE_RAM_ATTR onSdaChange(void); static void IRAM_ATTR onSdaChange(void);
static void eventTask(ETSEvent *e); 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 // Allow not linking in the slave code if there is no call to setAddress
bool _slaveEnabled = false; bool _slaveEnabled = false;
// Internal use functions // Internal use functions
void ICACHE_RAM_ATTR busywait(unsigned int v); void IRAM_ATTR busywait(unsigned int v);
bool write_start(void); bool write_start(void);
bool write_stop(void); bool write_stop(void);
bool write_bit(bool bit); bool write_bit(bool bit);
bool read_bit(void); bool read_bit(void);
bool write_byte(unsigned char byte); bool write_byte(unsigned char byte);
unsigned char read_byte(bool nack); 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 // Handle the case where a slave needs to stretch the clock with a time-limited busy wait
inline void WAIT_CLOCK_STRETCH() inline void WAIT_CLOCK_STRETCH()
@ -149,8 +149,8 @@ public:
uint8_t transmit(const uint8_t* data, uint8_t length); uint8_t transmit(const uint8_t* data, uint8_t length);
void attachSlaveRxEvent(void (*function)(uint8_t*, size_t)); void attachSlaveRxEvent(void (*function)(uint8_t*, size_t));
void attachSlaveTxEvent(void (*function)(void)); void attachSlaveTxEvent(void (*function)(void));
void ICACHE_RAM_ATTR reply(uint8_t ack); void IRAM_ATTR reply(uint8_t ack);
void ICACHE_RAM_ATTR releaseBus(void); void IRAM_ATTR releaseBus(void);
void enableSlave(); 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; unsigned int i;
for (i = 0; i < v; i++) // loop time is 5 machine cycles: 31.25ns @ 160MHz, 62.5ns @ 80MHz 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 // 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 // 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 // transmit master read ready signal, with or without ack
if (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 // release bus
//TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT); //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; twip_status = status;
switch (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; (void)unused;
twi.releaseBus(); twi.releaseBus();
@ -662,7 +662,7 @@ void Twi::eventTask(ETSEvent *e)
// Shorthand for if the state is any of the or'd bitmask x // Shorthand for if the state is any of the or'd bitmask x
#define IFSTATE(x) if (twip_state_mask & (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 sda;
unsigned int scl; 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 sda;
unsigned int scl; unsigned int scl;

View File

@ -31,7 +31,7 @@ extern "C" {
static volatile timercallback timer1_user_cb = NULL; 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) para;
(void) frame; (void) frame;
if ((T1C & ((1 << TCAR) | (1 << TCIT))) == 0) TEIE &= ~TEIE1;//edge int disable 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); 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; timer1_user_cb = userFunc;
ETS_FRC1_INTR_ENABLE(); ETS_FRC1_INTR_ENABLE();
} }
void ICACHE_RAM_ATTR timer1_detachInterrupt() { void IRAM_ATTR timer1_detachInterrupt() {
timer1_user_cb = 0; timer1_user_cb = 0;
TEIE &= ~TEIE1;//edge int disable TEIE &= ~TEIE1;//edge int disable
ETS_FRC1_INTR_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); T1C = (1 << TCTE) | ((divider & 3) << TCPD) | ((int_type & 1) << TCIT) | ((reload & 1) << TCAR);
T1I = 0; T1I = 0;
} }
void ICACHE_RAM_ATTR timer1_write(uint32_t ticks){ void IRAM_ATTR timer1_write(uint32_t ticks){
T1L = ((ticks)& 0x7FFFFF); T1L = ((ticks)& 0x7FFFFF);
if ((T1C & (1 << TCIT)) == 0) TEIE |= TEIE1;//edge int enable if ((T1C & (1 << TCIT)) == 0) TEIE |= TEIE1;//edge int enable
} }
void ICACHE_RAM_ATTR timer1_disable(){ void IRAM_ATTR timer1_disable(){
T1C = 0; T1C = 0;
T1I = 0; T1I = 0;
} }
@ -80,7 +80,7 @@ void ICACHE_RAM_ATTR timer1_disable(){
static volatile timercallback timer0_user_cb = NULL; 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) para;
(void) frame; (void) frame;
if (timer0_user_cb) { 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); 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; timer0_user_cb = userFunc;
ETS_CCOMPARE0_ENABLE(); ETS_CCOMPARE0_ENABLE();
} }
void ICACHE_RAM_ATTR timer0_detachInterrupt() { void IRAM_ATTR timer0_detachInterrupt() {
timer0_user_cb = NULL; timer0_user_cb = NULL;
ETS_CCOMPARE0_DISABLE(); ETS_CCOMPARE0_DISABLE();
} }

View File

@ -112,7 +112,7 @@ int stopWaveform(uint8_t pin);
// to determine whether or not to perform an operation. // to determine whether or not to perform an operation.
// Pass in NULL to disable the callback and, if no other waveforms being // Pass in NULL to disable the callback and, if no other waveforms being
// generated, stop the timer as well. // 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)()); void setTimer1Callback(uint32_t (*fn)());

View File

@ -111,7 +111,7 @@ namespace {
} }
// Interrupt on/off control // Interrupt on/off control
static ICACHE_RAM_ATTR void timer1Interrupt(); static IRAM_ATTR void timer1Interrupt();
// Non-speed critical bits // Non-speed critical bits
#pragma GCC optimize ("Os") #pragma GCC optimize ("Os")
@ -125,7 +125,7 @@ static void initTimer() {
timer1_write(IRQLATENCYCCYS); // Cause an interrupt post-haste 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); ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL);
timer1_disable(); timer1_disable();
timer1_isr_init(); 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 // 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 // Can't possibly need to stop anything if there is no timer active
if (!waveform.timer1Running) { if (!waveform.timer1Running) {
return false; 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. // 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. // 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) { if (ISCPUFREQ160MHZ) {
return isCPU2X ? ccys : (ccys >> 1); 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(); const uint32_t isrStartCcy = ESP.getCycleCount();
int32_t clockDrift = isrStartCcy - waveform.nextEventCcy; int32_t clockDrift = isrStartCcy - waveform.nextEventCcy;
const bool isCPU2X = CPU2X & 1; const bool isCPU2X = CPU2X & 1;

View File

@ -93,7 +93,7 @@ static WVFState wvfState;
#pragma GCC optimize ("Os") #pragma GCC optimize ("Os")
// Interrupt on/off control // Interrupt on/off control
static ICACHE_RAM_ATTR void timer1Interrupt(); static IRAM_ATTR void timer1Interrupt();
static bool timerRunning = false; static bool timerRunning = false;
static __attribute__((noinline)) void initTimer() { 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)) { if (T1L > microsecondsToClockCycles(10)) {
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. // If there are no more scheduled activities, shut down Timer 1.
// Otherwise, do nothing. // Otherwise, do nothing.
static ICACHE_RAM_ATTR void disableIdleTimer() { static IRAM_ATTR void disableIdleTimer() {
if (timerRunning && !wvfState.waveformEnabled && !pwmState.cnt && !wvfState.timer1CB) { if (timerRunning && !wvfState.waveformEnabled && !pwmState.cnt && !wvfState.timer1CB) {
ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL); ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL);
timer1_disable(); 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. // 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) // 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; p->pwmUpdate = nullptr;
pwmState.pwmUpdate = p; pwmState.pwmUpdate = p;
MEMBARRIER(); 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%)) // Disable PWM on a specific pin (i.e. when a digitalWrite or analogWrite(0%/100%))
extern bool _stopPWM_weak(uint8_t pin) __attribute__((weak)); 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<<pin) & pwmState.mask)) { if (!((1<<pin) & pwmState.mask)) {
return false; // Pin not actually active return false; // Pin not actually active
} }
@ -430,7 +430,7 @@ void setTimer1Callback(uint32_t (*fn)()) {
// Stops a waveform on a pin // Stops a waveform on a pin
extern int stopWaveform_weak(uint8_t pin) __attribute__((weak)); extern int stopWaveform_weak(uint8_t pin) __attribute__((weak));
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 // Can't possibly need to stop anything if there is no timer active
if (!timerRunning) { if (!timerRunning) {
return false; return false;
@ -454,7 +454,7 @@ ICACHE_RAM_ATTR int stopWaveform_weak(uint8_t pin) {
return true; return true;
} }
static int stopWaveform_bound(uint8_t pin) __attribute__((weakref("stopWaveform_weak"))); static int stopWaveform_bound(uint8_t pin) __attribute__((weakref("stopWaveform_weak")));
ICACHE_RAM_ATTR int stopWaveform(uint8_t pin) { IRAM_ATTR int stopWaveform(uint8_t pin) {
return stopWaveform_bound(pin); return stopWaveform_bound(pin);
} }
@ -464,14 +464,14 @@ ICACHE_RAM_ATTR int stopWaveform(uint8_t pin) {
// Normally would not want two copies like this, but due to different // Normally would not want two copies like this, but due to different
// optimization levels the inline attribute gets lost if we try the // optimization levels the inline attribute gets lost if we try the
// other version. // other version.
static inline ICACHE_RAM_ATTR uint32_t GetCycleCountIRQ() { static inline IRAM_ATTR uint32_t GetCycleCountIRQ() {
uint32_t ccount; uint32_t ccount;
__asm__ __volatile__("rsr %0,ccount":"=a"(ccount)); __asm__ __volatile__("rsr %0,ccount":"=a"(ccount));
return ccount; return ccount;
} }
// Find the earliest cycle as compared to right now // Find the earliest cycle as compared to right now
static inline ICACHE_RAM_ATTR uint32_t earliest(uint32_t a, uint32_t b) { static inline IRAM_ATTR uint32_t earliest(uint32_t a, uint32_t b) {
uint32_t now = GetCycleCountIRQ(); uint32_t now = GetCycleCountIRQ();
int32_t da = a - now; int32_t da = a - now;
int32_t db = b - now; int32_t db = b - now;
@ -496,7 +496,7 @@ static inline ICACHE_RAM_ATTR uint32_t earliest(uint32_t a, uint32_t b) {
// When the time to the next edge is greater than this, RTI and set another IRQ to minimize CPU usage // When the time to the next edge is greater than this, RTI and set another IRQ to minimize CPU usage
#define MINIRQTIME microsecondsToClockCycles(4) #define MINIRQTIME microsecondsToClockCycles(4)
static ICACHE_RAM_ATTR void timer1Interrupt() { static IRAM_ATTR void timer1Interrupt() {
// Flag if the core is at 160 MHz, for use by adjust() // Flag if the core is at 160 MHz, for use by adjust()
bool turbo = (*(uint32_t*)0x3FF00014) & 1 ? true : false; bool turbo = (*(uint32_t*)0x3FF00014) & 1 ? true : false;

View File

@ -149,7 +149,7 @@ void micros_overflow_tick(void* arg) {
// //
// Reference function: corrected millis(), 64-bit arithmetic, // Reference function: corrected millis(), 64-bit arithmetic,
// truncated to 32-bits by return // 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 // // Get usec system time, usec overflow conter
// ...... // ......
@ -163,7 +163,7 @@ void micros_overflow_tick(void* arg) {
#define MAGIC_1E3_wLO 0x4bc6a7f0 // LS part #define MAGIC_1E3_wLO 0x4bc6a7f0 // LS part
#define MAGIC_1E3_wHI 0x00418937 // MS part, magic multiplier #define MAGIC_1E3_wHI 0x00418937 // MS part, magic multiplier
unsigned long ICACHE_RAM_ATTR millis() unsigned long IRAM_ATTR millis()
{ {
union { union {
uint64_t q; // Accumulator, 64-bit, little endian uint64_t q; // Accumulator, 64-bit, little endian
@ -194,18 +194,18 @@ unsigned long ICACHE_RAM_ATTR millis()
} //millis } //millis
unsigned long ICACHE_RAM_ATTR micros() { unsigned long IRAM_ATTR micros() {
return system_get_time(); return system_get_time();
} }
uint64_t ICACHE_RAM_ATTR micros64() { uint64_t IRAM_ATTR micros64() {
uint32_t low32_us = system_get_time(); uint32_t low32_us = system_get_time();
uint32_t high32_us = micros_overflow_count + ((low32_us < micros_at_last_overflow_tick) ? 1 : 0); uint32_t high32_us = micros_overflow_count + ((low32_us < micros_at_last_overflow_tick) ? 1 : 0);
uint64_t duration64_us = (uint64_t)high32_us << 32 | low32_us; uint64_t duration64_us = (uint64_t)high32_us << 32 | low32_us;
return duration64_us; return duration64_us;
} }
void ICACHE_RAM_ATTR delayMicroseconds(unsigned int us) { void IRAM_ATTR delayMicroseconds(unsigned int us) {
os_delay_us(us); os_delay_us(us);
} }

View File

@ -81,7 +81,7 @@ extern void __pinMode(uint8_t pin, uint8_t mode) {
} }
} }
extern void ICACHE_RAM_ATTR __digitalWrite(uint8_t pin, uint8_t val) { extern void IRAM_ATTR __digitalWrite(uint8_t pin, uint8_t val) {
stopWaveform(pin); // Disable any Tone or startWaveform on this pin stopWaveform(pin); // Disable any Tone or startWaveform on this pin
_stopPWM(pin); // and any analogWrites (PWM) _stopPWM(pin); // and any analogWrites (PWM)
if(pin < 16){ if(pin < 16){
@ -93,7 +93,7 @@ extern void ICACHE_RAM_ATTR __digitalWrite(uint8_t pin, uint8_t val) {
} }
} }
extern int ICACHE_RAM_ATTR __digitalRead(uint8_t pin) { extern int IRAM_ATTR __digitalRead(uint8_t pin) {
if(pin < 16){ if(pin < 16){
return GPIP(pin); return GPIP(pin);
} else if(pin == 16){ } else if(pin == 16){
@ -131,7 +131,7 @@ typedef struct {
static interrupt_handler_t interrupt_handlers[16] = { {0, 0, 0, 0}, }; static interrupt_handler_t interrupt_handlers[16] = { {0, 0, 0, 0}, };
static uint32_t interrupt_reg = 0; static uint32_t interrupt_reg = 0;
void ICACHE_RAM_ATTR interrupt_handler(void *arg, void *frame) void IRAM_ATTR interrupt_handler(void *arg, void *frame)
{ {
(void) arg; (void) arg;
(void) frame; (void) frame;
@ -218,7 +218,7 @@ extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void* arg
__attachInterruptFunctionalArg(pin, userFunc, arg, mode, false); __attachInterruptFunctionalArg(pin, userFunc, arg, mode, false);
} }
extern void ICACHE_RAM_ATTR __detachInterrupt(uint8_t pin) { extern void IRAM_ATTR __detachInterrupt(uint8_t pin) {
if (pin < 16) if (pin < 16)
{ {
ETS_GPIO_INTR_DISABLE(); ETS_GPIO_INTR_DISABLE();

View File

@ -26,7 +26,7 @@
same stub can be used for gdb_present. */ same stub can be used for gdb_present. */
extern "C" { extern "C" {
static bool ICACHE_RAM_ATTR __gdb_no_op() static bool IRAM_ATTR __gdb_no_op()
{ {
return false; return false;
} }

View File

@ -164,7 +164,7 @@ void* _calloc_r(struct _reent* unused, size_t count, size_t size)
#define DEBUG_HEAP_PRINTF ets_uart_printf #define DEBUG_HEAP_PRINTF ets_uart_printf
void ICACHE_RAM_ATTR print_loc(size_t size, const char* file, int line) void IRAM_ATTR print_loc(size_t size, const char* file, int line)
{ {
(void)size; (void)size;
(void)line; (void)line;
@ -186,7 +186,7 @@ void ICACHE_RAM_ATTR print_loc(size_t size, const char* file, int line)
} }
} }
void ICACHE_RAM_ATTR print_oom_size(size_t size) void IRAM_ATTR print_oom_size(size_t size)
{ {
(void)size; (void)size;
if (system_get_os_print()) { if (system_get_os_print()) {
@ -232,7 +232,7 @@ void ICACHE_RAM_ATTR print_oom_size(size_t size)
For malloc(), calloc(), and zalloc() Full Posion Check is done 1st since For malloc(), calloc(), and zalloc() Full Posion Check is done 1st since
these functions do not modify an existing allocation. these functions do not modify an existing allocation.
*/ */
void* ICACHE_RAM_ATTR malloc(size_t size) void* IRAM_ATTR malloc(size_t size)
{ {
INTEGRITY_CHECK__ABORT(); INTEGRITY_CHECK__ABORT();
POISON_CHECK__ABORT(); POISON_CHECK__ABORT();
@ -242,7 +242,7 @@ void* ICACHE_RAM_ATTR malloc(size_t size)
return ret; return ret;
} }
void* ICACHE_RAM_ATTR calloc(size_t count, size_t size) void* IRAM_ATTR calloc(size_t count, size_t size)
{ {
INTEGRITY_CHECK__ABORT(); INTEGRITY_CHECK__ABORT();
POISON_CHECK__ABORT(); POISON_CHECK__ABORT();
@ -252,7 +252,7 @@ void* ICACHE_RAM_ATTR calloc(size_t count, size_t size)
return ret; return ret;
} }
void* ICACHE_RAM_ATTR realloc(void* ptr, size_t size) void* IRAM_ATTR realloc(void* ptr, size_t size)
{ {
INTEGRITY_CHECK__ABORT(); INTEGRITY_CHECK__ABORT();
void* ret = UMM_REALLOC_FL(ptr, size, NULL, 0); void* ret = UMM_REALLOC_FL(ptr, size, NULL, 0);
@ -262,7 +262,7 @@ void* ICACHE_RAM_ATTR realloc(void* ptr, size_t size)
return ret; return ret;
} }
void ICACHE_RAM_ATTR free(void* p) void IRAM_ATTR free(void* p)
{ {
INTEGRITY_CHECK__ABORT(); INTEGRITY_CHECK__ABORT();
UMM_FREE_FL(p, NULL, 0); UMM_FREE_FL(p, NULL, 0);
@ -271,7 +271,7 @@ void ICACHE_RAM_ATTR free(void* p)
#endif #endif
STATIC_ALWAYS_INLINE STATIC_ALWAYS_INLINE
void* ICACHE_RAM_ATTR heap_pvPortMalloc(size_t size, const char* file, int line) void* IRAM_ATTR heap_pvPortMalloc(size_t size, const char* file, int line)
{ {
INTEGRITY_CHECK__PANIC_FL(file, line); INTEGRITY_CHECK__PANIC_FL(file, line);
POISON_CHECK__PANIC_FL(file, line); POISON_CHECK__PANIC_FL(file, line);
@ -282,7 +282,7 @@ void* ICACHE_RAM_ATTR heap_pvPortMalloc(size_t size, const char* file, int line)
} }
STATIC_ALWAYS_INLINE STATIC_ALWAYS_INLINE
void* ICACHE_RAM_ATTR heap_pvPortCalloc(size_t count, size_t size, const char* file, int line) void* IRAM_ATTR heap_pvPortCalloc(size_t count, size_t size, const char* file, int line)
{ {
INTEGRITY_CHECK__PANIC_FL(file, line); INTEGRITY_CHECK__PANIC_FL(file, line);
POISON_CHECK__PANIC_FL(file, line); POISON_CHECK__PANIC_FL(file, line);
@ -293,7 +293,7 @@ void* ICACHE_RAM_ATTR heap_pvPortCalloc(size_t count, size_t size, const char* f
} }
STATIC_ALWAYS_INLINE STATIC_ALWAYS_INLINE
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)
{ {
INTEGRITY_CHECK__PANIC_FL(file, line); INTEGRITY_CHECK__PANIC_FL(file, line);
void* ret = UMM_REALLOC_FL(ptr, size, file, line); void* ret = UMM_REALLOC_FL(ptr, size, file, line);
@ -304,7 +304,7 @@ void* ICACHE_RAM_ATTR heap_pvPortRealloc(void *ptr, size_t size, const char* fil
} }
STATIC_ALWAYS_INLINE STATIC_ALWAYS_INLINE
void* ICACHE_RAM_ATTR heap_pvPortZalloc(size_t size, const char* file, int line) void* IRAM_ATTR heap_pvPortZalloc(size_t size, const char* file, int line)
{ {
INTEGRITY_CHECK__PANIC_FL(file, line); INTEGRITY_CHECK__PANIC_FL(file, line);
POISON_CHECK__PANIC_FL(file, line); POISON_CHECK__PANIC_FL(file, line);
@ -315,14 +315,14 @@ void* ICACHE_RAM_ATTR heap_pvPortZalloc(size_t size, const char* file, int line)
} }
STATIC_ALWAYS_INLINE STATIC_ALWAYS_INLINE
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)
{ {
INTEGRITY_CHECK__PANIC_FL(file, line); INTEGRITY_CHECK__PANIC_FL(file, line);
UMM_FREE_FL(ptr, file, line); UMM_FREE_FL(ptr, file, line);
POISON_CHECK__PANIC_FL(file, line); POISON_CHECK__PANIC_FL(file, line);
} }
size_t ICACHE_RAM_ATTR xPortWantedSizeAlign(size_t size) size_t IRAM_ATTR xPortWantedSizeAlign(size_t size)
{ {
return (size + 3) & ~((size_t) 3); return (size + 3) & ~((size_t) 3);
} }
@ -338,31 +338,31 @@ void system_show_malloc(void)
malloc calls pvPortMalloc, ... we can leverage that for this solution. malloc calls pvPortMalloc, ... we can leverage that for this solution.
Force pvPortMalloc, ... APIs to serve DRAM only. Force pvPortMalloc, ... APIs to serve DRAM only.
*/ */
void* ICACHE_RAM_ATTR pvPortMalloc(size_t size, const char* file, int line) void* IRAM_ATTR pvPortMalloc(size_t size, const char* file, int line)
{ {
HeapSelectDram ephemeral; HeapSelectDram ephemeral;
return heap_pvPortMalloc(size, file, line);; return heap_pvPortMalloc(size, file, line);;
} }
void* ICACHE_RAM_ATTR pvPortCalloc(size_t count, size_t size, const char* file, int line) void* IRAM_ATTR pvPortCalloc(size_t count, size_t size, const char* file, int line)
{ {
HeapSelectDram ephemeral; HeapSelectDram ephemeral;
return heap_pvPortCalloc(count, size, file, line); return heap_pvPortCalloc(count, size, file, line);
} }
void* ICACHE_RAM_ATTR pvPortRealloc(void *ptr, size_t size, const char* file, int line) void* IRAM_ATTR pvPortRealloc(void *ptr, size_t size, const char* file, int line)
{ {
HeapSelectDram ephemeral; HeapSelectDram ephemeral;
return heap_pvPortRealloc(ptr, size, file, line); return heap_pvPortRealloc(ptr, size, file, line);
} }
void* ICACHE_RAM_ATTR pvPortZalloc(size_t size, const char* file, int line) void* IRAM_ATTR pvPortZalloc(size_t size, const char* file, int line)
{ {
HeapSelectDram ephemeral; HeapSelectDram ephemeral;
return heap_pvPortZalloc(size, file, line); return heap_pvPortZalloc(size, file, line);
} }
void ICACHE_RAM_ATTR vPortFree(void *ptr, const char* file, int line) void IRAM_ATTR vPortFree(void *ptr, const char* file, int line)
{ {
#if defined(DEBUG_ESP_OOM) || defined(UMM_POISON_CHECK) || defined(UMM_POISON_CHECK_LITE) || defined(UMM_INTEGRITY_CHECK) #if defined(DEBUG_ESP_OOM) || defined(UMM_POISON_CHECK) || defined(UMM_POISON_CHECK_LITE) || defined(UMM_INTEGRITY_CHECK)
// This is only needed for debug checks to ensure they are performed in // This is only needed for debug checks to ensure they are performed in

View File

@ -47,27 +47,27 @@
extern "C" { extern "C" {
int ICACHE_RAM_ATTR _open_r (struct _reent* unused, const char *ptr, int mode) { int IRAM_ATTR _open_r (struct _reent* unused, const char *ptr, int mode) {
(void)unused; (void)unused;
(void)ptr; (void)ptr;
(void)mode; (void)mode;
return 0; return 0;
} }
int ICACHE_RAM_ATTR _close_r(struct _reent* unused, int file) { int IRAM_ATTR _close_r(struct _reent* unused, int file) {
(void)unused; (void)unused;
(void)file; (void)file;
return 0; return 0;
} }
int ICACHE_RAM_ATTR _fstat_r(struct _reent* unused, int file, struct stat *st) { int IRAM_ATTR _fstat_r(struct _reent* unused, int file, struct stat *st) {
(void)unused; (void)unused;
(void)file; (void)file;
st->st_mode = S_IFCHR; st->st_mode = S_IFCHR;
return 0; 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)unused;
(void)file; (void)file;
(void)ptr; (void)ptr;
@ -75,7 +75,7 @@ int ICACHE_RAM_ATTR _lseek_r(struct _reent* unused, int file, int ptr, int dir)
return 0; 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)unused;
(void)file; (void)file;
(void)ptr; (void)ptr;
@ -83,7 +83,7 @@ int ICACHE_RAM_ATTR _read_r(struct _reent* unused, int file, char *ptr, int len)
return 0; 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; (void) r;
int pos = len; int pos = len;
if (file == STDOUT_FILENO) { 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; 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; (void) r;
if (file->_file == STDOUT_FILENO) { if (file->_file == STDOUT_FILENO) {
ets_putc(c); ets_putc(c);
@ -106,7 +106,7 @@ int ICACHE_RAM_ATTR _putc_r(struct _reent* r, int c, FILE* file) {
return EOF; return EOF;
} }
int ICACHE_RAM_ATTR puts(const char * str) { int IRAM_ATTR puts(const char * str) {
char c; char c;
while((c = *str) != 0) { while((c = *str) != 0) {
ets_putc(c); ets_putc(c);
@ -117,7 +117,7 @@ int ICACHE_RAM_ATTR puts(const char * str) {
} }
#undef putchar #undef putchar
int ICACHE_RAM_ATTR putchar(int c) { int IRAM_ATTR putchar(int c) {
ets_putc(c); ets_putc(c);
return c; return c;
} }

View File

@ -52,7 +52,7 @@ static inline void __wsr_vecbase(uint32_t vector_base) {
asm volatile("wsr.vecbase %0" :: "r" (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() */ /* reverse engineered from system_restart_core() */
/* Before disabling instruction cache and restoring instruction RAM to a /* Before disabling instruction cache and restoring instruction RAM to a

View File

@ -115,7 +115,7 @@ struct uart_
// called by ISR // called by ISR
inline size_t ICACHE_RAM_ATTR inline size_t IRAM_ATTR
uart_rx_fifo_available(const int uart_nr) uart_rx_fifo_available(const int uart_nr)
{ {
return (USS(uart_nr) >> USRXC) & 0xFF; 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 // Copy all the rx fifo bytes that fit into the rx buffer
// called by ISR // called by ISR
inline void ICACHE_RAM_ATTR inline void IRAM_ATTR
uart_rx_copy_fifo_to_buffer_unsafe(uart_t* uart) uart_rx_copy_fifo_to_buffer_unsafe(uart_t* uart)
{ {
struct uart_rx_buffer_ *rx_buffer = uart->rx_buffer; 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() // 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 // Since we've already read the bytes from the FIFO, can't use that
// function directly and need to implement it bytewise here // 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; uart_t* uart = (uart_t*)arg;
if(uart == NULL || !uart->rx_enabled) { 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 // The default ISR handler called when GDB is not enabled
void ICACHE_RAM_ATTR void IRAM_ATTR
uart_isr(void * arg, void * frame) uart_isr(void * arg, void * frame)
{ {
(void) frame; (void) frame;

View File

@ -793,11 +793,11 @@ extern "C" {
#include <pgmspace.h> #include <pgmspace.h>
// Reuse pvPort* calls, since they already support passing location information. // Reuse pvPort* calls, since they already support passing location information.
// Specificly the debug version (heap_...) that does not force DRAM heap. // 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* IRAM_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* IRAM_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* IRAM_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* IRAM_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_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 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__); }) #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) #elif defined(UMM_POISON_CHECK) || defined(UMM_POISON_CHECK_LITE)
#include <pgmspace.h> #include <pgmspace.h>
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__); }) #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 //C - to be discussed
/* /*
Problem, I would like to report the file and line number with the umm poison Problem, I would like to report the file and line number with the umm poison

View File

@ -247,8 +247,8 @@ Interrupt Service Routines
cache may kick in for that code. However, the cache currently can't be used 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 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 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 IRAM_ATTR attribute declared. Not only that, but the entire function tree
called from the ISR must also have the ICACHE_RAM_ATTR declared. called from the ISR must also have the IRAM_ATTR declared.
Be aware that every function that has this attribute reduces available memory. 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, In addition, it is not possible to execute delay() or yield() from an ISR,

View File

@ -9,13 +9,13 @@ and have several limitations:
* Interrupt callback functions must be in IRAM, because the flash may be * 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 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 attribute is not present, the sketch will crash when it attempts to
``attachInterrupt`` with an error message. ``attachInterrupt`` with an error message.
.. code:: cpp .. 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 * Interrupts must not call ``delay()`` or ``yield()``, or call any routines
which internally use ``delay()`` or ``yield()`` either. 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 ``detachInterrupt`` functions. Interrupts may be attached to any GPIO
pin, except GPIO16. Standard Arduino interrupt types are supported: pin, except GPIO16. Standard Arduino interrupt types are supported:
``CHANGE``, ``RISING``, ``FALLING``. ISRs need to have ``CHANGE``, ``RISING``, ``FALLING``. ISRs need to have
``ICACHE_RAM_ATTR`` before the function definition. ``IRAM_ATTR`` before the function definition.
Analog input Analog input
------------ ------------

View File

@ -67,7 +67,7 @@ likely crash.
#define ATTR_GDBINIT ICACHE_FLASH_ATTR #define ATTR_GDBINIT ICACHE_FLASH_ATTR
#endif #endif
#ifndef ATTR_GDBFN #ifndef ATTR_GDBFN
#define ATTR_GDBFN ICACHE_RAM_ATTR #define ATTR_GDBFN IRAM_ATTR
#endif #endif
#ifndef ATTR_GDBEXTERNFN #ifndef ATTR_GDBEXTERNFN
#define ATTR_GDBEXTERNFN ICACHE_FLASH_ATTR #define ATTR_GDBEXTERNFN ICACHE_FLASH_ATTR

View File

@ -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 void (*_hspi_slave_tx_status_cb)(void * arg) = NULL;
static uint8_t _hspi_slave_buffer[33]; 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; (void) frame;
uint32_t status; uint32_t status;
@ -124,7 +124,7 @@ void hspi_slave_end()
SPI1P = B110; SPI1P = B110;
} }
void ICACHE_RAM_ATTR hspi_slave_setStatus(uint32_t status) void IRAM_ATTR hspi_slave_setStatus(uint32_t status)
{ {
SPI1WS = status; SPI1WS = status;
} }

View File

@ -109,7 +109,7 @@ void view_accsum ( const char *desc, uint16_t *acc, uint16_t *itrm )
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// FOR BENCHTEST // FOR BENCHTEST
// Original millis() function // 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 // Get usec system time, usec overflow conter
uint32_t m = system_get_time(); uint32_t m = system_get_time();
@ -123,7 +123,7 @@ unsigned long ICACHE_RAM_ATTR millis_orig ( void )
// FOR DEBUG // FOR DEBUG
// Corrected millis(), 64-bit arithmetic gold standard // Corrected millis(), 64-bit arithmetic gold standard
// truncated to 32-bits by return // 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 // Get usec system time, usec overflow conter
uint32_t m = system_get_timeA(); // DEBUG uint32_t m = system_get_timeA(); // DEBUG
@ -135,7 +135,7 @@ unsigned long ICACHE_RAM_ATTR millis_corr_DEBUG( void )
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// FOR BENCHMARK // FOR BENCHMARK
unsigned long ICACHE_RAM_ATTR millis_corr ( void ) unsigned long IRAM_ATTR millis_corr ( void )
{ {
// Get usec system time, usec overflow conter // Get usec system time, usec overflow conter
uint32_t m = system_get_time(); 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, // Reference function: corrected millis(), 64-bit arithmetic,
// truncated to 32-bits by return // 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 // // 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_wLO 0x4bc6a7f0 // LS part
#define MAGIC_1E3_wHI 0x00418937 // MS part, magic multiplier #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 { union {
uint64_t q; // Accumulator, 64-bit, little endian uint64_t q; // Accumulator, 64-bit, little endian
@ -300,7 +300,7 @@ unsigned long ICACHE_RAM_ATTR millis_test_DEBUG ( void )
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// FOR BENCHTEST // FOR BENCHTEST
unsigned long ICACHE_RAM_ATTR millis_test ( void ) unsigned long IRAM_ATTR millis_test ( void )
{ {
union { union {
uint64_t q; // Accumulator, 64-bit, little endian uint64_t q; // Accumulator, 64-bit, little endian

View File

@ -94,16 +94,16 @@ typedef enum {
#define __ICACHE_STRINGIZE_NX(A) #A #define __ICACHE_STRINGIZE_NX(A) #A
#define __ICACHE_STRINGIZE(A) __ICACHE_STRINGIZE_NX(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_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__) "\""))) #define ICACHE_RODATA_ATTR __attribute__((section("\".irom.text." __FILE__ "." __ICACHE_STRINGIZE(__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\"")))
#else #else
#define ICACHE_FLASH_ATTR #define ICACHE_FLASH_ATTR
#define ICACHE_RAM_ATTR #define IRAM_ATTR
#define ICACHE_RODATA_ATTR #define ICACHE_RODATA_ATTR
#endif /* ICACHE_FLASH */ #endif /* ICACHE_FLASH */
// counterpart https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp8266-compat.h // 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))) #define STORE_ATTR __attribute__((aligned(4)))

View File

@ -86,15 +86,15 @@ typedef enum {
#ifdef ICACHE_FLASH #ifdef ICACHE_FLASH
#define __ICACHE_STRINGIZE_NX(A) #A #define __ICACHE_STRINGIZE_NX(A) #A
#define __ICACHE_STRINGIZE(A) __ICACHE_STRINGIZE_NX(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_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__) "\"")))
#else #else
#define ICACHE_FLASH_ATTR #define ICACHE_FLASH_ATTR
#define ICACHE_RAM_ATTR #define IRAM_ATTR
#endif /* ICACHE_FLASH */ #endif /* ICACHE_FLASH */
// counterpart https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp8266-compat.h // 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))) #define STORE_ATTR __attribute__((aligned(4)))

View File

@ -27,7 +27,7 @@ def get_segment_hints(iram):
hints = {} hints = {}
hints['ICACHE'] = ' - flash instruction cache' hints['ICACHE'] = ' - flash instruction cache'
hints['IROM'] = ' - code in flash (default or ICACHE_FLASH_ATTR)' 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['DATA'] = ') - initialized variables (global, static) in RAM/HEAP'
hints['RODATA'] = ') / 81920 - constants (global, static) in RAM/HEAP' hints['RODATA'] = ') / 81920 - constants (global, static) in RAM/HEAP'
hints['BSS'] = ') - zeroed variables (global, static) in RAM/HEAP' hints['BSS'] = ') - zeroed variables (global, static) in RAM/HEAP'