Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

vTaskDelayUntil(), vTaskSuspend(), vTaskResume()

Posted by clendinning on June 6, 2016

I've not been able to get vTaskDelayUntil() and vTaskSuspend() to work well together. It seems that if I call a vTaskSuspend() during the period that vTaskDelayUntil() has the task blocked, that the task is taken to the Ready Pending state, rather than suspended. At least that is what a trace of vTaskResume() appeared to indicate, when it failed to find that the task was in a suspended state.

I tried setting the wake time and then calling a vTaskResume() as was described in other posts with no success. Has anyone else noticed this behavior? I'm trying to suspend a periodic task, to be resumed at a later time. In order to do so, I tried to use a vTaskSuspend(NULL) just after the task awakened from a vTaskDelayUntil(). Of course the task was then put on the block list. The task seemed to have suspended, or at least didn't execute again, but could not be resumed as described above.


vTaskDelayUntil(), vTaskSuspend(), vTaskResume()

Posted by rtel on June 7, 2016

What you are reporting is the expected behaviour. See the state diagram on the following page: http://www.freertos.org/RTOS-task-states.html


vTaskDelayUntil(), vTaskSuspend(), vTaskResume()

Posted by clendinning on June 7, 2016

I would have thought, after calling a vTaskSuspend(), even during the block period of a vTaskDelayUntil(), that the task state would gone to a suspended state, either overriding the block, or moving from ready to suspended, as per the diagram. However, it appeared to be in a ready state when the vTaskResume() was called, causing the resume to be ignored. One would have expected the task to run, due to the ready state, but it did not. I don't see that as the expected behavior.


vTaskDelayUntil(), vTaskSuspend(), vTaskResume()

Posted by rtel on June 7, 2016

In which case I don't think I understand your post/question.

Maybe it is related to the use of vTaskDelayUntil() - the first parameter to which stores the last wake time. If you suspend a task that called vTaskDelayUntil() for a time that is greater than the next time the task would otherwise have executed then the variable that holds the last wake time will be out of date. In that case I would expect the periodic task to execute immediately a number of times after it is resumed, until the last wake time has caught up with the actual time.

....but I don't think that is what you are describing.


vTaskDelayUntil(), vTaskSuspend(), vTaskResume()

Posted by clendinning on June 7, 2016

I have a task that is to wake periodically and start another task. I would like to suspend and resume the periodic task at will. When the periodic task is created with vTaskCreate(), it is immediately suspended, before the call to vTaskStartScheduler(). Later, calling a vTaskResume(), it begins to run. After a specified number of loops at the specified period, the task suspends itself with a vTaskSuspend() called directly after waking and calling vTaskDelayUntil() for the next period.

I would think that the periodic task would move from the blocked caused by the vTaskDelayUntil(), to the suspended state at that point. However, the next time a vTaskResume() is called, the task fails to start again.


vTaskDelayUntil(), vTaskSuspend(), vTaskResume()

Posted by rtel on June 7, 2016

When the periodic task is created with vTaskCreate(), it is immediately suspended, before the call to vTaskStartScheduler().

So when the scheduler starts the task is in the Suspended state.

Later, calling a vTaskResume(), it begins to run.

After vTaskResume() has been called the task moves out of the Suspended state into the Ready state - and depending on its priority relative to other tasks in the Ready state - may also move into the Running state.

If the task is now periodically calling vTaskDelayUntil() it will move from the Running state into the Blocked state each time it calls vTaskDelayUntil(), then out of the Blocked state into the Ready state (it must have been in the Running state to call vTaskDelayUntil(), and to be in the Running state it must have come from the Ready state as only Ready tasks can be selected to run) each time the block time expires. Again, depending on the task's priority relative to other Ready state tasks, the task will enter the Running state.

After a specified number of loops at the specified period, the task suspends itself with a vTaskSuspend()

At which point it will move from the Running state into the Suspended state.

called directly after waking and calling vTaskDelayUntil() for the next period.

So it calls vTaskSuspend() after it unblocks from a vTaskDelayUntil() call? The sequence is not clear here but I don't think it is relevant.

If this is the sequence then I have annotated with the states:

vTaskDelayUntil(); [Running state -> Blocked state] [Back to Ready/Running state on timeout] vTaskSuspend(); [Running state -> Suspended state]

I would think that the periodic task would move from the blocked caused by the vTaskDelayUntil(), to the suspended state at that point.

After the task unblocks it will move to the Ready/Running state depending on priority, and only enter the Suspended state when it suspends itself (or another task suspends it).


vTaskDelayUntil(), vTaskSuspend(), vTaskResume()

Posted by clendinning on June 7, 2016

vTaskDelayUntil(); [Running state -> Blocked state] Back to Ready/Running state on timeout . . vTaskDelayUntil(); [Running state -> Blocked state] Back to Ready/Running state on timeout . . n repeats . . vTaskDelayUntil(); [Running state -> Blocked state] vTaskSuspend(); [Blocked state -> Suspended state] . . random amount of time . . vTaskResume() . . The task does not start.

Another interesting artifact using vTaskDelayUntil() is that, the periodic task called vTaskResume() for another task, which had a taskENTERCRITICAL(), task EXITCRITICAL() pair. I thought the critical section was to prevent context switching, however it disabled interrupts, causing vTaskDelayUntil() to be robbed of system timer ticks so that the delay was too long by the amount of time between the ENTERCRITCAL and EXITCRITICAL.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS