Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FreeRTOS Task should not return - ESP32

I'm using multi-threading on my ESP32. I have created two tasks and pinned them to core 1. With one of them, I get the following error:

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

However, there is no return statement in my "MeasurementTask" (see code below). What's the issue here?

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");
}

Sketch:

#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();
}

There are quite some files included in the tracker.h, but I don't believe they're relevant to this problem. Some of the functions used in the takeMeasurement do have return values, but I never return them in that function itself.

like image 665
Lithimlin Avatar asked Aug 28 '20 13:08

Lithimlin


People also ask

How do I suspend a task on FreeRTOS?

Now, coming to the individual task codes, Task4 suspends Task2, Task3 and then itself. Task 1 resumes these tasks one by one, and then deletes itself. Tasks 2 and 3 just delete themselves after printing a statement. Thus, Task4, with the highest priority starts first, and suspends Tasks 2, 3 and itself.

Is ESP IDF RTOS?

The Espressif Internet Development Framework (ESP-IDF) uses FreeRTOS to make better use of the two high speed processors and manage the numerous built-in peripherals. It is done by creating tasks.

What is vTaskDelete?

vTaskDelete():This function is used to delete as task. To delete the own task we should pass NULL as parameter.

How does FreeRTOS work?

The main job of all operating systems is to run and coordinate user tasks. Like many operating systems, the basic unit of work in FreeRTOS is the task. FreeRTOS uses a Task Control Block (TCB) to represent each task. The TCB is defined in tasks.c like this:

How do I create tasks in FreeRTOS?

Create a new task and add it to the list of tasks that are ready to run. Internally, within the FreeRTOS implementation, tasks use two blocks of memory. The first block is used to hold the task’s data structures. The second block is used by the task as its stack.

How is ESP-IDF FreeRTOS started?

Instead, ESP-IDF FreeRTOS is started automatically. The entry point is a user defined voidapp_main(void)function. Typically, users would spawn the rest of their applications task from app_main. The app_mainfunction is allowed to return at any point (i.e., before the application terminates). The app_mainfunction is called from the maintask.

How do list items work in FreeRTOS scheduling lists?

Each task has two list items for use in FreeRTOS’s various scheduling lists. When a task is inserted into a list FreeRTOS doesn’t insert a pointer directly to the TCB. Instead, it inserts a pointer to either the TCB’s xGenericListItem or xEventListItem.


2 Answers

In FreeRTOS, tasks are started with xTaskCreate... and ended with vTaskDelete. A task function may not simply "end", this is not allowed.

Put vTaskDelete(NULL); at the end of the function to gracefully end the task:

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

Having said that, tasks are usually meant to be long-running. For example, the measurement task could be an endless loop that takes the measurement, sleeps for a while, and repeats.

like image 65
rustyx Avatar answered Oct 03 '22 18:10

rustyx


It seems to me that You forgot to add an infinite loop:

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 **
}
like image 25
Воха Воха Avatar answered Oct 03 '22 19:10

Воха Воха