Help with ESP32 and RTOS

protttoy
Posts: 2
Joined: Thu Apr 07, 2022 9:12 am

Help with ESP32 and RTOS

Postby protttoy » Thu Apr 07, 2022 9:27 am

Hi, I don't understand how the vTaskResume and vTaskSuspend commands work in this following code:

Code: Select all


static TaskHandle_t handle_task1 = NULL;
static TaskHandle_t handle_task2 = NULL;
static TaskHandle_t handle_task3 = NULL;


void setup()
{
    Serial.begin(115200);
    delay(2000);
    
    // create tasks
    xTaskCreate(task1, "task1", 1024, NULL, 2, &handle_task1);
    xTaskCreate(task2, "task2", 1024, NULL, 2, &handle_task2);
    xTaskCreate(task3, "task3", 1024, NULL, 2, &handle_task3);
}

void loop()
{
    // nothing to do here
    vTaskDelete(NULL);
}


void task1(void *params)
{
    TickType_t xLastWakeUpTime = xTaskGetTickCount();
    const TickType_t xDelay10000ms = pdMS_TO_TICKS(10000);

    while(1)
    {   xLastWakeUpTime = xTaskGetTickCount();

        if (handle_task2)
        vTaskSuspend(handle_task2);
        if (handle_task3)
        vTaskSuspend(handle_task3);
        Serial.println("in Task 1");
        vTaskResume(handle_task2);
        vTaskResume(handle_task3);
        
        vTaskDelayUntil(&xLastWakeUpTime , xDelay10000ms );
    }
}

void task2(void *params)
{
    TickType_t xLastWakeUpTime = xTaskGetTickCount();
    const TickType_t xDelay5000ms = pdMS_TO_TICKS(5000);

    while(1)
    {
        xLastWakeUpTime = xTaskGetTickCount();

        if (handle_task1)
        vTaskSuspend(handle_task1);
        if (handle_task3)
        vTaskSuspend(handle_task3);
        Serial.println("in Task 2");
        vTaskResume(handle_task1);
        vTaskResume(handle_task3);

        vTaskDelayUntil(&xLastWakeUpTime , xDelay5000ms );
    }
}

void task3(void *params)
{
    TickType_t xLastWakeUpTime = xTaskGetTickCount();
    const TickType_t xDelay1000ms = pdMS_TO_TICKS(1000);
    while(1)
    {
        xLastWakeUpTime = xTaskGetTickCount();

        if (handle_task2)
        vTaskSuspend(handle_task2);
        if (handle_task1)
        vTaskSuspend(handle_task1);

        Serial.println("in Task 3");
        vTaskResume(handle_task2);
        vTaskResume(handle_task1);
        
        vTaskDelayUntil(&xLastWakeUpTime , xDelay1000ms );    
    }
}

What I am trying to achieve: The task1 should run every 10 seconds but when it is running the other two tasks should not run. Similarly task2 should run every 5 seconds and task3 every second.

But the output is like this: data of 20 seconds
Timestamp --> Serial output
15:20:56:596 --> in Task 1in Task 2
15:20:56:596 -->
15:20:56:596 --> in Task 3
15:20:57:539 --> in Task 3
15:20:57:539 --> in Task 2
15:20:57:540 --> in Task 1
15:20:58:539 --> in Task 3
15:20:58:540 --> in Task 2
15:20:58:541 --> in Task 1
15:20:59:539 --> in Task 3
15:20:59:540 --> in Task 2
15:20:59:541 --> in Task 1
15:21:00:539 --> in Task 3
15:21:00:540 --> in Task 2
15:21:00:541 --> in Task 1
15:21:01:538 --> in Task 3
15:21:01:540 --> in Task 2
15:21:01:541 --> in Task 1
15:21:02:538 --> in Task 3
15:21:02:540 --> in Task 2
15:21:02:541 --> in Task 1
15:21:03:538 --> in Task 3
15:21:03:539 --> in Task 2
15:21:03:540 --> in Task 1
15:21:04:538 --> in Task 3
15:21:04:539 --> in Task 2
15:21:04:540 --> in Task 1
15:21:05:538 --> in Task 3
15:21:05:539 --> in Task 2
15:21:05:540 --> in Task 1
15:21:06:538 --> in Task 3
15:21:06:539 --> in Task 2
15:21:06:540 --> in Task 1
15:21:07:538 --> in Task 3
15:21:07:539 --> in Task 2
15:21:07:541 --> in Task 1
15:21:08:538 --> in Task 3
15:21:08:540 --> in Task 2
15:21:08:541 --> in Task 1
15:21:09:538 --> in Task 3
15:21:09:539 --> in Task 2
15:21:09:540 --> in Task 1
15:21:10:538 --> in Task 3
15:21:10:539 --> in Task 2
15:21:10:540 --> in Task 1
15:21:11:538 --> in Task 3
15:21:11:539 --> in Task 2
15:21:11:540 --> in Task 1
15:21:12:538 --> in Task 3
15:21:12:539 --> in Task 2
15:21:12:540 --> in Task 1
15:21:13:538 --> in Task 3
15:21:13:539 --> in Task 2
15:21:13:540 --> in Task 1
15:21:14:538 --> in Task 3
15:21:14:539 --> in Task 2
15:21:14:540 --> in Task 1
15:21:15:537 --> in Task 3
15:21:15:538 --> in Task 2
15:21:15:539 --> in Task 1
15:21:16:537 --> in Task 3
15:21:16:538 --> in Task 2
15:21:16:539 --> in Task 1
15:21:17:538 --> in Task 3
15:21:17:538 --> in Task 2
15:21:17:539 --> in Task 1
Please can anyone explain what is happening ? I am using Arduino IDE and ESP core 2.0.3-RC1

lbernstone
Posts: 826
Joined: Mon Jul 22, 2019 3:20 pm

Re: Help with ESP32 and RTOS

Postby lbernstone » Thu Apr 07, 2022 6:21 pm

I know it is not the answer you are looking for, but I think what you really want here is a mutex with a 10 (or maybe 9) second timeout, rather than suspending the processes. That way, you could just have the three functions on timers, and if Task1 timer is defined first, it will consistently run first, take the mutex, and the other two processes will have to wait for it to release the lock.

ESP_Sprite
Posts: 9730
Joined: Thu Nov 26, 2015 4:08 am

Re: Help with ESP32 and RTOS

Postby ESP_Sprite » Thu Apr 07, 2022 11:53 pm

That is one mess of code. What may be happening is that as soon as you wake up a task, it gets to work and suspends the task that woke it up. (This could even happen between the vTaskDelayUntil and GetTickCount, making your task sleep for longer than intended.)

protttoy
Posts: 2
Joined: Thu Apr 07, 2022 9:12 am

Re: Help with ESP32 and RTOS

Postby protttoy » Fri Apr 08, 2022 1:56 am

with the vTaskResume the task should resume from the moment it was suspended, right ? Why is the vTaskDelayUntill not working in this case ? Please see the output, the tasks are printing things without executing the delay.

ESP_Sprite
Posts: 9730
Joined: Thu Nov 26, 2015 4:08 am

Re: Help with ESP32 and RTOS

Postby ESP_Sprite » Fri Apr 08, 2022 8:19 am

Ah, that is potentially because a delay already suspends the task. Likely the resume also resumes it if the task is suspended because of that.

sfoulk526
Posts: 2
Joined: Sat Apr 16, 2022 7:22 am

Re: Help with ESP32 and RTOS

Postby sfoulk526 » Sat Apr 16, 2022 7:58 am

lbernstone wrote:
Thu Apr 07, 2022 6:21 pm
I know it is not the answer you are looking for, but I think what you really want here is a mutex with a 10 (or maybe 9) second timeout, rather than suspending the processes. That way, you could just have the three functions on timers, and if Task1 timer is defined first, it will consistently run first, take the mutex, and the other two processes will have to wait for it to release the lock.
Just what I was thinking, this is definitely job for the mutex.

Who is online

Users browsing this forum: No registered users and 83 guests