Quality RTOS & Embedded Software

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


Loading

vTaskDelay() not giving consistent times

Posted by Matt Budd on June 6, 2008
I have a problem with vTaskDelay. What I want to do is perform an action on a regular task once every tick, and then every say 100 ticks (1 second in my config) have a periodic task wake up and report on the status of the regular task. Here is my code:

//--------------------------------------------------------------
portTASK_FUNCTION_PROTO(regularTask, ppvParameters);
portTASK_FUNCTION_PROTO(periodicTask, ppvParameters);

static volatile unsigned int m_iCounter = 0;

void CreateTasks(void)
{
xTaskCreate(regularTask, "reg", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);
xTaskCreate(periodicTask, "per", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL);
}

portTASK_FUNCTION(regularTask, ppvParameters)
{
while (1)
{
m_iCounter++;
vTaskDelay(1);
}
}

portTASK_FUNCTION(periodicTask, ppvParameters)
{
while (1)
{
vTaskDelay(1000 / portTICK_RATE_MS);
CSLog("counter = %d, tickcount = %d", m_iCounter, xTaskGetTickCount()); //This just logs to the debug window
}
}
//--------------------------------------------------------------

So the periodic task is a higher priority, but it doesn't seem to fire off every 1 second...it takes about 3 or 4 second to fire off. If I take out the "vTaskDelay(1)" in the regular task, it will fire off at the correct speed, but then m_iCounter gets updated more than once per tick. How do I yield the regular task to the next tick...taskYield() seems have the same issue.
Any ideas?

RE: vTaskDelay() not giving consistent times

Posted by Dave on June 6, 2008
If you just call taskYIELD() then you are not delaying so FreeRTOS will just choose the same task to run again.

If you call vTaskDelay( 1 ) then you are on the limit of the resolution and the period you delay for will depend on where in the current time slice the function is called. This is also very inefficient.

Can you replace regularTask with a tick hook? http://www.freertos.org/a00016.html

RE: vTaskDelay() not giving consistent times

Posted by Matt Budd on June 6, 2008
Thanks for your help. Some further comments:

1. So then I would expect that if I called taskYIELD() that is would be the same as having no statement in there at all (since this is the only task (besides the idle task) that is in the ready state), so like you say it would give execution right back to the "regular" task. However, I don't see that....if I use taskYIELD() it still takes about 4 seconds for my periodic guy to fire and the regular task still fires once per tick.

2. So lets say I simplify the "regular task" like this:
while (1)
{
//Do nothing except sleep
vTaskDelay(1);
}
Why do I still see the problem? Why would a task that executes during every tick at lower priority affect the overall time duration of the tick. The periodic task is still waiting 100 ticks, its just that those ticks are taking 4 times as long to happen. And nothing else is going on in the system besides the idle task and the regular task that does nothing except sleep. Does the overhead of switching to a task every tick really lengthen the tick period that much?

3. I can't use a tick hook, because this problem/code is not really what I am trying to do. It is just a sample that demonstrates the same problem I am having in my much more complicated code. I stripped it down to this ficticious example to make it really simple for people to analyze.

RE: vTaskDelay() not giving consistent times

Posted by Matt Budd on June 6, 2008
A updated code listing for the simplified version:

//--------------------------------------------------------------
portTASK_FUNCTION_PROTO(regularTask, ppvParameters);
portTASK_FUNCTION_PROTO(periodicTask, ppvParameters);

void CreateTasks(void)
{
xTaskCreate(regularTask, "reg", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);
xTaskCreate(periodicTask, "per", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL);
}

portTASK_FUNCTION(regularTask, ppvParameters)
{
while (1)
{
vTaskDelay(1);
}
}

portTASK_FUNCTION(periodicTask, ppvParameters)
{
while (1)
{
vTaskDelay(1000 / portTICK_RATE_MS);

//ERR: I don't get here every second...I get here about every 4 seconds. Why?
CSLog("tickcount = %d", xTaskGetTickCount());
}
}
//--------------------------------------------------------------


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


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

Latest News

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

Meet Richard Barry and learn about running FreeRTOS on RISC-V at FOSDEM 2019

Version 10.1.1 of the FreeRTOS kernel is available for immediate download. MIT licensed.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


Careers

FreeRTOS and other embedded software careers at AWS.



FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Renesas

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

Xilinx Microblaze and Zynq partner