xTaskCreate does't work constantly

ruziev-dev
Posts: 1
Joined: Fri Jun 23, 2023 4:41 am

xTaskCreate does't work constantly

Postby ruziev-dev » Fri Jun 23, 2023 5:24 am

Hi! I have faced with a problem: Sometimes FreeRTOS ignores creating a new task (xTaskCreate).

In code (see below) there are two places with calling functions xTaskCreate(Door::_FollowLockStopTriggerTaskStart, NULL, 6 * configMINIMAL_STACK_SIZE, this, configMAX_PRIORITIES, &_xLockActiveExecutionHandler);

Code: Select all

#include "Door.h"

#define LOG_LOCAL_LEVEL ESP_LOG_INFO
#include "esp_log.h"
static const char *TAG = "DOOR CLASS";

Door::Door(
    int irptLockPin,
    int openLimitPin,
    int preCloseLimitPin,
    int closeLimitPin,
    int lock_pin_A,
    int lock_pin_B,
    int actuator1_pin_A,
    int actuator1_pin_B,
    int actuator2_pin_A,
    int actuator2_pin_B)
{

    esp_log_level_set(TAG, LOG_LOCAL_LEVEL);

    _pin_irptLock = irptLockPin;
    _pin_openLimit = openLimitPin;
    _pin_preCloseLimit = preCloseLimitPin;
    _pin_closeLimit = closeLimitPin;

    pinMode(_pin_irptLock, INPUT_PULLUP);
    pinMode(_pin_openLimit, INPUT_PULLUP);
    pinMode(_pin_preCloseLimit, INPUT_PULLUP);
    pinMode(_pin_closeLimit, INPUT_PULLUP);

    lock = MotorHBridge(lock_pin_A, lock_pin_B);
    actuator1 = MotorHBridge(actuator1_pin_A, actuator1_pin_B);
    actuator2 = MotorHBridge(actuator2_pin_A, actuator2_pin_B);
}

void Door::open()
{
    // if lock phase of opening or chosing is active it has to be done
    if (_xLockActiveExecutionHandler == NULL)
    {
        // stop close task if it exists
        if (_xCloseTaskHandler != NULL)
        {
            vTaskDelete(_xCloseTaskHandler);
            _xCloseTaskHandler = NULL;
        }

        // run only in case if there is not any open task has been run before
        if (_xOpenTaskHandler == NULL)
        {
            xTaskCreate(Door::_OpenTaskStart, NULL, 6 * configMINIMAL_STACK_SIZE, this, configMAX_PRIORITIES, &_xOpenTaskHandler);
        }
    }
}

void Door::_FollowLockStopTriggerTaskStart(void *taskParameters)
{
    ESP_LOGI(TAG, "Task _FollowLockStopTrigger will be started");

    Door *this_pointer = (Door *)taskParameters;
    this_pointer->_FollowLockStopTrigger();
}

void Door::_FollowLockStopTrigger()
{
    ESP_LOGI(TAG, "Task _FollowLockStopTrigger has been started");

    uint32_t maxLockUpTime = 3100;
    uint32_t startTime = millis();

    while (digitalRead(_pin_irptLock))
    {
        if (millis() - startTime >= maxLockUpTime)
        {
            ESP_LOGE(TAG, "lock interrupt pin does't work");
            break;
        }
        ESP_LOGI(TAG, "Wait _pin_irptLock triger");
        vTaskDelay(pdMS_TO_TICKS(100));
    }

    lock.stop();
    ESP_LOGI(TAG, "lock.stop()");

    ESP_LOGI(TAG, "Task _FollowLockStopTrigger has been executed");
    _xLockActiveExecutionHandler = NULL;
    vTaskDelete(xTaskGetCurrentTaskHandle());
}

void Door::_OpenTaskStart(void *taskStartParameters)
{
    Door *this_pointer = (Door *)taskStartParameters;
    this_pointer->_TaskOpen();
}

void Door::_TaskOpen()
{
    ESP_LOGI(TAG, "Task _TaskOpen has been started");

    // if _TaskClose were runned before
    actuator1.stop();
    actuator2.stop();

    // unlock
    lock.up();

    vTaskDelay(pdMS_TO_TICKS(400));

    actuator1.down();
    actuator2.down();
    ESP_LOGI(TAG, "actuators down");

    xTaskCreate(Door::_FollowLockStopTriggerTaskStart, NULL, 6 * configMINIMAL_STACK_SIZE, this, configMAX_PRIORITIES, &_xLockActiveExecutionHandler);
    configASSERT(_xLockActiveExecutionHandler);

    // actuator movement
    while (!isOpen())
    {
        // TODO: make constraint for a time
        ESP_LOGI(TAG, "actuator.down()");
        vTaskDelay(pdMS_TO_TICKS(50));
    }

    actuator1.stop();
    actuator2.stop();

    // self end task
    ESP_LOGI(TAG, "Task _TaskOpen is completed");
    _xOpenTaskHandler = NULL;
    vTaskDelete(xTaskGetCurrentTaskHandle());
}

void Door::close()
{
    // if lock phase of opening or chosing is active it has to be done
    if (_xLockActiveExecutionHandler == NULL)
    {
        // stop open task if it exists
        if (_xOpenTaskHandler != NULL)
        {
            vTaskDelete(_xOpenTaskHandler);
            _xOpenTaskHandler = NULL;
        }

        // run only in case if there is not any close task has been run before
        if (_xCloseTaskHandler == NULL)
        {
            xTaskCreate(Door::_CloseTaskStart, NULL, 6 * configMINIMAL_STACK_SIZE, this, configMAX_PRIORITIES, &_xCloseTaskHandler);
        }
    }
}
void Door::_CloseTaskStart(void *taskStartParameters)
{
    Door *this_pointer = (Door *)taskStartParameters;
    this_pointer->_TaskClose();
}

void Door::_TaskClose()
{
    ESP_LOGI(TAG, "Task _TaskClose has been started");
    while (1)
    {
        actuator1.up();
        actuator2.up();
        while (!isPreClosed())
        {
            // TODO: make constraint for a time
            ESP_LOGI(TAG, "actuator.up()");
            vTaskDelay(pdMS_TO_TICKS(50));
        }

        lock.down();

        vTaskDelay(pdMS_TO_TICKS(400));

        actuator1.stop();
        actuator2.stop();

        xTaskCreate(Door::_FollowLockStopTriggerTaskStart, NULL, 6 * configMINIMAL_STACK_SIZE, this, configMAX_PRIORITIES, &_xLockActiveExecutionHandler);
        configASSERT(_xLockActiveExecutionHandler);

        // self end task
        ESP_LOGI(TAG, "Task _TaskClose is completed");
        _xCloseTaskHandler = NULL;
        vTaskDelete(xTaskGetCurrentTaskHandle());
    }
}

uint8_t Door::checkDoorStatus()
{

    bool isLock = isLocked();
    bool isPreClose = isPreClosed();
    bool isOpenned = isOpen();

    if (_xCloseTaskHandler != NULL)
        return DoorMode_CLOSING;
    else if (_xOpenTaskHandler != NULL)
        return DoorMode_OPENING;
    else if (isLock && !isOpenned)
        return DoorMode_CLOSED;
    else if (!isLock && isOpenned)
        return DoorMode_OPEN;
    else
        return DoorMode_UNKNOWN;
}

bool Door::isOpen()
{
    return digitalRead(_pin_openLimit);
}

bool Door::isPreClosed()
{
    return digitalRead(_pin_preCloseLimit);
}
bool Door::isLocked()
{
    return digitalRead(_pin_closeLimit);
}



And sometimes this works good and I see good logs and execution

Code: Select all


[632745][I][Door.cpp:99] _TaskOpen(): [DOOR CLASS] Task _TaskOpen has been started
[633146][I][Door.cpp:112] _TaskOpen(): [DOOR CLASS] actuators down
[633147][I[]6[3D3o1o4r7.]c[pIp]:[1D2o1o]r ._cTpaps:k5O9p]e n_(Fol oDLORkCLopSriageuaasr.dort():
[DOOR CLASS] Task _FollowLockStopTrigger will be started
[633155][I][Door.cpp:67] _FollowLockStopTrigger(): [DOOR CLASS] Task _FollowLockStopTrigger has been started
[633164][I][Door.cpp:79] _FollowLockStopTrigger(): [DOOR CLASS] Wait _pin_irptLock triger
[633199][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[633249][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[633272][I][Door.cpp:79] _FollowLockStopTrigger(): [DOOR CLASS] Wait _pin_irptLock triger
[633299][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[633349][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[633372][I][Door.cpp:79] _FollowLockStopTrigger(): [DOOR CLASS] Wait _pin_irptLock triger
[633399][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[633449][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[633472][I][Door.cpp:79] _FollowLockStopTrigger(): [DOOR CLASS] Wait _pin_irptLock triger
[633499][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[633549][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[633572][I][Door.cpp:79] _FollowLockStopTrigger(): [DOOR CLASS] Wait _pin_irptLock triger
[633599][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[633649][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[633672][I][Door.cpp:79] _FollowLockStopTrigger(): [DOOR CLASS] Wait _pin_irptLock triger
[633699][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[633749][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[633771][I][LedStripControl.cpp:103] TaskON(): [LED_STRIP_CONTROL] Side: R TaskON has started; handler: 1070484980
[633772][I][Door.cpp:79] _FollowLockStopTrigger(): [DOOR CLASS] Wait _pin_irptLock triger
[633799][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[633849][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[633877][I][Door.cpp:79] _FollowLockStopTrigger(): [DOOR CLASS] Wait _pin_irptLock triger
[633899][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[633949][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[633977][I][Door.cpp:79] _FollowLockStopTrigger(): [DOOR CLASS] Wait _pin_irptLock triger
[633999][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[634049][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[634077][I][Door.cpp:79] _FollowLockStopTrigger(): [DOOR CLASS] Wait _pin_irptLock triger
[634099][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[634149][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[634177][I][Door.cpp:79] _FollowLockStopTrigger(): [DOOR CLASS] Wait _pin_irptLock triger
[634199][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[634249][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[634277][I][Door.cpp:79] _FollowLockStopTrigger(): [DOOR CLASS] Wait _pin_irptLock triger
[634299][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[634349][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[634377][I][Door.cpp:84] _FollowLockStopTrigger(): [DOOR CLASS] lock.stop()
[634378][I][Door.cpp:86] _FollowLockStopTrigger(): [DOOR CLASS] Task _FollowLockStopTrigger has been executed
[634399][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[634449][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[634499][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[634549][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[634599][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[634649][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[634699][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[634749][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[634799][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[634849][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[634899][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[634949][I][Door.cpp:121] _TaskOpen(): [DOOR CLASS] actuator.down()
[635000][I][Door.cpp:129] _TaskOpen(): [DOOR CLASS] Task _TaskOpen is completed


But sometimes FreeRTOS ignores calling `xTaskCreate` and `configASSERT(_xLockActiveExecutionHandler);` throws exception.

Code: Select all

[327722][I][Door.cpp:99] _TaskOpen(): [DOOR CLASS] Task _TaskOpen has been started
[328123][I][Door.cpp:112] _TaskOpen(): [DOOR CLASS] actuators down

assert failed: void Door::_TaskOpen() Door.cpp:115 (_xLockActiveExecutionHandler)

Backtrace: 0x40378142:0x3fce7790 0x4037f9c1:0x3fce77b0 0x4038590d:0x3fce77d0 0x4200374f:0x3fce7900 0x420037a9:0x3fce7930


How can I fix this behaviour?

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

Re: xTaskCreate does't work constantly

Postby ESP_Sprite » Sat Jun 24, 2023 2:32 am

So first of all: it'd be generally bad practice to create and destroy tasks like that: it's an expensive operation and you normally do it on startup only. For instance, you could have a doorTask which is created on startup and normally waits on some inter-task thing (a FreeRTOS semaphore or queue or whatever) to wake up and know what it must do, then do it, then go back to sleep waiting for a new command.

For your issue: I think the problem is that your task actually *is* created, but finishes before the assert in your creating task is called. While it finishes, it sets the handle variable to NULL and the assert triggers. Again, I'd not try to work around this, but rather do it in the proper way as described above.

Who is online

Users browsing this forum: No registered users and 45 guests