espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
12.93k stars 7.09k forks source link

NMI interrupts are unusable in IDF 5.2.1 (IDFGH-12631) #13629

Open kristinpaget opened 2 months ago

kristinpaget commented 2 months ago

Answers checklist.

IDF version.

v5.2.1

Espressif SoC revision.

ESP32-D0WD-V3 (revision v3.1)

Operating System used.

Linux

How did you build your project?

Command line with idf.py

If you are using Windows, please specify command line type.

None

Development Kit.

Custom board

Power Supply used.

USB

What is the expected behavior?

I have an application using NMI interrupts from GPIO. I am able to set up the GPIO interrupt peripheral just fine, but mapping that peripheral to the NMI interrupt no longer works. It was working under ESP-IDF 4.4 using the following code:

ESP_INTR_DISABLE(14);
esp_rom_route_intr_matrix(1, ETS_GPIO_INTR_SOURCE, 14);
ESP_INTR_ENABLE(14);    

Since porting to v5.2.1 I've been unable to get the NMI to work; this code fails. Under the new API I now call

esp_intr_alloc(ETS_GPIO_INTR_SOURCE, ESP_INTR_FLAG_NMI | ESP_INTR_FLAG_IRAM, 0, 0, 0); 

which fails with ESP_ERR_NOT_FOUND unless I drop to ESP_INTR_FLAG_LEVEL4. esp_intr_dump() shows:

 14     7    Level  Reserved

on both cores. If I patch components/esp_hw_support/cpu.c and change

{ 7, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, ESP_CPU_INTR_DESC_FLAG_RESVD} }, //14, NMI

to

{ 7, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0} }, //14, NMI

then esp_intr_dump now shows

14     7    Level  Free (not general-use)

The above call to esp_rom_route_intr_matrix now succeeds and esp_intr_dump now shows

14     7    Level  Used: GPIO

but the ISR does not appear to be called, despite being linked using all the same tricks as worked in v4.4.

I expected the initial call to esp_intr_alloc(ETS_GPIO_INTR_SOURCE, ESP_INTR_FLAG_NMI | ESP_INTR_FLAG_IRAM, 0, 0, 0); to succeed, or at least to see documentation of why all level 5+ interrupts are now reserved / unusable in esp-idf v5.2.1.

What is the actual behavior?

The call to esp_intr_alloc fails because interrupt 14 is marked ESP_CPU_INTR_DESC_FLAG_RESVD and there appears to be no way to remove this flag.

Steps to reproduce.

See above

Debug Logs.

No response

More Information.

No response

kristinpaget commented 2 months ago

Additional: after patching cpu.c the nmi interrupt still fails because the build system is not linking my ISR. I can add the following to cmakelists.txt with no errors: target_link_libraries(${COMPONENT_TARGET} "-u ld_something_that_doesnt_exist") The unresolved symbol is apparently not making it to the linker, so my ISR never gets linked / called. The documentation looks wrong? Either way, NMI is double-broken and I'm now not sure how to link any high-level ISR into IDF 5.2.1.

SoucheSouche commented 2 months ago

Hi @kristinpaget, thanks for reporting this issue. We will take a look at it shortly.

kristinpaget commented 1 month ago

Hi, is there any update on this? I could work around the interrupt assignment issue but the linker problem is a hard break for my application. Do you have a workaround that will allow my ISR to be linked and called if I can hack my way into a level 4 interrupt?