1. Introduction
I cannot seem to find information or a detailed explanation about the behavioral differences between the following functions in a FreeRTOS task:
2. Code
Suppose you have the following codes:
IdleHook + task creation
Long value = 0;
void vApplicationIdleHook( void ) {
while(1)
{
// empty
}
}
int main(void)
{
xTaskCreate(TaskIncrement, (const portCHAR *)"up" , 256, NULL, 2, NULL );
xTaskCreate(TaskDecrement, (const portCHAR *)"down" , 256, NULL, 1, NULL );
vTaskStartScheduler();
}
Tasks with vTaskDelay
static void TaskDecrement(void *param)
{
while(1)
{
for(unsigned long i=0; i < 123; i++) {
//semaphore take
value--;
//semaphore give
}
vTaskDelay(100);
}
}
static void TaskIncrement(void *param)
{
while(1)
{
for(unsigned long i=0; i < 123; i++) {
//semaphore take
value++;
//semaphore give
}
vTaskDelay(100);
}
}
Tasks with _delay_ms
static void TaskDecrement(void *param)
{
while(1)
{
for(unsigned long i=0; i < 123; i++) {
//semaphore take
value--;
//semaphore give
}
_delay_ms(100);
}
}
static void TaskIncrement(void *param)
{
while(1)
{
for(unsigned long i=0; i < 123; i++) {
//semaphore take
value++;
//semaphore give
}
_delay_ms(100);
}
}
3. Question
What happens with the flow of the program when the tasks are provided with a vTaskDelay versus _delay_ms?
Note: the two given example tasks have different priorities.
From https://www.freertos.org/Documentation/FreeRTOS_Reference_Manual_V10.0.0.pdf:
Places the task that calls vTaskDelay() into the Blocked state for a fixed number of tick interrupts. Specifying a delay period of zero ticks will not result in the calling task being placed into the Blocked state, but will result in the calling task yielding to any Ready state tasks that share its priority. Calling vTaskDelay(0) is equivalent to calling taskYIELD().
I think you get the idea already, but if you have multiple tasks created, then vTaskDelay()
will put the running task into the "Blocked" state for the specified number of tick interrupts (not milliseconds!) and allow the task with the next highest priority to run until it yields control (or gets preempted, depending on your FreeRTOS configuration).
I don't think _delay_ms()
is part of the FreeRTOS library. Are you sure it's not a platform specific function? My guess is, if the highest priority task calls _delay_ms()
, then it will result in a busy wait. Otherwise, a task with a higher priority may preempt the task that calls _delay_ms()
as it is delaying (that is, _delay_ms()
will not yield control immediately).
Perhaps a better summary of the above: in a multitasking application, _delay_ms()
is not deterministic.