Page 1 of 1

FreeRTOS task integration

Posted: Thu Jul 29, 2021 11:47 am
by alqine
Hi guys,

I am programming a device, which should get some values from sensors and send them over the MQTT protocol back to the server. Right now, there are two ways how to connect to the internet - external LTE modem over pppos and WiFi integrated right on ESP32.

I created two tasks - MQTT and CONN. Basically, my main function spawns those two tasks.

The CONN task connects to the internet (either using WiFi or LTE modem - it depends on current settings and availability of each method) and then unlocks mutex shared with MQTT task. After this, CONN task just maintains connection - meaning it checks for disconnect events and tries to reconnect when possible, or switch between WiFi <-> LTE.

MQTT task, after unlocking from CONN connects to the broker and waits for other parts of the application to publish messages. Again, MQTT task is responsible for waiting for disconnect event to reconnect back.

Now comes my question. Is it okay to end the task with infinite while?
  1. void task_mqtt(void *param) {
  2.  
  3.     esp_err_t ret = ESP_FAIL;
  4.  
  5.     // Wait for muttex from CONN task
  6.     xSemaphoreTake(mqtt_semaphore_start, portMAX_DELAY);
  7.  
  8.     // Connect to the broker, start event loop
  9.     ret = mqtt_init();
  10.     while (ret != ESP_OK) {
  11.  
  12.         // Wait before next try
  13.         vTaskDelay(MS_TO_TICKS(10 * 1000));
  14.  
  15.         // Try it again
  16.         ret = mqtt_init();
  17.     }
  18.  
  19.     // Here, MQTT should be connected to the broker
  20.     while (1) {
  21.         // IS THIS REQUIRED?
  22.     }
  23. }
The problem is that mqtt_init function contains all the code necessary to connect to the broker, it starts event loops and registers event handlers. I suppose that without the loop at the end, all code would stop. But would not the infinite loop exhaust all resources while doing nothing? Should I insert small delay? Or is this completely wrong design?

Thank you.

Re: FreeRTOS task integration

Posted: Fri Jul 30, 2021 2:02 am
by Victoria Nope
I don't know which component do you use, but it's not usual to rely on a task state in the application code. As that is the only reason I can think about when speaking about keeping the task in "running" state after doing its work. So my best guess is that your design is wrong.

Usual pattern for a task that is going to be used more than once is making a loop in which you wait for its notification to start the work. In pseudocode that might be, e.g.:

Code: Select all

void do_something_more_than_once(void *param)
{
    while (1) {
        ulTaskNotifyTake(pdFALSE, portMAX_DELAY); // wait for the notification to start the work
        // <- do the work here and go back in the loop to wait for another notification
    } 
    vTaskDelete(NULL); // if you want to exit the task, break the above loop and the task will delete itself when the processor goes idle
}
I've mentioned this as it seems that you're making some sort of a connection task which I bet you can use more than once.