Discuss here different C compiler set ups, and compiling executables for the ESP8266

User avatar
By rhaenel
#23021
Looks like Espressif SDK started to use NMI recently (starting with v.1.1.0), if you're using that or later SDK version that may be the reason.


Thanks, that was really helpful. Actually, I'm running the current RTOS SDK, and according to the commit comments this has recently been sync'ed to the SDK v1.1.1.

And yes, I can confirm that the interrupts increase dramatically if I put a flood ping via WiFi to the chip. If I disable WiFi (wifi_set_opmode(NULL_MODE)), the effect is gone.

So all in all, it seems to be an NMI, and it seems that WiFi stuff is triggering it.

I'm not that familiar with the xtensa architecture, do you see any way I could possible work around this? All I'm trying to do is to get complete timing control for about 50us. Do you happen to know if there is a way to mask the NMI (even though the name implies probably not)? Or some sort of dirty trick like rewriting the interrupt vector for the NMI for the duration of my procedure?

-Roland
User avatar
By jcmvbkbc
#23022
rhaenel wrote:All I'm trying to do is to get complete timing control for about 50us. Do you happen to know if there is a way to mask the NMI (even though the name implies probably not)? Or some sort of dirty trick like rewriting the interrupt vector for the NMI for the duration of my procedure?

Right, there's no way to mask NMI in the CPU. The following options come to mind:
- sync back to pre-NMI SDK. That seems the easiest and the most robust solution to me.
- analyze NMI-related changes in the SDK to find the registers that control WiFi IRQ routing, in order to see if it may be disabled outside the CPU/temporarily rerouted to level-1 IRQ line. There may be no way to disable IRQ externally as well and SDK interrupt handler may not work correctly when called from lower level.
- provide your own interrupt vectors table for the NMI, kernel and user vectors and install it into vecbase SR. That won't disable NMI, but you'll be able to control the amount of work done in the handler. You'd probably need to record the arrival of NMI and call the original handler afterwards, which again may not work correctly.
User avatar
By projectgus
#23045 FWIW I'm not sure if there's a version of the RTOS SDK that doesn't use the NMI. Unlike the IOT SDK I think it's always been there.

jcmvbkbc wrote:- provide your own interrupt vectors table for the NMI, kernel and user vectors and install it into vecbase SR. That won't disable NMI, but you'll be able to control the amount of work done in the handler. You'd probably need to record the arrival of NMI and call the original handler afterwards, which again may not work correctly.


For my 2c I'd agree with this approach.

You could either just rename NMIExceptionVector in the linker script so it links your own "wrapper" NMI handler that checks if it's safe to call the real handler.

Or, like Cal suggestsm you could write a new NMI vector address at runtime (the default RTOS vecbase points into IRAM) to swap the vector out for a dummy vector for the duration of your time-sensitive operation, then swap it back to _NMIExceptionVector when you were finished.

I'm curious how the SDK handles having the NMI handler event either deferred up to 50us or skipped entirely. Keen to hear how you go. :)