1

When I've developed for the ESP32, I've always included the linker attribute IRAM_ATTR when I've declared functions called from interrupts. This is based on https://docs.espressif.com/projects/esp-idf/en/v4.2/esp32s2/api-guides/general-notes.html :

Interrupt handlers must be placed into IRAM if ESP_INTR_FLAG_IRAM is used when registering the interrupt handler. In this case, ISR may only call functions placed into IRAM or functions present in ROM

To better understand how attachInterrupt intRoutine callback is used.This std::function is called from an internal function:

static void ARDUINO_ISR_ATTR __onPinInterrupt(void * arg) {
 InterruptHandle_t * isr = (InterruptHandle_t*)arg;
 if(isr->fn) {
 if(isr->arg){
 ((voidFuncPtrArg)isr->fn)(isr->arg);
 } else {
 isr->fn();
 }
 }
}

Where ARDUINO_ISR_ATTR is defined as:

#if CONFIG_ARDUINO_ISR_IRAM
#define ARDUINO_ISR_ATTR IRAM_ATTR
#define ARDUINO_ISR_FLAG ESP_INTR_FLAG_IRAM
#else
#define ARDUINO_ISR_ATTR
#define ARDUINO_ISR_FLAG (0)
#endif

I'm not sure where CONFIG_ARDUINO_ISR_IRAM is set for the Arduino tool chain, but looking at the PlatformIO framework-arduinoespressif32/tools/sdk/esp32*/sdkconfig files, it does not appear to be set for any of them.

Does this mean that generally the Arduino interrupts aren't being loaded into the IRAM for ESP32 targets?

asked Aug 8 at 5:01
3
  • An indictaion is no proof, and would not explain where and why it is set, but did you try to check the value of CONFIG_ARDUINO_ISR_IRAM in a sketch? For example, you could use Serial.println(CONFIG_ARDUINO_ISR_IRAM); Commented Aug 8 at 5:32
  • In my PlatformIO build, I get the error, "'CONFIG_ARDUINO_ISR_IRAM' was not declared in this scope". This doesn't mean much though since it's not the same compilation unit the Arduino library was built in. Commented Aug 8 at 5:53
  • Ah, sure, my fault. The library was built separately, and it might be difficult to find out. -- One spontaneous idea is to investigate the resulting executable by the common ELF tools. I'd expect that the attributes/properties of the ISR could reveal something. (Again, no general result.) Commented Aug 8 at 6:12

1 Answer 1

1

It appears that the Arduino library does not place its external interrupt handler in IRAM.

So I checked with both the Arduino IDE (esp32 board version 3.3.0) and PlatformIO (framework-arduinoespressif32 @ 3.20017.241212) that the __onPinInterrupt function is not placed into IRAM. I did this by generating a map file (adding -Wl,-Map,output.map to the build arguments) and looking where the functions were being placed.

My callback with IRAM_ATTR looks like:

 .iram1.0 0x400811bc 0x1f C:\Users\feros\AppData\Local\arduino\sketches2189円D6248A4BEC430F3ABA605F7D1065\sketch\encoder_test.ino.cpp.o
 0x400811bc handleEncoderInterrupt()

while __onPinInterrupt looks like:

 .text.__onPinInterrupt
 0x400f21e0 0x17 C:\Users\feros\AppData\Local\arduino\cores\eaa94e01c7ef80d31535561863eab262\core.a(esp32-hal-gpio.c.o)

Where the .text memory region is normal flash. Also as mentioned in the previous documentation snippet, IRAM is 0x40080000 to 0x400A0000.

I can modify the build flags with -DCONFIG_ARDUINO_ISR_IRAM=1 which does change this, but I guess now I'm a little confused why the Arduino library doesn't do this by default since this seems like it might impact interrupt latency.

answered Aug 8 at 18:28
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.