任务看门狗被触发./abort() 在核心 0 上的 PC 0x400de07b 上被调用 [英] Task watchdog got triggered./abort() was called at PC 0x400de07b on core 0

查看:27
本文介绍了任务看门狗被触发./abort() 在核心 0 上的 PC 0x400de07b 上被调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我参与了一个自主 GPS 机器人项目.当我在一段时间后运行以下代码时,esp32(devkit v1) 会重新启动,并且这种情况会不断重复.

I am on an Autonomous GPS robot project. When I am running the below code after some time the esp32(devkit v1) reboots and this goes on repeating.

Pause for Startup... 3
Pause for Startup... 2
Pause for Startup... 1
Searching for Satellites 
Searching for Satellites 
GPS Waypoint 1 Set Waypoint #1: 0.000000 , 0.000000
Waypoint #2: 0.000000 , 0.000000
5 Satellites Acquired10.190620
76.424872
25.190620
47.424872
YOYYYYO
Go to Waypoint
E (98333) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (98333) task_wdt:  - async_tcp (CPU 0/1)
E (98333) task_wdt: Tasks currently running:
E (98333) task_wdt: CPU 0: IDLE0
E (98333) task_wdt: CPU 1: async_tcp
E (98333) task_wdt: Aborting.
abort() was called at PC 0x400de07b on core 0

Backtrace: 0x4008cbf8:0x3ffbe170 0x4008ce29:0x3ffbe190 0x400de07b:0x3ffbe1b0 0x40084f01:0x3ffbe1d0 0x40148e07:0x3ffbc0d0 0x400df42b:0x3ffbc0f0 0x4008ab01:0x3ffbc110 0x4008930d:0x3ffbc130

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:1044
load:0x40078000,len:8896
load:0x40080400,len:5816
entry 0x400806ac
Welcome
Autonmous Mode Initiated...

IP Address: 192.168.1.18
Compass setting done
 iam here1
Pause for Startup... 
Pause for Startup... 10
Pause for Startup... 9
Pause for Startup... 8
YOYYYYO
Go to Waypoint
Pause for Startup... 7
Pause for Startup... 6
Pause for Startup... 5
Pause for Startup... 4
Pause for Startup... 3
E (10128) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (10128) task_wdt:  - async_tcp (CPU 0)
E (10128) task_wdt: Tasks currently running:
E (10128) task_wdt: CPU 0: Tmr Svc
E (10128) task_wdt: CPU 1: IDLE1
E (10128) task_wdt: Aborting.
abort() was called at PC 0x400de07b on core 0

Backtrace: 0x4008cbf8:0x3ffbe170 0x4008ce29:0x3ffbe190 0x400de07b:0x3ffbe1b0 0x40084f01:0x3ffbe1d0 0x4000bfed:0x3ffbd060 0x4008a489:0x3ffbd070 0x400827d1:0x3ffbd090 0x40082843:0x3ffbd0b0 0x4008b825:0x3ffbd0d0 0x4008b924:0x3ffbd100 0x4008930d:0x3ffbd130

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

这是出现在串行监视器上的消息.我试过调试,但找不到为什么会这样.

This is the msg that appears on the serial monitor. I tried debugging but can't find why this is happening.

代码真的很大,所以我只上传了其中的一部分.

The Code is really big, so I have uploaded only a part of it.

// CompaSerial Variables & Setup

HMC5883L compass;
int16_t mx, my, mz;                                                // variables to store x,y,z axis from compass (HMC5883L)
int desired_heading;                                               // initialize variable - stores value for the new desired heading
int compass_heading;                                               // initialize variable - stores value calculated from compass readings
int compass_dev = 5;                                               // the amount of deviation that is allowed in the compass heading - Adjust as Needed
                                                                   // setting this variable too low will cause the robot to continuously pivot left and right
                                                                   // setting this variable too high will cause the robot to veer off course

int Heading_A;                                                     // variable to store compass heading
int Heading_B;                                                     // variable to store compass heading in Opposite direction
int pass = 0;                                                      // variable to store which paSerial the robot is on


//*****************************************************************************************************
// GPS Locations

unsigned long Distance_To_Home;                                    // variable for storing the distance to destination

int ac =0;                                                         // GPS array counter
int wpCount = 0;                                                   // GPS waypoint counter
double Home_LATarray[2];                                          // variable for storing the destination Latitude - Only Programmed for 5 waypoint
double Home_LONarray[2];                                          // variable for storing the destination Longitude - up to 50 waypoints

int increment = 0;

//*****************************************************************************************************
// HTML Page
AsyncWebServer server(80);
const char* ssid = "******";
const char* password = "******";

const char* PARAM_INPUT_1 = "input1";
const char* PARAM_INPUT_2 = "input2";
const char* PARAM_INPUT_3 = "input3";
const char* PARAM_INPUT_4 = "input4";
const char* PARAM_COMMIT = "commit";
double lati1;
double logi1;
double lati2;
double logi2;

// HTML web page to handle 4 input fields 
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML>
<html>
   <head>
      <h2>Autonomus GPS Robot Car<h2>
      <h3> Submit your Destination coordinates</h3>
      <meta name="viewport" content="width=device-width, initial-scale=1">
   </head>
   <body>
   <style>

   a {
  border: 10px solid powderblue;
  padding: 10px;
  color: red;
  font-family: verdana;
  font-size: 150%;
}
</style>
</head>
<body>
<form action="/get" >
 <br> 
    Waypoint 1 Latitude : <input type="text" name="input1">
     <br>
   <br>
    Waypoint 1 Longitude: <input type="text" name="input2">
  <br><br>
    <br> 
    Waypoint 2 Latitude : <input type="text" name="input3">
     <br>
   <br>
    Waypoint 2 Longitude: <input type="text" name="input4">
  <br><br>
   <input type="submit" value="Submit">

        <br>
    <br><br>
    <br><br>


    <a href="/go" >Go to Destination</a>
    <br><br>    <br><br>
    <br><br>

    <a href="/clear" > Clear waypoints</a>
</form>
</body>
</html>)rawliteral";

void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}

//*****************************************************************************************************
// Extras

#define autopilot 18
 void  gesturecontroll();
 void getGPS();    
 void getCompass();  
 void Forward();
void Forward_Meter();
void Reverse();
void LeftTurn();
void RightTurn();
void SlowLeftTurn();
void SlowRightTurn();
void StopCar();
void setWaypoint();
 void move();
 void Startup();
 void goWaypoint();
 void clearWaypoints();

 int blueToothVal;  
 int flag=0;
 int button;


void setup() 
{    Serial.begin(115200);                                            // Serial 0 is for communication with the computer
     Serial.println("Welcome");

pinMode(autopilot, INPUT);

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 button = digitalRead(autopilot);
 if (button == HIGH)
 {   flag=15;
     Serial.println("Manual Control initated");
     Serial.println("ESPNow/Basic/Slave Example");
     //Set device in AP mode to begin with
     WiFi.mode(WIFI_AP);
     // configure device AP mode
     // This is the mac address of the Slave in AP Mode
     esp_wifi_set_mac(ESP_IF_WIFI_STA, &mac[0]);


     Serial.print("AP MAC: "); Serial.println(WiFi.softAPmacAddress());
     // Init ESPNow with a fallback logic
     if (esp_now_init()!=0)
      {
          Serial.println("*** ESP_Now init failed");
          while(true) {};
       }

       // Once ESPNow is successfully Init, we will register for recv CB to
      // get recv packer info.
       esp_now_register_recv_cb(OnDataRecv);
      Serial.print("Aheloiioi");                  // the remaining code for above part is not uploaded since when switch is pulled this part of code works perfectly
 }

 else{   
        S2.begin(9600, SERIAL_8N1, RXPin, TXPin);                                             // Serial 2 is for GPS communication at 9600 baud - DO NOT MODIFY - Ublox Neo 6m 
         flag=0;
        // pinMode(LED_BUILTIN, OUTPUT);                                   // An LED indicator - Not Used
         Serial.println("Autonmous Mode Initiated...");
    WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("WiFi Failed!");
    return;
  }
  Serial.println();
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
      CompaSerial////////////////////////////////////////////////////////////////////////////////////
         Wire.begin();                                                    // Join I2C bus used for the HMC5883L compass
        //compass.init();
         compass.begin();                                                 // initialize the compass (HMC5883L)
         compass.setRange(HMC5883L_RANGE_1_3GA);                          // Set measurement range  
         compass.setMeasurementMode(HMC5883L_CONTINOUS);                  // Set measurement mode  
         compass.setDataRate(HMC5883L_DATARATE_30HZ);                     // Set data rate  
         compass.setSamples(HMC5883L_SAMPLES_8);                          // Set number of samples averaged  
         compass.setOffset(0,0);
         Serial.println("Compass setting done");
               Startup(); // Run the Startup procedure on power-up one time
     }              
}  

// Main Loop

void loop()
{  button = digitalRead(autopilot);
    if (button == HIGH && flag==15)
    {      
      } 
     else
    {  Coordinates();
    getGPS();                                                        // Update the GPS location
    getCompass();                                                    // Update the CompaSerial Heading
    //Ping();                                                          // Use at your own discretion, this is not fully tested

    }    

}


void Coordinates()
{    Serial.println("i am here1");


  // Send web page with input fields to client
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html);
  });

  // Send a GET request to <ESP_IP>/get?input1=<inputMessage>
  server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String latitude1;
    String latitude1Param;
    String longitude1;
    String longitude1Param;
    String latitude2;
    String latitude2Param;
    String longitude2;
    String longitude2Param;
   String commitType;;


    if (request->hasParam(PARAM_INPUT_2)||request->hasParam(PARAM_INPUT_1) ) {
    // GET input1 value on <ESP_IP>/get?input1=<latitude>

      latitude1 = request->getParam(PARAM_INPUT_1)->value();
      latitude1Param = PARAM_INPUT_1;

    // GET input2 value on <ESP_IP>/get?input2=<longitude>

       longitude1 = request->getParam(PARAM_INPUT_2)->value();
       longitude1Param = PARAM_INPUT_2;

// GET input3 value on <ESP_IP>/get?input3=<latitude>

      latitude2 = request->getParam(PARAM_INPUT_3)->value();
      latitude2Param = PARAM_INPUT_3;

    // GET input4 value on <ESP_IP>/get?input4=<longitude>

       longitude2 = request->getParam(PARAM_INPUT_4)->value();
       longitude2Param = PARAM_INPUT_4;
  }


    else {
      latitude1 = "No message sent";
      latitude1Param = "none";
      longitude1 = "No message sent";
      longitude1Param = "none";
      latitude2 = "No message sent";
      latitude2Param = "none";
      longitude2 = "No message sent";
      longitude2Param = "none";

    }


    Serial.println(latitude1);
    Serial.println(longitude1);
    Serial.println(latitude2);
    Serial.println(longitude2);
    lati1=(latitude1.toFloat());
    logi1=(longitude1.toFloat());
    lati2=(latitude2.toFloat());
    logi2=(longitude2.toFloat());
    //Serial.println(lati,6);
    //Serial.println(logi,6);
    request->send(200, "text/html", "Command succesfuly sent""<br><a href=\"/\">Return to Home Page</a>");
  });

  server.on("/go", HTTP_GET, [] (AsyncWebServerRequest *request) {
//logic for go here
Serial.println("YOYYYYO");
        goWaypoint();

request->redirect("/");
});

server.on("/clear", HTTP_GET, [] (AsyncWebServerRequest *request) {
//logic for clear here
  Serial.println("fdfghgh");
   clearWaypoints();
request->redirect("/");
});
  server.onNotFound(notFound);
  server.begin();
}

void getGPS()                                                 // Get Latest GPS coordinates
{  Serial.println("i am here2");
    while (S2.available() > 0)
    gps.encode(S2.read());
} 

// *************************************************************************************************************************************************

void setWaypoint()                                            // Set up to 5 GPS waypoints
{

//if ((wpCount >= 0) && (wpCount < 50))
if (wpCount >= 0)
  {
    Serial.print("GPS Waypoint ");
    Serial.print(wpCount + 1);
    Serial.print(" Set ");

    Home_LATarray[ac] = lati1 ;                   // store waypoint in an array   
    Home_LONarray[ac] = logi1 ;             // store waypoint in an array   
    Home_LATarray[ac] = lati2 ;               // store waypoint in an array   
    Home_LONarray[ac] = logi2 ;                  // store waypoint in an array   

    Serial.print("Waypoint #1: ");
    Serial.print(Home_LATarray[0],6);
    Serial.print(" , ");
    Serial.println(Home_LONarray[0],6);
    Serial.print("Waypoint #2: ");
    Serial.print(Home_LATarray[1],6);
    Serial.print(" , ");
    Serial.println(Home_LONarray[1],6);
    wpCount++;                                                  // increment waypoint counter
    ac++;                                                       // increment array counter

  }         
  else {Serial.print("Waypoints Full");}
}

// ************************************************************************************************************************************************* 

void clearWaypoints()
{
   memset(Home_LATarray, 0, sizeof(Home_LATarray));             // clear the array
   memset(Home_LONarray, 0, sizeof(Home_LONarray));             // clear the array
   wpCount = 0;                                                 // reset increment counter to 0
   ac = 0;

   Serial.print("GPS Waypoints Cleared");                      // display waypoints cleared

}

 // *************************************************************************************************************************************************

void getCompass()                                               // get latest compass value
 {  

  Vector norm = compass.readNormalize();

  // Calculate heading
  float heading = atan2(norm.YAxis, norm.XAxis);

  if(heading < 0)
     heading += 2 * M_PI;      
  compass_heading = (int)(heading * 180/M_PI);                   // aSerialign compass calculation to variable (compass_heading) and convert to integer to remove decimal places                                                              

 }

void Startup()
{ 
     Serial.println("Pause for Startup... ");

     for (int i=10; i >= 1; i--)                       // Count down for X seconds
      {         
        Serial.print("Pause for Startup... "); 
        Serial.println(i);
        delay(1000);                                   // Delay for X seconds
      }    


  Serial.println("Searching for Satellites "); 
  Serial.println("Searching for Satellites "); 

  while (Number_of_SATS <= 4)                         // Wait until x number of satellites are acquired before starting main loop
  {                                  
    getGPS();                                         // Update gps data
    Number_of_SATS = (int)(gps.satellites.value());   // Query Tiny GPS for the number of Satellites Acquired       
  }    
  setWaypoint();                                      // set intial waypoint to current location
  wpCount = 0;                                        // zero waypoint counter
  ac = 0;                                             // zero array counter

  Serial.print(Number_of_SATS);
  Serial.print(" Satellites Acquired");    
}   

void goWaypoint()
{   
 Serial.println("Go to Waypoint");
//Serial.print("Home_Latarray ");
//Serial.print(Home_LATarray[ac],6);
//Serial.print(" ");
//Serial.println(Home_LONarray[ac],6);   

//Serial1.print("Distance to Home");   
//Serial1.print(Distance_To_Home);

//Serial1.print("ac= ");
//Serial1.print(ac);

 while (true)  
  {                                                                // Start of Go_Home procedure 
 // bluetooth();                                                     // Run the Bluetooth procedure to see if there is any data being sent via BT
  if (blueToothVal == 5){break;}                                   // If a 'Stop' Bluetooth command is received then break from the Loop
  getCompass();                                                    // Update Compass heading                                          
  getGPS();                                                        // Tiny GPS function that retrieves GPS data - update GPS location// delay time changed from 100 to 10

  if (millis() > 5000 && gps.charsProcessed() < 10)                // If no Data from GPS within 5 seconds then send error
    Serial.println(F("No GPS data: check wiring"));     

  Distance_To_Home = TinyGPSPlus::distanceBetween(gps.location.lat(),gps.location.lng(),Home_LATarray[ac], Home_LONarray[ac]);  //Query Tiny GPS for Distance to Destination
  GPS_Course = TinyGPSPlus::courseTo(gps.location.lat(),gps.location.lng(),Home_LATarray[ac],Home_LONarray[ac]);                               //Query Tiny GPS for Course to Destination   

   /*
    if (Home_LATarray[ac] == 0) {
      Serial1.print("End of Waypoints");
      StopCar();      
      break;
      }      
   */ 
    if (Distance_To_Home == 0)                                   // If the Vehicle has reached it's Destination, then Stop
        {
        StopCar();                                               // Stop the robot after each waypoint is reached
        Serial.println("You have arrived!");                    // Print to Bluetooth device - "You have arrived"          
        ac++;                                                    // increment counter for next waypoint
        break;                                                   // Break from Go_Home procedure and send control back to the Void Loop 
                                                                 // go to next waypoint

        }   


   if ( abs(GPS_Course - compass_heading) <= 15)                  // If GPS Course and the Compass Heading are within x degrees of each other then go Forward                                                                  
                                                                  // otherwise find the shortest turn radius and turn left or right  
       {
         Forward();                                               // Go Forward
       } else 
         {                                                       
            int x = (GPS_Course - 360);                           // x = the GPS desired heading - 360
            int y = (compass_heading - (x));                      // y = the Compass heading - x
            int z = (y - 360);                                    // z = y - 360

            if ((z <= 180) && (z >= 0))                           // if z is less than 180 and not a negative value then turn left otherwise turn right
                  { SlowLeftTurn();  }
             else { SlowRightTurn(); }               
        } 


  }                                                              // End of While Loop


}   

推荐答案

ESP-IDF 为空闲任务创建了一个看门狗定时器,除了执行您工作的任何任务.IE,它创建了两个额外的任务 IDLE0 &IDLE 1(每个内核一个),其唯一目的是什么都不做,即空闲.这些空闲任务只是在其各自的内核空闲时为看门狗提供数据.每当 Arduino 或 ESP-IDF 中的任何任务以及中断例程以比 IDLE 任务更高的优先级运行而没有延迟或阻塞足够长/足够频繁时(例如在紧凑的 while 循环中执行时),它就会触发看门狗,因为该内核现在完全忙碌,这意味着它不再经常空闲,这意味着空闲的任务"没有了.饿死了,所以他们不能重置看门狗.ESP-IDF 中的 app_main() 和 Arduino 中的 loop() 以比空闲任务更高的优先级运行.这是问题的根源.您要么必须以足够的时间间隔进行一些调用以阻止您的代码至少 10 毫秒,要么您必须调用 yield() 或vTaskDelay(NUMBER_OF_MILLISECONDS_TO_DELAY/portTICK_PERIOD_MS)最少 10 毫秒(否则,由于离散性,它等于 0,即根本没有延迟,因此将不起作用.您可以通过增加调度程序频率来解决此问题).

ESP-IDF creats a watchdog timer for idle tasks in addition to any tasks doing your work. IE, it creates two extra tasks IDLE0 & IDLE 1 (one for each core), whose sole purpose is to do nothing, ie idle. These idle tasks simply feed the watchdog whenever its respective core is idling. Whenever any task, in Arduino or in ESP-IDF, as well as interrupt routines, run with a higher priority than the IDLE tasks without delaying or blocking sufficiently long/often enough (such as when executing in a tight while loop), it triggers the watchdog, because that core is now fully busy, meaning it is no longer idling often enough, meaning the idle "tasks" get starved, so they can't reset the watchdog. Your app_main() in ESP-IDF and loop() in Arduino, run with higher priorities than the IDLE tasks. This is the source of the problem. You either have to make some call that blocks your code for atleast 10mS in sufficient intervals, or you have to call yield() or vTaskDelay(NUMBER_OF_MILLISECONDS_TO_DELAY / portTICK_PERIOD_MS) with a minimum of 10mS (otherwise, due to discreteness, it amounts to 0, ie no delay at all, thus won't work. You can work around this by increasing the scheduler frequency).

另一种方法是完全禁用看门狗,但这会使它的使用无效.有一个更优雅的解决方案.如果你确实需要一些东西来消耗所有可用的 CPU 时间,不想为延迟或阻塞的考虑而烦恼,也不想禁用看门狗,但不想让它吠叫,那么把所有密集代码在其自己的函数或函数集中进行操作,并使用以下任务创建函数调用它/每个:

An alternative is fully disabling the watchdog, but this nullifies its uses. There is a more elegant solution. If you do need something to consume all available CPU time, and don't want to bother with considerations of delay or blocking, and don't want to disable the watchdog, but don't want it to bark, then put all intensive code operations in its own function or set of functions, and call it/each using the following task creation function:

xTaskCreate(someFunction, "HumanReadableNameofTask", 4096, NULL, tskIDLE_PRIORITY, NULL);

其中您的函数具有以下签名:

where your function has the following signature:

void someFunction(void* arg)

无论如何这都不会触发看门狗,因为它使用 tskIDLE_PRIORITY 优先级.我不确定它有什么价值,但它似乎大于 10,因为我尝试了 10 但它不起作用.不确定 11 是否有,这会比 IDLE 任务的优先级低.但请注意,您放置在 someFunction() 中的任何代码都不会执行,除非在 CPU 空闲时.因此,您的所有其他代码仍必须足够睡眠/延迟/阻塞,以便有时间运行.这是无休止的密集代码的理想场所,例如电机控制和 PID 控制回路.

This won't trip the watchdog no matter what, because it uses the tskIDLE_PRIORITY priority. I'm not sure what value it has, but it seems greater than 10, because I tried 10 and it didn't work. Not sure if 11 did, which would be lower priority than the IDLE tasks. Note though, any code you place in someFunction(), won't execute at all except during times when the CPU is IDLE. So all your other code must still sleep/delay/block sufficiently enough to give it time to run. This is the ideal place for endless intensive code, such as motor control and PID control loops.

您甚至可以在 Arduino 中执行此操作.

You can even do this in Arduino.

这篇关于任务看门狗被触发./abort() 在核心 0 上的 PC 0x400de07b 上被调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆