Task create and delete multiple times without task handle crashes the system

Hi All,
I have to create a task based on the events.
Inside the task, do functionality based on the events and then send out the responses to the events and delete the task using vTaskDelete(NULL) inside the task.
Based on the response sent there will be further some more events to create the saame task again till a functionality is done.
What i am seeing is the vTaskDelete(NULL) is not deleting the TCB and there is crash happening everytime.
i tried to get the TCB details using vTaskGetHandle() before the task creation and observed that the task handle is not getting cleared after some calls to create and delete the task.
If i wait till the task handle is cleared, i dont see any crash.
Is there any better way not to wait?
Is this happening because the IDLE task is not getting time to cleanup the deleted task?

Are you creating the task with vTaskCreate, or vTaskCreateStatic. If you are using vTaskCreateStatic, then you need to wait for the task to finish being destroyed by the idle task, and if that isn’t happening fairly promptly, you perhaps have your system overloaded.

VTaskCreate shouldn’t have any problems, unless you are short on resources and it just fails to create the task, in which case you again need to wait for the resource to be available.

Personally, unless your system needs different numbers of these tasks to be in existence at once, with a memory allocation that doesn’t allow making the maximum number to just exist, I would just have the task created at the beginning, and when it is done, loop back to the beginning of its loop and wait for a notification that it is needed again.

Do you have the callstack at the time of crash. One likely reason is that you are running out of memory because IDLE task is not getting a chance to run and free the resources.

As @richard-damon suggested, you should consider updating your application to not use task deletion.

Hi @richard-damon ,thank you for the response.
I am using xTaskCreate() API.
There are multiple tasks and few tasks related to display are high priority than the task that is crashing.
Few of those high priority tasks runs without any vTaskDelay() in a continuous loops.
Before creating the task, i used vTaskGetInfo() API to get hold of the Task Handle.
I kept calling this API in a while loop to check if the handle is cleared or not with a vTaskDelay(100);.
I could observe that task handle is not NULL for some time and then once it becomes NULL i am breaking the while loop and continuing to create the task.
This is solving my problem.
I just wanted to check like is there any better solution to make sure the task is deleted when calling vTaskDelete() and then create the task again?

Hi @aggarg ,thank you for the response.
I can think of changing my design but i have so many tasks in my system and some tasks are self deleting. So only thing what i was looking is for a way to check if the task is deleted before creating a new task

vTaskGetInfo() is NOT a good function to call to see if the task is still alive, as it assumes the parameter is a valid task handle. If you really need to see if the task is still alive, use xTaskGetHandle() and refer to the unique name you gave the task. Which will cleanly return 0 when the task is gone.

Note, having tasks that “don’t block” and are not at the idle priority is a good way to get your system tied up. Not using vTaskDelay is ok, as long as they do block waiting on something like a semaphore or queue or the like, to give other tasks time to run. A general guideline is that the idle task should be getting a reasonable percentage of the CPU (at least 10%) most of the time or your system is overloaded, and may criteria want 25-40% available at the initial design (since they know usage will go up as things change).

If you are having problems with idle getting run, you may need to look at your system design.

Hi @richard-damon ,
Sorry i am using xTaskGetHandle() api and not vTaskgetInfo() and xTaskGetHandle() dose not return 0 when the taskcreate() is called.
There were few high priority tasks without vTaskdelay() but call xSemaphoreTake().
So from your answer what i understand is this way of calling xSemaphoreTake() in a high priority task can create issue.
Is my understanding correct?

xSemaphoreTake, with a non-zero block time, will block the task and allow lower priority tasks to run, which is what you want. The key is tasks should block when they don’t actively have something to do, and be woken up when they do. Sometimes people think they want the task to be “polling” resources to see if they are ready, using up a lot of time checking, instead of doing work.

ok got it.
So when i check xTaskGetHandle() and this dose not return 0 even after vTaskDelete(NULL) means that IDLE task did not get time to run to clear the task handle.
I dont see a crash if i wait in a while loop checking xTaskGetHandle() and breaking the while loop once 0 is returned. i am calling a vTaskDelay(100) in the while loop.

xTaskGetHandle() will continue to return the task handle until the task is actually fully deleted.

Since you are calling the normal xTaskCreate(), the old task being around shouldn’t cause a problem, unless other parts are using xTaskGetHandle() to find the task, or you are running out of memory because you aren’t letting the idle task run to do the cleanup.

xTaskGetHandle() is NOT an efficient way to get the task handle, as it needs to search a bunch of lists to find the task, it is much better to save the handle from the create and us it. It is handy in this one case, since you are looking for the handle to go away, ad thus shouldn’t be using the original handle.

I am using xTaskGetHandle() as a test code after i zeroed in the task that is creating the crash.
I am only using this before taskcreate() to as a test code.
The task create and delete will happen only a maximum 10 times.
Task handle is returned 0 initially for couple of calls.
If i keep creating the task even if the handle is not 0, after 3 to 4 task creates the system crashes at vTaskDelete() call.
what i observed is the task handle value is always same and is 0x204ad00 and the crash report R2 register is showing R2 = 0x0204ad04.
PC is at vListInsertEnd()
Most of the time i observed PC is at uxListRemove()

Since the taskhandle is not getting 0 and the same TCB address is getting returned every time, i am suspecting the same memory location is getting assigned every time the task is created and is causing the crash.

Follow the advice of @aggarg try not to create and delete tasks all the time. It is usually much better to simply inform your task that works needs to be done rather.

Hi @rvt , yes i agree. But for understanding i want to know how safe to delete the task and create it?

Assuming that you are using xTaskCreate as you mentioned and NOT xTaskCreateState, the same TCB address would mean that the TCB was freed by IDLE task and then got allocated at the same address. This should not result in a crash.

This should be safe as long as IDLE task gets a chance to run and free up resources.

just query the forum. There are uncountable threads on the quirks of dynamic task deletion, and these are being discussed over and over again. Just browsing the discussions will give you an idea of how many pitfalls there are.

It should be “safe”, unless you are using xTaskCreateStatic or xTaskCreateRestricted, in which case you need to make sure the memories provided are no longer being used.

You do need to be careful about running out of memory, and checking that the task was actually created as it won’t clear the handle that you pass the address of on failure, just return the error code, and creating before it gets deleted means both copies need their memory.

There are a lot of dangers you need to avoid so it normally better to not do it.

Hi @richard-damon , i am bit confused. If xtaskCreate uses the freertos heap and if there is no heap, then task should not be created correct? Is task handle not part of the freertos heap?

The task handle is not managed by the heap. It is created before the call to xTaskCreate (see example on that page).

Hi @kstribrn , @rvt , @RAc , @richard-damon , @aggarg ,
i am seeing something like this:

Task handle address Check handle status
0 Start of the function call before checking task handle Handle is NULL
0 in function call after checking task handle Handle is NULL
204a000 inside task Handle is created to H1
204a000 Start of the function call before checking task handle H1 is not checked
0 in function call after checking task handle H1 is NULL by IDLE
204a000 inside task H2 is created
204a000 Start of the function call before checking task handle H2 is not checked
0 in function call after checking task handle H2 is NULL by IDLE
204a000 inside task H3 is created
204a000 Start of the function call before checking task handle H3 not checked
204a000 in function call after checking task handle H3 not cleared by IDLE
204a360 inside task H4 is created
204a360 Start of the function call before checking task handle H4 not checked
204a000 in function call after checking task handle H3 is not cleared by IDLE
204a0a0 inside task H5 is created
204a0a0 Start of the function call before checking task handle H5 is not checked
204a0a0 in function call after checking task handle H3, H4 are cleared, H5 is not cleared by IDLE
204a560 inside task H6 is created which is simmilar to H4
crash

in row number 11,14, two task handles created are not deleted. Still xTaskGetHandle() gives the old task handle number but in row number 17 xTaskGetHandle() shows its deleted the two task handles. But i have checked the memory dump. the two task handles are still available in memory