No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Ciclo de vida de las tareas con FreeRTOS

16/30
Recursos

Aportes 6

Preguntas 3

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

La razón por la que los logs del ejemplo al final, no salen intercalados uno a uno de forma ideal, es porque en la práctica FreeRTOS le asigna un tiempo fijo a cada tarea, por lo que mientras la tarea siga dentro de su tiempo disponible, seguirá ejecutando los printf que le corresponden, hasta que FreeRTOS le de paso a la siguiente.

Es por eso que vemos varios “Task 1” juntos, luego varios “Task 2” juntos, y así sucesivamente.

Ahí os dejo mi código

#include <stdio.h>
#include "esp_chip_info.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

TaskHandle_t task1Handle = NULL;
TaskHandle_t task1Handle2 = NULL;


void task1(void *arg){
    unsigned int counter = 0;
    while(1){
        printf("Tarea 1, felicidades, count: %d\n", counter);
        counter++;
        if(counter == 5){
            printf("tarea 2 suspendida\n");
            vTaskSuspend(task1Handle2);
        }
        if (counter == 10){
            printf("tarea 2 reanudada\n");
            vTaskResume(task1Handle2);
        }
        if (counter == 15){
            printf("tarea 2 eliminada\n");
            vTaskDelete(task1Handle2);
        }
        if (counter == 15){
            printf("tarea 1 finalizada\n");
            vTaskDelete(NULL);
        }
        vTaskDelay(100 / portTICK_PERIOD_MS);
    }
}
void task2(void *arg){
    unsigned int counter = 0;
    while(1){
        printf("Tarea 2, felicidades, count: %d\n", counter);
        counter++;
        if (counter>15){
            printf("tarea 2 finalizada\n");
            vTaskDelete(NULL);
        }
        vTaskDelay(100 / portTICK_PERIOD_MS);
    }
}
void app_main(void)
{
    xTaskCreatePinnedToCore(task1, "task1", 4096, NULL, 10, &task1Handle, 0);
    xTaskCreatePinnedToCore(task2, "task2", 4096, NULL, 10, &task1Handle2, 1);
}

Le puse un pequeño delay de 100ms porque sin eso algunos printf no salían y parecía que en el tiempo en el que se montaba la tarea 2 en el segundo núcleo le daba tiempo la la tarea 1 de ejecutarse en su totalidad y los log salían muy raro.

En mi vida soy el core 1 entrando en pánico ;’)

Estoy probando con el LilyGo TTGO LoRa 32, y obtenía la salida:

I (313) app_start: Starting scheduler on CPU0
I (318) app_start: Starting scheduler on CPU1
I (318) main_task: Started on CPU0
I (328) main_task: Calling app_main()
Task 1 count: 1
Task 1 count: 2
Task 1 count: 3
Task 2 suspended
I (328) main_task: Returned from app_main()
Task 2 count: 1
Task 2 count: 2
Task 2 count: 3
Task 2 count: 4
Task 2 count: 5
Task 2 count: 6
Task 2 count: 7
Task 2 count: 8
Task 2 count: 9
Task 2 count: 10
Task 2 count: 11
Task 2 count: 12
Task 2 count: 13
Task 2 count: 14
Task 2 count: 15
Task 2 deleted

No se ve que la tarea 1 no controla la tarea. 2, ya que se la tarea 2 sigue ejecutándose después de que la tarea 1 la suspende, así que agregué al final del while de cada tarea un delay:

while (1)
    {
        ...
        vTaskDelay(pdMS_TO_TICKS(100));
    }

Y de esa forma ya funciona como debe:

I (313) app_start: Starting scheduler on CPU0
I (318) app_start: Starting scheduler on CPU1
I (318) main_task: Started on CPU0
I (328) main_task: Calling app_main()
Task 1 count: 1
I (328) main_task: Returned from app_main()
Task 2 count: 1
Task 1 count: 2
Task 2 count: 2
Task 1 count: 3
Task 2 suspended
Task 1 count: 4
Task 1 count: 5
Task 1 count: 6
Task 1 count: 7
Task 1 count: 8
Task 1 count: 9
Task 1 count: 10
Task 2 resumed
Task 2 count: 3
Task 1 count: 11
Task 2 count: 4
Task 1 count: 12
Task 2 deleted
Task 1 count: 13
Task 1 count: 14
Task 1 count: 15
Task 1 deleted

Ciclo de vida de las tareas con FreeRTOS

Este es mi codigo utilizando vTaskDelay

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "time.h"

TaskHandle_t taskHandle_1;
TaskHandle_t taskHandle_2;

const TickType_t taskDelay_1 = 500 / portTICK_PERIOD_MS;
const TickType_t taskDelay_2 = 700 / portTICK_PERIOD_MS;

time_t elapsed_time_1;
time_t elapsed_time_2;

int counter_1 = 0;
int counter_2 = 0;

void task_1(void *args)
{
    while (true)
    {
        time(&elapsed_time_1);
        printf("Task 1 counter: %d seconds: %lld\n", counter_1, elapsed_time_1);
        counter_1++;
        vTaskDelay(taskDelay_1);

        switch (counter_1)
        {
            case 10:
                printf("Suspendiendo la tarea 2\n");
                vTaskSuspend(taskHandle_2);
                break;
            case 20:
                printf("Resumiendo la tarea 2\n");
                vTaskResume(taskHandle_2);
                break;
            case 30:
                printf("Eliminando la tarea 2\n");
                vTaskDelete(taskHandle_2);
                break;        
            case 50 ... 60:
                printf("Eliminando la tarea 1\n");
                vTaskDelete(taskHandle_1);
                break; 
            default:
                break;         
        };

    }
}

void task_2(void *args)
{
    while (true)
    {
        time(&elapsed_time_2);
        printf("Task 2 counter: %d seconds: %lld\n", counter_2, elapsed_time_2);
        counter_2++;
        vTaskDelay(taskDelay_2);

        if (counter_2 > 50)
        {
            printf("Finalizando la tarea 2\n");
            vTaskDelete(taskHandle_2);
        }

    }
}


void app_main(void)
{
    xTaskCreate(
        task_1,         //Nombre de la funcion que implementa la tarea
        "Tarea_1",      //Nombre descriptivo de la tarea con fines de debugging
        4096,           //El tamaño del task stack en bytes
        NULL,           //pointer a un parametro cuando la tarea esta siendo creada
        10,             //Prioridad de la tarea un numero
        &taskHandle_1   //apuntador para referenciar la tarea. 
    );
    
    //creamos la tarea asociandola al segundo core
    xTaskCreatePinnedToCore(
        task_2,         //Nombre de la funcion que implementa la tarea
        "Tarea_2",      //Nombre descriptivo de la tarea con fines de debugging
        4096,           //El tamaño del task stack en bytes
        NULL,           //pointer a un parametro cuando la tarea esta siendo creada
        10,             //Prioridad de la tarea un numero
        &taskHandle_2,  //apuntador para referenciar la tarea. 
        1               // core 0 y core 1
    );
}