Page 1 of 2

(resolved) is there a way to make a function uninterruptible?

Posted: Tue Apr 16, 2019 5:42 pm
by mzimmers
Hi all -

I'm still contending with an I2C library issue that causes my app to crash. I'm wondering whether there is a compiler option for making a particular function uninterruptible. (The keyword "atomic" is used in other IDEs.) Does anyone know of such an option?

Thanks...

Re: is there a way to make a function uninterruptible?

Posted: Tue Apr 16, 2019 5:48 pm
by fly135
This was just posted in the General discussion....

viewtopic.php?f=2&t=10149

John A

Re: is there a way to make a function uninterruptible?

Posted: Tue Apr 16, 2019 6:08 pm
by mzimmers
Excellent...thanks.

The wording in the FreeRTOS doc is a little odd:

Calls to taskENTER_CRITICAL() and taskEXIT_CRITICAL() are designed to nest. Therefore, a critical section will only be exited when one call to taskEXIT_CRITICAL() has been executed for every preceding call to taskENTER_CRITICAL().

That sounds like the opposite of nesting to me...but I just work here.

EDIT: I just tried adding this, and I get this compiler error:
C:/esp32_projects/wifibutton/main/max77818.cpp:610:13: warning: 'taskENTER_CRITICAL(mux)' is deprecated in ESP-IDF, consider using 'portENTER_CRITICAL(mux)'
I looked in task.h, and found this section:

Code: Select all

#ifdef _ESP_FREERTOS_INTERNAL
#define taskENTER_CRITICAL(mux)		portENTER_CRITICAL(mux)
#else
#define taskENTER_CRITICAL(mux) _Pragma("GCC warning \"'taskENTER_CRITICAL(mux)' is deprecated in ESP-IDF, consider using 'portENTER_CRITICAL(mux)'\"") portENTER_CRITICAL(mux)
#endif
#define taskENTER_CRITICAL_ISR(mux)		portENTER_CRITICAL_ISR(mux)
So, do I correctly understand that ESP32 has overridden the FreeRTOS syntax, and requires me to supply a mutex for this purpose?

Re: is there a way to make a function uninterruptible?

Posted: Tue Apr 16, 2019 7:43 pm
by mzimmers
I added the FreeRTOS critical calls, and now I'm getting this on startup:
Guru Meditation Error: Core 0 panic'ed (Interrupt wdt timeout on CPU0)
Core 0 register dump:
PC : 0x40093184 PS : 0x00060934 A0 : 0x800919b7 A1 : 0x3ffb6080
A2 : 0x3ffb8724 A3 : 0x3ffb6394 A4 : 0x3ffbdda8 A5 : 0x00000001
A6 : 0x00060923 A7 : 0x00000001 A8 : 0x3ffb6394 A9 : 0x3ffb6394
A10 : 0x00000018 A11 : 0x00000018 A12 : 0x00000034 A13 : 0x00000001
A14 : 0x00060923 A15 : 0x00000001 SAR : 0x0000000d EXCCAUSE: 0x00000005
EXCVADDR: 0x00000000 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0x00000000

ELF file SHA256: 8c0bd7f04eb15f6a795d7a787f130e8c53daa7c22543731544723a14b6b5f6ca

Backtrace: 0x40093184:0x3ffb6080 0x400919b4:0x3ffb60a0 0x40092bec:0x3ffb60c0 0x4015f7da:0x3ffb6100 0x401242a3:0x3ffb6140 0x40124a25:0x3ffb61b0 0x40124bb7:0x3ffb6200 0x40110802:0x3ffb6240 0x40108796:0x3ffb6260 0x400d097a:0x3ffb62c0 0x40092279:0x3ffb62e0
The trace goes to the I2C library.

Re: is there a way to make a function uninterruptible?

Posted: Tue Apr 16, 2019 8:05 pm
by chegewara
How is your mux variable init looks like?
You need to pass mix as pointer, and in my case I am using this to init it:

Code: Select all

portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
 
and pas it by reference.

Re: is there a way to make a function uninterruptible?

Posted: Tue Apr 16, 2019 9:15 pm
by mzimmers
Yes, that's exactly what I did.

Code: Select all

    portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED;
    taskENTER_CRITICAL(&mutex);
    taskEXIT_CRITICAL(&mutex);

Re: is there a way to make a function uninterruptible?

Posted: Tue Apr 16, 2019 9:35 pm
by fly135
mzimmers wrote:
Tue Apr 16, 2019 6:08 pm
Excellent...thanks.

The wording in the FreeRTOS doc is a little odd:

Calls to taskENTER_CRITICAL() and taskEXIT_CRITICAL() are designed to nest. Therefore, a critical section will only be exited when one call to taskEXIT_CRITICAL() has been executed for every preceding call to taskENTER_CRITICAL().

That sounds like the opposite of nesting to me...but I just work here.
IMO It is nesting (or re-entrant). You will not be "non-critical" until you exit after enter. IOW, you can enter the critical section with the same thread over and over, vs another thread trying to get the critical section being blocked. But you won't be "non-critical" until each call to enter has a matching call to exit. So you could have a re-entrant function calling itself and entering the critical section as deep as you need to go.

John A

Re: is there a way to make a function uninterruptible?

Posted: Wed Apr 17, 2019 2:34 am
by ESP_Sprite
Also note the interrupt watchdog triggers when you stay in a critical section too long (or forget to exit it properly. 'Too long' by default is 300mS, but it's configurable in menuconfig.

Re: is there a way to make a function uninterruptible?

Posted: Wed Apr 17, 2019 2:39 am
by mzimmers
Oh...that's good to know. Does a WDT expiration manifest as a panic?

I don't think I'm spending 300ms in this routine anyway, but I'll take a closer look in the morning.

Re: is there a way to make a function uninterruptible?

Posted: Wed Apr 17, 2019 3:05 am
by chegewara
This is WDT reason (from your logs):

Code: Select all

Guru Meditation Error: Core 0 panic'ed (Interrupt wdt timeout on CPU0)