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

User avatar
By rhaenel
#23080 OK, I do now use the following code to write a "RFI 3" directly into the NMI code:

Code: Select all   // modify NMI ISR to return immediately
   void *nmi_isr;       
   __asm__ __volatile__ ("rsr.vecbase %0" : "=r" (nmi_isr));
   nmi_isr += XCHAL_NMI_VECOFS;
   uint32 nmi_backup = *((uint32 *) nmi_isr);
   *((uint32 *) nmi_isr) = 0x00003310;      // asm ("reti 3")


and after my time-critical stuff, I try to restore the original code:

Code: Select all   // restore original NMI ISR
   *((uint32 *) nmi_isr) = nmi_backup;


And well, it doesn't yet work...

After a couple of 100 runs of the function the ESP8266 crashes, and "wdev.c 1166" is printed on the UART before the crash. I assume that "wdev" correlates to WiFi stuff.

If I just leave the NMI ISR dead, it runs for a little more time, starts to complain about missing buffers on the UART and crashes somewhat later. It seems that the NMI is in fact used by the WiFi to notify that some stuff has been received and needs to be taken out of some queue/buffer/...

Back to my code that restores the original NMI -the system doesn't seem to tolerate that the NMI is potentially lost. And I don't know how to 'emulate' this NMI yet. I can't just jump into the original routine, because that will eventually do a "RFI 3" and that opcode will fail because it wasn't called by a NMI in the first place.

Any ideas?

-Roland
User avatar
By rhaenel
#23081 OK, I came up with an idea:

What if I modify the NMI ISR code to just "jump to the program counter it came from"? So if the NMI is taken, this will jump right back into my code.

At the end of my code, I restore the original NMI ISR, and check if I'm running in exception mode (that means, the NMI was taking during my code). If so, I modify the stored PC and jump to the NMI ISR (the original one).
User avatar
By jcmvbkbc
#23082
rhaenel wrote:What if I modify the NMI ISR code to just "jump to the program counter it came from"? So if the NMI is taken, this will jump right back into my code.

At the end of my code, I restore the original NMI ISR, and check if I'm running in exception mode (that means, the NMI was taking during my code). If so, I modify the stored PC and jump to the NMI ISR (the original one).

That may work, but the "jump to the program counter it came from" part looks a bit tricky: you either need to do it by rfi/rfe command, or by self-modifying code, or you'd need a register that is not used by the rest of your code.
User avatar
By eriksl
#23325 Tunnel vision guys...

It's in the SDK documentation that the new PWM implementation uses NMI's. Maybe other code as well.

If you want precise PWM, use the PWM implementation in the SDK, that's precise BECAUSE it's use NMI's.