1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-03 07:02:28 +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);
void ICACHE_RAM_ATTR interruptFunctional(void* arg)
void IRAM_ATTR interruptFunctional(void* arg)
{
ArgStructure* localArg = (ArgStructure*)arg;
if (localArg->functionInfo->reqScheduledFunction)

View File

@ -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;

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;
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;
}

View File

@ -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;

View File

@ -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() {}
};

View File

@ -103,23 +103,23 @@ private:
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 @@ public:
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;

View File

@ -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();
}

View File

@ -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)());

View File

@ -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;

View File

@ -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<<pin) & pwmState.mask)) {
return false; // Pin not actually active
}
@ -430,7 +430,7 @@ void setTimer1Callback(uint32_t (*fn)()) {
// Stops a waveform on a pin
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
if (!timerRunning) {
return false;
@ -454,7 +454,7 @@ ICACHE_RAM_ATTR int stopWaveform_weak(uint8_t pin) {
return true;
}
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);
}
@ -464,14 +464,14 @@ ICACHE_RAM_ATTR int stopWaveform(uint8_t pin) {
// Normally would not want two copies like this, but due to different
// optimization levels the inline attribute gets lost if we try the
// other version.
static inline ICACHE_RAM_ATTR uint32_t GetCycleCountIRQ() {
static inline IRAM_ATTR uint32_t GetCycleCountIRQ() {
uint32_t ccount;
__asm__ __volatile__("rsr %0,ccount":"=a"(ccount));
return ccount;
}
// 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();
int32_t da = a - 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
#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()
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,
// 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
// ......
@ -163,7 +163,7 @@ void micros_overflow_tick(void* arg) {
#define MAGIC_1E3_wLO 0x4bc6a7f0 // LS part
#define MAGIC_1E3_wHI 0x00418937 // MS part, magic multiplier
unsigned long ICACHE_RAM_ATTR millis()
unsigned long IRAM_ATTR millis()
{
union {
uint64_t q; // Accumulator, 64-bit, little endian
@ -194,18 +194,18 @@ unsigned long ICACHE_RAM_ATTR millis()
} //millis
unsigned long ICACHE_RAM_ATTR micros() {
unsigned long IRAM_ATTR micros() {
return system_get_time();
}
uint64_t ICACHE_RAM_ATTR micros64() {
uint64_t IRAM_ATTR micros64() {
uint32_t low32_us = system_get_time();
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;
return duration64_us;
}
void ICACHE_RAM_ATTR delayMicroseconds(unsigned int us) {
void IRAM_ATTR delayMicroseconds(unsigned int 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
_stopPWM(pin); // and any analogWrites (PWM)
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){
return GPIP(pin);
} else if(pin == 16){
@ -131,7 +131,7 @@ typedef struct {
static interrupt_handler_t interrupt_handlers[16] = { {0, 0, 0, 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) frame;
@ -218,7 +218,7 @@ extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void* arg
__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)
{
ETS_GPIO_INTR_DISABLE();

View File

@ -26,7 +26,7 @@
same stub can be used for gdb_present. */
extern "C" {
static bool ICACHE_RAM_ATTR __gdb_no_op()
static bool IRAM_ATTR __gdb_no_op()
{
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
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)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;
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
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();
POISON_CHECK__ABORT();
@ -242,7 +242,7 @@ void* ICACHE_RAM_ATTR malloc(size_t size)
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();
POISON_CHECK__ABORT();
@ -252,7 +252,7 @@ void* ICACHE_RAM_ATTR calloc(size_t count, size_t size)
return ret;
}
void* ICACHE_RAM_ATTR realloc(void* ptr, size_t size)
void* IRAM_ATTR realloc(void* ptr, size_t size)
{
INTEGRITY_CHECK__ABORT();
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;
}
void ICACHE_RAM_ATTR free(void* p)
void IRAM_ATTR free(void* p)
{
INTEGRITY_CHECK__ABORT();
UMM_FREE_FL(p, NULL, 0);
@ -271,7 +271,7 @@ void ICACHE_RAM_ATTR free(void* p)
#endif
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);
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
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);
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
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);
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
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);
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
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);
UMM_FREE_FL(ptr, 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);
}
@ -338,31 +338,31 @@ void system_show_malloc(void)
malloc calls pvPortMalloc, ... we can leverage that for this solution.
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;
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;
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;
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;
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)
// This is only needed for debug checks to ensure they are performed in

View File

@ -47,27 +47,27 @@
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)ptr;
(void)mode;
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)file;
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)file;
st->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;
}

View File

@ -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

View File

@ -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;

View File

@ -793,11 +793,11 @@ extern "C" {
#include <pgmspace.h>
// 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 <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__); })
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

View File

@ -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,

View File

@ -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
------------

View File

@ -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

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 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;
}

View File

@ -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

View File

@ -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)))

View File

@ -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)))

View File

@ -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'