I am implementing a state machine in FreeRTOS and I am struggling with the state changes because of vTaskDelayUntil().
Short description of the state machine:
I have multiple tasks which do the work, the priorities are assigned with the help of RMA (rate monotonic algorithm) and are therefore dependent on the period of which the work tasks have. There is one MasterTask which just handles the state change. It gets notified from an ISR and then changes the state according to the notification. The MasterTask suspends and resumes un-needed or needed tasks according to the state, but more importantly it changes the periods of the working tasks, which use the vTaskDelayUntil function to get an absolute period. (The priorities stay the same and such the period relative to the tasks. They just need to run more frequently)
The Problem: If I initiate a state change and change the periods of the task (I suspend the scheduler before doing so) because of vTaskDelayUntil(), the tasks stay in the blocked state for to long the first cycle until the new period has been adopted.
My question: Is there a possibility to reset the LasteWakeUp of the vTaskDelayUntil or just another method without losing the ability to block the states with an absolute period.
Thank you very much for your help.
To my knowledge, there is no task to let one task change the wakeup time of another task. The closest is vTaskAbortDelay which will end the delay right now. If you combined that with a flag to tell the task to reset the ‘current’ delay to time on this, you could come close.
This reset would be done by setting the xLastwakeTime variable to the current tick counter, just like you are supposed to at the beginning of the task.
Thank you for your fast reply.
This actually seems to work quite well. I have to do some further testing, but if I put my xLastwakeTime to the tickcount in the for-loop and then let the MasterTask abort the delay, the period changes without waiting for the last period to expire. Important is that the xLastWakeTime is set to the tick counter in the for loop, such that it gets reset as soon as the task is running.
You only want to reset xLastWakeTime initially, and on the aborted wakeup, not every time (or you might was well just use vTaskDelay), so prior to aborting the delay, the task doing so needs to set some sort of flag, that the periodic task checks right after the delay.
Thanks for pointing this out! I’ll have to take a deeper look at this. Would you recommend a direct task to task notification for that?
I would likely just use a ‘global’ variable. (It might be able to be just a file static or a member of a structure with info for/about the class).