Arduino: Latest Core - crash at boot with ISR not in IRAM error

Created on 22 May 2019  路  20Comments  路  Source: esp8266/Arduino

Basic Infos

  • [X ] This issue complies with the issue POLICY doc.
  • [X ] I have read the documentation at readthedocs and the issue is not addressed there.
  • [X ] I have tested that the issue is present in current master branch (aka latest git).
  • [X ] I have searched the issue tracker for a similar issue.
  • [ ] If there is a stack dump, I have decoded it.
  • [X ] I have filled out all fields below.

Platform

  • Hardware: ESP-12 NodeMCU & others
  • Core Version: 2.5.2
  • Development Env: Arduino IDE
  • Operating System: LinuxMint

Settings in IDE

  • Module: [Generic ESP8266 Module|Wemos D1 mini r2|Nodemcu|other]
  • Flash Mode: [qio|dio|other]
  • Flash Size: [4MB/1MB]
  • lwip Variant: [v1.4|v2 Lower Memory|Higher Bandwidth]
  • Reset Method: [ck|nodemcu]
  • Flash Frequency: [40Mhz]
  • CPU Frequency: [80Mhz|160MHz]
  • Upload Using: [OTA|SERIAL]
  • Upload Speed: [115200|other] (serial upload only)

Problem Description

I upgraded to the latest core this morning from the previous core. Two of my sketches
which use external interrupts, crash at boot up with an errors of ISR not in IRAM
(I have seen this with ESP32 before, but not with ESP8266)
Adding the IRAM_ATTR viz. void IRAM_ATTR test_interrupt(), causes a compiler error
expected initializer before 'test_interupt'

The IRAM_ATTR is not highlighted indicating that it is not supported!

Most helpful comment

The fix is: add ICACHE_RAM_ATTR just before all functions called from an interrupt (attach_interrupt)

All 20 comments

Here it's called ICACHE_RAM_ATTR.
Closing.

edit from @d-a-v: IRAM_ATTR is now also defined in this core

Thanks! I could not find any reference in the docs for ESP8266..

What would be the fix?

Hi,
Got also this on boot error with a simple toggle volatile byte in ISR. Is there anything to do?

I fixed the platform to:

platform = [email protected]

It helped for now.

The fix is: add ICACHE_RAM_ATTR just before all functions called from an interrupt (attach_interrupt)

@d-a-v i don't have time to check what changes are in newer arduino core but what i don't like is that pio upload tool doesn't have upload status signaling. You have no idea if it is uploading or not or how much more you need to wait.

Hi, I'm working on a project involving a WEMOS D1 mini pro board (ESP8266-based). The Arduino IDE been upgraded (to 1.8.9) and so the ESP8266 core (to 2.5.2). In this project I use an RFM69 module and library from LowPower. I got the ISR not in IRAM issue at RFM69 module initialization and fix using the RFM69 library with a proposal by @torntrousers with LoRa library... but RFM69 maintainer sees that more as an ESP bug instead of fixing the RFM69 library. That setup used to work just fine before upgrading the ESP8266 core (I had 2.5.0, I think). How do you guys see that?

In the ESP, all ISRs must be in iram, and all functions called from all ISRs must be in iram, and so on. This has always been a requirement, and not complying has been an endless source of issues akin to "I get a crash after updating" or "I changed code X and now it crashes, I don't know why". Users don't know, or forget about this.
Non compliance means that it may or may not work depending on luck, and unrelated code changes could change that luck. In a recent core version, we are now enforcing that at least the top level ISR function is in IRAM. If it is not, panic with a msg to let you know.
To be absolutely crystal clear, not specifying the iram attr for an ISR is a bug by the user. Enforcement of the top level ISR is now uncovering a whole bunch of such user-side bugs where the attr is missing.

Thanks @devyte , I'd wondered about the other functions called by the ISR. In that LoRa library mentioned in a previous comment the ISR uses all this code, so I also need to add the ICACHE_RAM_ATTR to those 3 functions, but are all the ESP8266 core functions used in that code like the digitalWrite and SPI functions already using ICACHE_RAM_ATTR ?

Is that code doing an spi transaction from an ISR??? There are strict timing requirements on the exec time of an ISR in the ESP. Blocking operations are a big no no, and in general ISRs shouldn't take more than a few us. At a glance, I don't think that code will work, at least not with wifi running.
I would advise an ESP user to set a flag in the ISR and execute from the loop, or use the scheduled function api (runs a cb as though it were in the loop).

Adding a NOTE here:
There is a real solution, and its not something that can be done in this repo yet.
Arduino NEEDS to provide an official "abstracted" symbol for ISR routines, that on AVR may map to nothing, but on Esp8266 would map to the required ICACHE_RAM_ATTR. This issue will continue to appear as different platforms try to support Arduino. Once they have that, then this repo should support it by having a mapping for the official abstract ISR attribute to ICACHE_RAM_ATTR.

https://groups.google.com/a/arduino.cc/forum/#!topic/developers/56VPC9t2MPc

I'm aware of your discussion at the arduino forum. I wish you the best in the discussion. If your propisal is accepted, we can implement whatever is needed here.

can anyone explain briefly where we need to add ICACHE_RAM_ATTR attr???????

in most Arduino code you will find the interrupt service routines implemented like ...

void IsrDoSomething(blah) { 
}

In the Esp world, you need to attribute these routines like ...

void ICACHE_RAM_ATTR IsrDoSomething(blah) {
}

There is no mention of this in the documentation .
There is also no mention of this on a few online how-to's that I just checked.
Could you please add this info to the documentation? I can't see how the average user could know this.

Sorry. Totally my fault. Even in the section about interrupts it is clearly mentioned.

The fix is: add ICACHE_RAM_ATTR just before all functions called from an interrupt (attach_interrupt)

This fix works for me.
By putting ICACHE_RAM_ATTR before the function would mean putting this Interrupt Service Routine (ISR) in RAM. RAM is faster than any memory space. We need to access the ISR faster so that we can get out of the Interrupt fast so that the ESP8266 will not hold up too long or worst could crash.

I'm getting the "ISR not in IRAM!" crash with the following config.
Hardware: ESP-12 NodeMCU v1.0
Core Version: 2.6.3
Development Env: Visual Micro in Visual Studio 2019
Operating System: Windows 10

I've been using ICACHE_RAM_ATTR since 2.4.0 when it was working, and have since rolled back to 2.4.0.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

eliabieri picture eliabieri  路  3Comments

mreschka picture mreschka  路  3Comments

treii28 picture treii28  路  3Comments

markusschweitzer picture markusschweitzer  路  3Comments

mechanic98 picture mechanic98  路  3Comments