New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task watchdog got triggered. The following tasks did not feed the watchdog in time #595

Closed
orcema opened this Issue Aug 28, 2017 · 41 comments

Comments

Projects
None yet
@orcema
Copy link

orcema commented Aug 28, 2017

Hardware:

Board: ESP32-WROVER-KIT
Core Installation/update date: 25/08/2017
IDE name: Arduino IDE
Upload Speed: 115200

Description:

if the

void loop()

function is empty i keep receiving the error message

Task watchdog got triggered. The following tasks did not feed the watchdog in time:

 - IDLE (CPU 1)

Tasks currently running:

CPU 0: IDLE

CPU 1: loopTask

i solved the problem by adding

vTaskDelay(10);

in the main.cpp

void loopTask(void *pvParameters)
{
    setup();
    for(;;) {
        micros(); //update overflow
        loop();
        vTaskDelay(10);
    }
}

according to ESP_Sprite recommendation in this post
https://esp32.com/viewtopic.php?f=2&t=809&p=10191&hilit=esp_task_wdt_feed#p10191

Would it be possible to update the arduino-esp32 framework ?

Sketch:

/*
 *  This sketch demonstrates how to scan WiFi networks.
 *  The API is almost the same as with the WiFi Shield library,
 *  the most obvious difference being the different file you need to include:
 */
#include "WiFi.h"

void setup()
{
    Serial.begin(115200);

    // Set WiFi to station mode and disconnect from an AP if it was previously connected
    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    delay(100);

    Serial.println("Setup done");
    Serial.println("scan start");

     // WiFi.scanNetworks will return the number of networks found
     int n = WiFi.scanNetworks();
     Serial.println("scan done");
     if (n == 0) {
         Serial.println("no networks found");
     } else {
         Serial.print(n);
         Serial.println(" networks found");
         for (int i = 0; i < n; ++i) {
             // Print SSID and RSSI for each network found
             Serial.print(i + 1);
             Serial.print(": ");
             Serial.print(WiFi.SSID(i));
             Serial.print(" (");
             Serial.print(WiFi.RSSI(i));
             Serial.print(")");
             Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*");
             delay(10);
         }
     }
     Serial.println("");

     // Wait a bit before scanning again
     delay(5000);
}

void loop()
{

}

Debug Messages:


@lonerzzz

This comment has been minimized.

Copy link
Contributor

lonerzzz commented Aug 29, 2017

@orcema Your link gives a 404. What are you suggesting?

@tobozo

This comment has been minimized.

Copy link
Contributor

tobozo commented Aug 29, 2017

@lonerzzz

This comment has been minimized.

Copy link
Contributor

lonerzzz commented Aug 29, 2017

Thanks for the link but I a unsure what it is you are suggesting. Please clarify. The link refers to calling vTaskDelay() and that works for keeping the watchdog fed when there is no other activity. You wouldn't want to feed the watchdog by default because that would defeat its purpose when the loop is actually supposed to be doing something and fails to service the watchdog.

@orcema

This comment has been minimized.

Copy link

orcema commented Aug 30, 2017

In the sketch above the loop() function is empty. I had to search long time to find how to avoid this error message. The idea is to apply a default watchdog feed in order to avoid this error reporting when the loop() function is empty. I think it wouldn't defeat the purpose of the watchdog as code instructions inside a loop() function are executed sequentially thus if the code hangs up inside this loop() function the default watchdog feed using the vTaskDelay() will not be triggered.

@lonerzzz

This comment has been minimized.

Copy link
Contributor

lonerzzz commented Aug 30, 2017

@orcema I understand where you are going but what is the delay that gets chosen? It will vary per application and you wouldn't want to put a delay in that negatively impacts the ability of a particular application to meet its processing needs. Having sufficient delay in an empty loop to prevent watchdog triggering means slowing down the application for other use cases. This is especially bad for lightweight tasks that have to execute frequently.

I would also like to understand if @tobozo is looking for the same thing.

@tobozo

This comment has been minimized.

Copy link
Contributor

tobozo commented Aug 30, 2017

@lonerzzz I have an ESP32-WROVER-KIT too and was just curious to know why a loop() would be empty (better power management?).

@lonerzzz

This comment has been minimized.

Copy link
Contributor

lonerzzz commented Aug 30, 2017

@tobozo Sorry if I tell you something you already know, but I will go into detail just for clarity. Let me know if you are asking something different than what I answer.

As part of the Arduino standard implementation across the different MCUs, the underlying framework always calls a loop function for the application-specific code to be able to periodically perform its own steps. In some situations, the loop function is not required by the application, but is required to match the standard Arduino API of a setup() function and a loop() function.

Having the loop function gives no benefits of its own. It simply allows the underlying implementation time to do its own work and allows an Arduino application to get CPU time as well. The loop exists to provide a common implementation that is compliant with the standard pattern of the Arduino across the different MCUs. Because the ESP-32 implementation is sitting on top of FreeRTOS, the RTOS is checking for tight loops and can result in the watchdog timeouts. Hence we need to have the vTaskDelay() calls if we are not writing code that makes use of the loop() method.

@orcema

This comment has been minimized.

Copy link

orcema commented Aug 31, 2017

@lonerzzz A delay of 10ms is suffisent to avoid the error message and i guess that a delay of 10ms shouldn't be a problem for any arduino sketch.

@lonerzzz

This comment has been minimized.

Copy link
Contributor

lonerzzz commented Aug 31, 2017

@orcema I would have to disagree with that. It completely depends on the application what the tolerance to such a delay would be. If driving a display for example, such a delay could easily become noticeable if regular updates needed to be processed. On top of that, once the delay is automatically added, any application that cannot support such a delay would require removing it from core code.

@orcema

This comment has been minimized.

Copy link

orcema commented Sep 1, 2017

@lonerzzz Thus i think this vTaskDelay() has to be managed individually by each arduino sketch.

@lonerzzz

This comment has been minimized.

Copy link
Contributor

lonerzzz commented Sep 1, 2017

@orcema I would agree with managing how it is used per sketch, the question is in what manner. We would either have to explicitly add vTaskDelay as is indirectly documented or augment the Arduino definition with something to set a specified delay or no delay in the loop, possibly as part of the setup. I think that this would be seen as a variation from the standard Arduino approach so would required getting buy in. I could see this method but that is still not great in terms of being visible to people just getting started.

@orcema

This comment has been minimized.

Copy link

orcema commented Sep 1, 2017

@lonerzzz Maybe the solution would be to define a global variable in Arduino.h and set its default value to 10. As you suggested this value could be updated to the needed value in the setup function. This way the arduino standard would be respected and for most sketches the default value would be ok.

@copercini

This comment has been minimized.

Copy link
Collaborator

copercini commented Sep 1, 2017

@orcema you also can just add some delay in your sketch loop() without change core files, like:

void loop(){
    delay(2000);
}

Trying reproduce with others sketches but looks like this just occur with this one

@orcema

This comment has been minimized.

Copy link

orcema commented Sep 1, 2017

@copercini with my board the ESP32-WROVER-KIT it happens for every arduino sketch having an empty loop function. Even if the loop function is not empty but holds only an conditional statement "IF" the error shows up.
For me is ok to add this vTaskDelay manually in each sketch but for a beginner this would be non Arduino standard and most beginner will struggle to find the origin of this error.

@me-no-dev

This comment has been minimized.

Copy link
Member

me-no-dev commented Sep 2, 2017

I don't know what is going on here, but I can tell you that I will not add vTaskDelay(10) after each loop. For you to trigger WDT in the loop, you have to be running as IDF component and have WDT enabled for the Idle task on Core1. Those are disabled for Arduino in order to give to most Arduino-like behavior under FreeRTOS. You can add vTaskDelay(10) to your loop if you need it and achieve the same result.

10ms between each loop is ages in processor time ;) 2.4 million wasted CPU cycles, to be exact. Nothing else is running on Core1 ;)

@orcema

This comment has been minimized.

Copy link

orcema commented Sep 2, 2017

@me-no-dev if the WDT is disabled for the Idle task on Core 1, what happens if the code hangs up?

@me-no-dev

This comment has been minimized.

Copy link
Member

me-no-dev commented Sep 2, 2017

The same thing that happens on any AVR and STM ;) nothing. I do not say that this is the correct way, but that is tha way of Arduino. Still you have the option to run through IDF and delay/yield in the loop. So you are not left hanging.

@me-no-dev me-no-dev closed this Sep 2, 2017

@tuskiomi

This comment has been minimized.

Copy link

tuskiomi commented Sep 10, 2017

This is a bug. It is caused by the WIFI Thread coming in at the same priority as the Loop function.

@me-no-dev

This comment has been minimized.

Copy link
Member

me-no-dev commented Sep 10, 2017

wifi thread and loop run on different processors

@jenextech

This comment has been minimized.

Copy link

jenextech commented Dec 25, 2017

Hello guys,

So,finally what we should use instead of vTaskDelay() to feed the watchdog.
Actually,I am also facing same issue as can see logs below:

Task watchdog got triggered. The following tasks did not feed the watchdog in time:
Tasks currently running:
CPU 0: wifi
Task watchdog got triggered. The following tasks did not feed the watchdog in time:
Tasks currently running:
CPU 0: wifi
Task watchdog got triggered. The following tasks did not feed the watchdog in time:
Tasks currently running:
CPU 0: wifi
Task watchdog got triggered. The following tasks did not feed the watchdog in time:
Tasks currently running:
CPU 0: wifi

@Ningappaa

This comment has been minimized.

Copy link

Ningappaa commented Mar 19, 2018

am also getting same thing, I tried using delay but did not solved
what is the solution for that, other then vTaskDelay

@jenextech

This comment has been minimized.

Copy link

jenextech commented Mar 19, 2018

hello,
I could not resolved this issue.
But we can do one thing and that is change some set up in menuconfig.
Means there is one option available to do operation when watchdog-got triggered.
If we can restart the device whenever watchdog will trigger we can atleast retain to hang-up the device.

Regards,
Kishan Patel.

@Ningappaa

This comment has been minimized.

Copy link

Ningappaa commented Mar 19, 2018

@tuskiomi

This comment has been minimized.

Copy link

tuskiomi commented Mar 19, 2018

hello, another possible cause for this going off is a delay in i2c response time. i have not tested with SPI, but i suspect it may be the same.

@Ningappaa

This comment has been minimized.

Copy link

Ningappaa commented Mar 20, 2018

@tuskiomi

This comment has been minimized.

Copy link

tuskiomi commented Mar 23, 2018

In the MAKE -menuconfig you can turn off the thread watchdog. I'm not sure if there is a dynamic solution.

@akshar001

This comment has been minimized.

Copy link

akshar001 commented Aug 17, 2018

Anyone who still want to avoid that error should try
adding these three line to your continuous rtos function,

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

And add this header

#include "soc/timer_group_struct.h"
#include "soc/timer_group_reg.h"
@tuskiomi

This comment has been minimized.

Copy link

tuskiomi commented Sep 23, 2018

Anyone who still want to avoid that error should try
adding these three line to your continuous rtos function,

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

And add this header

#include "soc/timer_group_struct.h"
#include "soc/timer_group_reg.h"

This is the proper solution. The cause is arduino builtins not reporting to the watchdog.
If you're having issues with this, it means that some code/function is making the CPU wait too long. for the most part, the user has limited ability to do this.

@danielfabro

This comment has been minimized.

Copy link

danielfabro commented Sep 23, 2018

How i adding these three line to your continuous rtos function?

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

@PriyankPa

This comment has been minimized.

Copy link

PriyankPa commented Dec 28, 2018

Anyone who still want to avoid that error should try
adding these three line to your continuous rtos function,

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

And add this header

#include "soc/timer_group_struct.h"
#include "soc/timer_group_reg.h"

The watchdog is still getting triggered after I added this in the main loop. I am using the Arduino SDK so don't have access to the RTOS functions. But what I am more concerned about is the module not getting reset. The watchdog is supposed to reset the module. If that;'s not happening then the watchdog is of no use.
What do I have to do the make the watchdog reset the device?

@me-no-dev

This comment has been minimized.

Copy link
Member

me-no-dev commented Dec 28, 2018

Arduino does have access to all IDF things, but is built with WDT disabled for Core 1 (where loop runs). This is made on purpose to allow code written for other platforms to run on ESP32 without constantly causing resets. If you want to trigger WDT, then spin a task on core 0

@burner-

This comment has been minimized.

Copy link

burner- commented Jan 5, 2019

Looks that this bug is still exists and if you use BLE & wifi together board will drop to infinite WDT errors loop after random time:
Task watchdog got triggered. The following tasks did not reset the watchdog in time:

  • IDLE (CPU 0)
    Tasks currently running:
    CPU 0: wifi
    CPU 1: IDLE
    Task watchdog got triggered. The following tasks did not reset the watchdog in time:
  • IDLE (CPU 0)
    Tasks currently running:
    CPU 0: wifi
    CPU 1: IDLE
    And this continues for ever.
    I understand that there is some bugs left at wifi code what can cause hangups with BLE. But I like to repeat @PriyankPa question that why TWDT does not reset board? WDT without reset function is quite pointless so my question is that how I will get TWDT to do reset when it is triggered? I use Arduino ide.
@me-no-dev

This comment has been minimized.

Copy link
Member

me-no-dev commented Jan 5, 2019

WDT is now enabled to reset the board (by default on Core0 only, but can be enabled for Core1 or the loop task also). Update your Arduino and try again ;)

@me-no-dev

This comment has been minimized.

@MohRaouf

This comment has been minimized.

Copy link

MohRaouf commented Jan 6, 2019

Looks that this bug is still exists and if you use BLE & wifi together board will drop to infinite WDT errors loop after random time:
Task watchdog got triggered. The following tasks did not reset the watchdog in time:

  • IDLE (CPU 0)
    Tasks currently running:
    CPU 0: wifi
    CPU 1: IDLE
    Task watchdog got triggered. The following tasks did not reset the watchdog in time:
  • IDLE (CPU 0)
    Tasks currently running:
    CPU 0: wifi
    CPU 1: IDLE
    And this continues for ever.
    I understand that there is some bugs left at wifi code what can cause hangups with BLE. But I like to repeat @PriyankPa question that why TWDT does not reset board? WDT without reset function is quite pointless so my question is that how I will get TWDT to do reset when it is triggered? I use Arduino ide.

Same here ! did you find any solutions ?

@me-no-dev

This comment has been minimized.

Copy link
Member

me-no-dev commented Jan 6, 2019

@MohRaouf did you just skip what I wrote above?

@MohRaouf

This comment has been minimized.

Copy link

MohRaouf commented Jan 6, 2019

@me-no-dev No i didn't, but nothing did work for me, WDT is getting triggered after about 30 mins on Core 0 which is running the WiFi and BLE, the problem that it doesn't reset the board, but hang the code on the Error message.

however, i tried to set or simulate a WDT interrupt manually but it runs on Core 1 which doesn't have any issues. so i think i'll give a try to spin my WDT task on Core 0.
i use Arduino SDK with Visual Studio.

@me-no-dev

This comment has been minimized.

Copy link
Member

me-no-dev commented Jan 7, 2019

with latest master, wdt reset is enabled and is active on core 0. If you want it to reset also for core1, you can call enableCore1WDT();

@MohRaouf

This comment has been minimized.

Copy link

MohRaouf commented Jan 7, 2019

@me-no-dev
i updated the ESP libraries but still Reset doesn't happen when the Watchdog get triggered.

@me-no-dev

This comment has been minimized.

Copy link
Member

me-no-dev commented Jan 7, 2019

are you using the package manager? Through the IDE? If so, see here: https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/windows.md

@nevercast

This comment has been minimized.

Copy link

nevercast commented Jan 18, 2019

I have this as my loop:

void loop(void) {
  delay(100);
}

I still get

E (15174) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (15174) task_wdt:  - IDLE1 (CPU 1)
E (15174) task_wdt: Tasks currently running:
E (15174) task_wdt: CPU 0: IDLE0
E (15174) task_wdt: CPU 1: loopTask

I disabled the WDT on CPU 1 and that fixes the problem for now, but is delay not sufficient to keep the IDLE task from choking?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment