【问题标题】:FreeRTOS Task should not return - ESP32FreeRTOS 任务不应返回 - ESP32
【发布时间】:2020-12-17 10:54:45
【问题描述】:

我在我的 ESP32 上使用多线程。我创建了两个任务并将它们固定到核心 1。其中一个任务出现以下错误:

E (20426) FreeRTOS: FreeRTOS Task "MeasurementTask" should not return, Aborting now!
abort() was called at PC 0x4008b8f3 on core 1

Backtrace: 0x4008f34c:0x3ffd0a40 0x4008f57d:0x3ffd0a60 0x4008b8f3:0x3ffd0a80

Rebooting...

但是,我的“MeasurementTask”中没有return 语句(参见下面的代码)。这里有什么问题?

tracker.cpp:

#include "tracker.h"

void threadedLoop(void *pvParameters) {
  Serial.println("Loop task pinned");
  for(;;) {
    checkAPTrigger();
    mqttLoop();
  }
}

void setupTracker() {
  Serial.print("Setup start: ");
  Serial.println(millis());
  Wire.begin();
  setup_sensors();
  if(setupAP()) {
    setupTime();
    setupMQTT();
  }
  Serial.print("Setup done: ");
  Serial.println(millis());

  Serial.println("Pinning measurement");
  TaskHandle_t measureTask;
  xTaskCreatePinnedToCore(
    takeMeasurement,
    "MeasurementTask",
    2048,
    NULL,
    1,
    NULL,
    ARDUINO_RUNNING_CORE
  );

  Serial.println("Pinning loop");
  TaskHandle_t loopTask;
  xTaskCreatePinnedToCore(
    threadedLoop,
    "LoopTask",
    2048,
    NULL,
    1,
    NULL,
    ARDUINO_RUNNING_CORE
  );
}

void loopTracker() {
  //takeMeasurement();
}

void takeMeasurement(void *pvParameters) {
  Serial.println("Measurement task pinned");
  DynamicJsonDocument root(512);
  JsonObject rootObj = root.to<JsonObject>();
  read_sensors(rootObj);

  if(!(settings.mqttUsed && publishData(rootObj))) {
    appendFile("data", root);
  }

  serializeJsonPretty(root, Serial);
  Serial.println("\n---\n");
}

草图:

#include <tracker.h>

void setup() {
  Serial.begin(115200);
  // put your setup code here, to run once:
  wm.resetSettings();
  setupTracker();
}

void loop() {
  // put your main code here, to run repeatedly:
  loopTracker();
}

tracker.h 中包含相当多的文件,但我认为它们与此问题无关。 takeMeasurement 中使用的一些函数确实有返回值,但我从不在该函数本身中返回它们。

【问题讨论】:

  • 通常“不返回”并不意味着缺少return 语句,而是函数的控制流永远不会终止。应该有某种无限的while循环来保持函数无限期地运行。
  • 啊,如果我不想这样,我需要删除任务吗?
  • 我不确定在这种情况下实际的解决方案应该是什么,我只是让您知道错误消息的含义。
  • 好的,感谢您的澄清。那我就试试看是否可行。

标签: c++ multithreading esp32 freertos


【解决方案1】:

在 FreeRTOS 中,tasksxTaskCreate... 开头,以 vTaskDelete 结尾。一个任务函数不能简单地“结束”,这是不允许的。

在函数末尾加上vTaskDelete(NULL);,优雅地结束任务:

void takeMeasurement(void *pvParameters) {
  // . . . task code . . .
  vTaskDelete(NULL);
}

话虽如此,任务通常意味着长期运行。例如,测量任务可能是一个无限循环,它进行测量、休眠一段时间并重复。

【讨论】:

  • 是的,@Patrick Roberts 已经提到了这一点,这确实是解决方案
  • 另外,我想最终实现这个循环,我只是还没有实现,并不总是需要它
【解决方案2】:

在我看来你忘了添加一个无限循环:

void takeMeasurement(void *pvParameters) {
    for(;;){ // ** Start of infinite loop **
        Serial.println("Measurement task pinned");
        DynamicJsonDocument root(512);
        JsonObject rootObj = root.to<JsonObject>();
        read_sensors(rootObj);
    
        if(!(settings.mqttUsed && publishData(rootObj))) {
            appendFile("data", root);
        }
    
        serializeJsonPretty(root, Serial);
        Serial.println("\n---\n");
    }   // ** End of infinite loop **
}

【讨论】:

  • 欢迎使用 stackoverflow。在代码的开头和结尾使用 ``` 来正确格式化它。
【解决方案3】:

我用这个解决它:

  Void Task1code( void * parameter) {
      for(;;) {
        Code for task 1 - infinite loop
        (...)
      }
    }

来自这里:https://randomnerdtutorials.com/esp32-dual-core-arduino-ide/

for(;;) 在任务内部创建一个循环,因此从不请求返回 ...

【讨论】:

    猜你喜欢
    • 2016-08-07
    • 1970-01-01
    • 2021-06-05
    • 2016-12-25
    • 2011-07-05
    • 2017-07-02
    • 2023-03-03
    • 1970-01-01
    • 2021-02-05
    相关资源
    最近更新 更多