My program needs to go into a low power state.
In that state I don’t want any of the tasks to run.
I suspend all the tasks using
However, I have a specific task that need to re-run again when the program exits from low power state.
Is it okay to delete that task and creating it again?
That task blocks on a queue waiting for data. The blocking time is from hundrends of ticks up to a few thousands of ticks. Usually (100 - 10000)
1 tick = 1ms in my case.
The create/delete frequency is non-deterministic. I don’t know when the device will enter low power state and when it will exit.
I use heap_4.
FreeRTOS ver 10.5.1
Currently, only this task is deleted and created again.
Any other FreeRTOS primitive is remaining after creation. I do not delete/re-create any other object like queues, semaphores etc…
How dangerous is this?
Your description of the control flow does not make sense to me. When your task’s main purpose is to wait for queue data to arrive, then by definition there can not be data arriving when the MCU is in low power state, so as long as the wait has no timeout, there should not be any harm in the task remaining suspended. In other words, some event needs to get your MCU out of low power, then probably queues some data, in which case your worker task can simply resume with the data arriving? Why would you want to delete the task then? What is wrong with your task remaining suspended?
Could you sketch out the rough overall control flow in pseudo code so we get an idea what is supposed to happen when? Ie who puts the MCU into low power mode based on what condition and what gets it back out of it?
The task manages an external module that communicates with a serial port.
In the low power state the module needs to be off. I use a high power switch to disable its power supply.
In normal state, the module is powered on by turning the power switch on. After the module boots up it needs to be initialized. The tasks does that at the beginning.
After initialization the tasks just reads data. It reads the queue waiting for data to arrive.
Deleting a task and re-creating it will not “unsuspend” the task from a vStaskSuspendAll, which doesn’t actually “suspend” the existing tasks, but turns off the scheduler.
The key to doing what you want isn’t suspending the tasks, but to just make them naturally block until they have something they should be doing. Then they naturally won’t run.
Normally, YOU control when you device enters the “low power” state, perhaps from a command from the outside, at which point you tell all the tasks to prepare for low power, and when it all happens, you go into low power mode.
Yes, that is correct I don’t expect it to be suspended
I mentioned I want to delete it and then restart it after a while.
However my initial question is whether it harms to delete and re-create a task periodically in a non-deterministic manner
Well, it doesn’t really harm. You can delete and re-create tasks. Be aware that delete and create free and allocate task stack and control memory from heap (I guess) and it’s asynchronous means kills a task whatever it is currently doing. Also the task memory cleanup is done ‘lazy’ or deferred by the idle task as documented. So you better should have enough heap to ensure that re-create will be successful every time.
In addition you have to manage all additional/task code related resource cleanup yourself somehow. All in all it’s probably not a very robust design.
Alternatively you could use a global flag maybe in conjunction with
xTaskAbortDelay to tell the module handler task to exit its normal processing loop and start over with the init preamble or call the init function and proceed with its normal operation.
This is actually a fairly serious issue. Using vTaskSuspendAll() implies that you do not have any control over what state a task is in. Assume that the “worker task” is suspended on a queue when the scheduler is stopped (which is very likely the case given the TOs description of the control flow) and the TCB that is being used by FreeRTOS to associate tasks with sync objects disappears - wouldn’t that blow up all the bookkeeping?
I agree with Hartmut that this design overall looks very error prone. Using vTaskSuspendAll() is dangerous in all scenarios (we discussed this many times here), but in conjunction with moving targets, my guts tell me that it will take a lot of brain cells and time to get that to work reliably.
I will repeat the comment I make most times when someone talks about deleting and recreating a task.
The danger of deleting a task (other than a task deleting itself when done) is that you likely don’t actually know what the task is doing and how to clean up its resources. And those will be left in whatever state they were in when the task was deleted.
It isn’t like a “Process” on a big-system machine, where the OS keeps track of what resources a process has taken, and takes them back when it is deleted.
It almost always is better, if it is needed at all, to set a flag that the process reads, and “restarts itself” in a controlled manner. Sometimes you need to send a signal of some sort to the task, or an “abort delay” to wake it from what it is doing.