繁体   English   中英

任务看门狗被触发。/abort() 在核心 0 上的 PC 0x400de07b 上被调用

[英]Task watchdog got triggered./abort() was called at PC 0x400de07b on core 0

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

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

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

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

// 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


}   

欢迎来到 String 堆压裂俱乐部:

String latitude1;
String latitude1Param;
String longitude1;
String longitude1Param;
String latitude2;
String latitude2Param;
String longitude2;
String longitude2Param;
String commitType;;

与异步网络服务器相结合是一个巨大的问题。 我重写了一个大约 15.000 行的应用程序来摆脱字符串(也在使用的库中),从那时起不再重置和重新启动。 希望这对您的项目有所帮助。
使用预定义的固定字符数组,它们将进入堆栈并保持低堆损坏。使用 strcpy、strcat、itoa / atoi 等函数来构建消息或检索值。

编辑:用固定字符数组示例替换字符串类

 char numBuffer [16] ={'\0'}    // For 15 chars and the null terminator
 char latitude1 [32] ={'\0'}    // For 31 chars and the null terminator
  .... some code here ....
 strcpy (latitude1 , "No values here"); 
 //or
 strcpy (latitude1 , "Value 1: ");
 itoa (SomeIntDataNumber, numBuffer,10);
 strcat (latitude1, numBuffer)   // append the converted SomeIntDataNumber

如果您使用 memset,还要做一件事,请确保您进行了适当的内存管理,还要检查使用的库是否大量使用 String 类。 一些库在静态环境中工作得很好,在网络上下文中使用它们会使 ESP 崩溃。 我不得不放弃一些库,或者至少在没有 String 类的情况下重写它们。
进一步阅读: https : //hackingmajenkoblog.wordpress.com/2016/02/04/the-evils-of-arduino-strings/
最后提示:尝试注释掉/用虚拟字符替换 String 类的所有外观,然后重试代码。

wdt是看门狗定时器。 它是一个计时器,用于检测您的代码是否已崩溃。 如果没有定期重置,它将抛出错误并重新启动 ESP32。 定时器需要经常重置。

请注意,该错误表明当看门狗定时器触发时,正在运行的是async_tcp任务。 您正在使用 AsyncWeb 服务器,它使用 async_tcp。

当异步 Web 服务器收到页面请求时,它会调用您的代码。 您有单个页面的处理程序。 这些处理程序需要以我们必须处理loop()的方式处理对它们的调用 - 如果您花费 3 秒或更长时间没有返回或调用delay()yield() 这使底层软件有机会重置看门狗定时器。

查看您的网页处理程序。 寻找您可能会在其中度过很长时间的地方。

您会发现您在处理程序中为“/go”调用了goWayPoint() 它有一个循环,可能会阻塞 5 秒。 5 秒太长了 - 如果该循环没有返回或调用delay()看门狗定时器将触发,它会触发。

简单的解决方法是在while(true)循环中添加对delay()的调用。

 while (true)  
  {
  delay(1);

这将使底层代码重置看门狗定时器。

如果您的代码的其他部分( getCompass()getGPS()或其他东西)花费太长时间,那将无济于事。

最终你应该重构你的代码。 您在 Web 服务器回调中做了太多工作。 这项工作应该在独立的任务中完成——也许在loop() 但这是一个大工程。 在 web 服务器回调中的任何地方添加对delay(1)调用,如果你有一个 while 循环或需要一些时间来做一些处理是笨拙的,但应该可以解决这个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM