How to disable 'interrupt watchdog' in ESP32 OR increase ISR time limit?
Asked Answered
M

6

7

I am using ESP32 DEVKIT link and Adafruit VS1053 Codec + MicroSD Breakout - MP3/WAV/MIDI/OGG Play + Record - v4 link to record and then play the sound. I am using Arduino IDE for coding.

I am facing an issue right now that the module uses hardware interrupt for playing purposes. But ESP32 is resetting again and again when I try to play a sound track. The debug log says:

Guru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1)
Core 1 register dump:
PC      : 0x400d1280  PS      : 0x00060834  A0      : 0x800d128f  A1      : 0x3ffc0bb0  
A2      : 0x3ffc241c  A3      : 0x3ffb1f20  A4      : 0x800d1779  A5      : 0x3ffb1f00  
A6      : 0x3ffc241c  A7      : 0x3f400f9c  A8      : 0x800d1280  A9      : 0x3ffc0b90  
A10     : 0x0000002b  A11     : 0x3f401067  A12     : 0x800d1691  A13     : 0x3ffb1ed0  
A14     : 0x3ffc241c  A15     : 0x00000000  SAR     : 0x0000001f  EXCCAUSE: 0x00000006  
EXCVADDR: 0x00000000  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xffffffff  
Core 1 was running in ISR context:
EPC1    : 0x400d4123  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x400d1280

Backtrace: 0x400d1280:0x3ffc0bb0 0x400d128c:0x3ffc0bd0 0x40080e21:0x3ffc0bf0 0x400817d5:0x3ffc0c10 0x400d3ae5:0x00000000

Core 0 register dump:
PC      : 0x400ee86e  PS      : 0x00060934  A0      : 0x8008656c  A1      : 0x3ffc7910  
A2      : 0x00000008  A3      : 0x00000000  A4      : 0x00000001  A5      : 0x3ffc7f4c  
A6      : 0x00000000  A7      : 0x00000001  A8      : 0x3ffc3404  A9      : 0x3ffc33e8  
A10     : 0x00000000  A11     : 0x00000001  A12     : 0x00000000  A13     : 0x00000001  
A14     : 0x00060b20  A15     : 0x00000000  SAR     : 0x00000000  EXCCAUSE: 0x00000006  
EXCVADDR: 0x00000000  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000  

Backtrace: 0x400ee86e:0x3ffc7910 0x40086569:0x3ffc7930

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:952
load:0x40078000,len:6084
load:0x40080000,len:7936
entry 0x40080310
Adafruit VS1053 Simple Test
VS1053 found

The line Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1) indicates that its interrupt wdt.

I searched ways to disable interrupt WDT but no help. The file esp_int_wdt.h in ~Documents\Arduino\hardware\espressif\esp32\tools\sdk\include\esp32 provides two functions for enabling interrupt WDT for both or one CPU. There is no function to disable it.

How to disable ESP32 interrupt WDT?

Morganstein answered 8/8, 2018 at 15:25 Comment(0)
U
6
#include "soc/rtc_wdt.h"

rtc_wdt_protect_off();
rtc_wdt_disable();

Or turn it off in menuconfig. I agree with other posters though, you should not turn it off, instead, you can also feed it with the following function:

rtc_wdt_feed();

I usually create a lowest priority FreeRTOS task that just loops and calls the feed method with a delay less then the timeout, giving enough time for higher priority "business logic" to run. Example:

Set timeout to 250 ms in menuconfig or in code:

rtc_wdt_set_length_of_reset_signal(RTC_WDT_SYS_RESET_SIG, RTC_WDT_LENGTH_3_2us);
rtc_wdt_set_stage(RTC_WDT_STAGE0, RTC_WDT_STAGE_ACTION_RESET_SYSTEM);
rtc_wdt_set_time(RTC_WDT_STAGE0, 250);

Then do this in your task:

while(true) {
    rtc_wdt_feed();
    vTaskDelay(pdMS_TO_TICKS(100));
}

This will feed both the FreeRTOS WDT and the RTC WDT and reset your system if it gets stuck in a loop or doesn't processes within your time requirements. You'll need to play with the timeout and how often you feed the timer to get it right for your system.Keep in mind the Wifi, PHY, and BT are not deterministic so you'll have a lot of unpredictability in timing if you are dependent on DAQ from from "the net".

Uxoricide answered 26/9, 2019 at 11:53 Comment(0)
T
3

I don't know how to disable watchdog using arduino, but I can tell you how to disable it using esp-idf and its make menuconfig

  1. Open menuconfig: make menuconfig
  2. Enter component config
  3. Enter ESP32-specific
  4. Remove star from interrupt watchdog

P.S. According to esp-idf docs void esp_int_wdt_init() is used to init interrupt watchdog. This function is called when IWDT enabled in menuconfig. So you can try to find call of this function and remove it ;)

BUT: I advise you to not disable watchdog. Instead of this, try to use FreeRTOS tasks to execute large amount of code on interrupt.

Im not sure how to do it exactly in arduino platform, but I can tell how I did it using esp-idf

First, create interrupt handler with signature void f(void*)

void MyHandler(void* pData){
    /* Your code here */
    vTaskDelete(NULL); // delete current taks, must have
}

Second, in interrupt handler you have to create new task, using xTaskCreate or xTaskCreatePinnedToCore. For example, xTaskCreate(MyHandler, "int_handler", 256, NULL, 4, NULL); (Check out api reference)

That's all, now you can run big code on your interrupt. In addition to this, I advise you to not create too many tasks. System may hang.

P.S. If you need to handle tonns of interurpt requests per second, try to use FreeRTOS queues

Tweeter answered 8/8, 2018 at 18:22 Comment(0)
S
1

The watchdog timer plays an important role in system stability.

Rather than disabling the watchdog timer, try to make sure that you don't stay in loop() for too long. You should always structure your code so that you do the least work you can in loop() and let it return. When it returns the software that supports your ESP32 application gets to do important housekeeping tasks, and reset the watchdog timer.

For instance, you should never write:

void loop() {
  while(1) {
    do_some_work();
  }
}

and instead you should write:

void loop() {
  do_some_work();
}

If you absolutely have to do more work in loop() than the watchdog timer allows for, make sure you call yield() or delay() occasionally from your code; this will allow the system to catch up on things it needs to do. yield() will return immediately after doing any needed housekeeping work; delay(milliseconds) will return milliseconds later after doing any needed work.

So rather than write

void loop() {
  unsigned long start_time = millis();

  while(millis() - start_time < 10*1000) { }

  do_some_work();
}

which would cause the watchdog timer to go off, you'd want to write

void loop() {
  delay(10*1000);

  do_some_work();
  start_time = millis();
}

or even better, if your loop may be servicing multiple needs:

void loop() {
  static unsigned long start_time1 = millis();
  static unsigned long start_time2 = millis();

  if(millis() - start_time >= 10*1000) {
    do_some_work1();
    start_time1 = millis();
  }

  if(millis() - start_time >= 20*1000) {
    do_some_work2();
    start_time2 = millis();
  }
}
Soilure answered 8/8, 2018 at 16:9 Comment(5)
With all due respect, you should NEVER tell someone that they should NEVER do something which isn't common practice method, or even a good idea to perform a task in a particular manor. There are plenty of reasons to perform a task in a manor which the "industry" says is a bad idea. FWIW: I speak from nearly 40 years programming experience.Postfree
Yeah, while useful, this doesn't actually answer the question. For example I'm bit banging an SPI-like protocol (incompatible with the esp one) out during a core 0 GPIO interrupt. I'm holding the interrupt as long as is required to prevent core 0's own interrupts disrupting things. In this oddball case turning the WD off, or extending it briefly would be the most effective solution.Honoria
@Honoria if you're doing that, you clearly know more than the OP did and are capable of making better informed decisions.Soilure
Fair, but this is still the top 'answer' on google and doesn't quite answer the problem.Honoria
An "answer" that is only advice to do something else is not an answer. This is not an advice forum. If you can't answer the question, better to not post at all.Luannaluanne
S
0

I use HELTEC ESP32 LORA. Board selected is Arduino HELTEC WIFI LORA 32 (V2)

My firmware works fine, but with the same firmware one year later, the esp32 starts to reset in the interrupt.

The message in the terminal:

Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1).

I checked:

  1. Watch dog, it did not work

  2. Decreased the program inside the interrupt, it did not work.

Finally, the solution was:

Downgrade the ESp32 by expressive system library from 2.0.6 to 2.0.3.

Skeg answered 17/2, 2023 at 3:57 Comment(0)
L
0

This code disables the interrupt watchdog timer and works when using Arduino libs:

#include "soc/timer_group_struct.h"
#include "soc/timer_group_reg.h"
...
TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE; // Unlock timer config.
TIMERG1.wdt_feed = 1; // Reset feed count.
TIMERG1.wdt_config0.en = 0; // Disable timer.
TIMERG1.wdt_wprotect = 0; // Lock timer config.

TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG0.wdt_feed = 1;
TIMERG0.wdt_config0.en = 0;
TIMERG0.wdt_wprotect = 0;

You probably only need to turn off TIMERG1.

Luannaluanne answered 20/8, 2023 at 0:58 Comment(0)
N
0

I've spent an hour or two looking into this problem on an ESP-32 "cheap yellow display) essentially an ESP-32 Dev Module integrated into a board with a color tft and touchscreen. (Was working through this project in some early project research https://randomnerdtutorials.com/touchscreen-on-off-button-cheap-yellow-display-esp32-2432s028r/ when my problem.)

While I'm uploading via Arduino IDE, the solution is probably similar events run on "Core 0" and functional code runs on "Core 1." There may be a morct as early e elegant solution, but I haven't found one.

In Arduino IDE these settings are found under the Tools menu when the ESP32 Dev Module board is selected. In other IDEs you may have to code directly for this.

This post was one of google's top most links in my search for help with this, so many people are obviously still coming here, hence this contribution. Hope the community don't mind.

Newell answered 3/6 at 6:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.