Reputation: 22252
I think I either have a) a misunderstanding of the way FreeRTOS taskGetTickCount() function works or b) something not quite right with our port.
I have some debugging where I'm showing the output of xTaskGetCount(). Any time I've done a vTaskDelayUntil(), it seems it's updated and is current. But if I do a spin-wait, waiting for it to increment, it never will. I thought the interrupt fired ever tick and incremented that value. But I'm only running one task at the moment, so perhaps it is smart enough to never check for a reschedule and the tickCount never gets updated? Anyone who can set me straight on how the FreeRTOS tick count works, I'd be much obliged.
EDIT: A sample fragment:
void someTask(void * _)
{
portTickType now = xTaskGetTickCount();
for( ; xTaskGetTickCount() - now < 25; )
{
debug("%u", xTaskGetTickCount();
}
}
This will spin forever, long past the 25 ms implied when tick = 1 ms. The output will just continually list the same value over and over and over. IF I add a vTaskDelay() to the bottom of the loop though, it will increment healthily, and drop out eventually.
Upvotes: 5
Views: 3657
Reputation: 11
vTaskDelay( 25 );
Well, what did you suggest?! This is not a solution! VTaskDelay () is a function that translates a task into a locked state for a period of time that is counted from the time of the call to vTaskDelay ().
VTaskDelayUntil () - this function provides a cyclical execution with a specified period.
The loop never blocks so it will starve all the priority tasks of any execution time, and will time slice with tasks of the same priority.
Function vTaskDelayUntil () specifically to avoid this! For example, I can not put this crutch with the vTaskDelay () function, because of a critical area of code, and the xTaskGetTickCount () function always returns 0. And I can not solve this problem ((
A few hours of torture later:
void StartTask01(void const * argument)
{
portTickType xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
const portTickType xPeriod = pdMS_TO_TICKS(100);
while(1)
{
canInterviewMC_100(); // Interview CAN Message
vTaskDelayUntil(&xLastWakeTime, xPeriod);
}
}
As a result, this code is executed every 100ms. At the same time, it has the highest priority, but this task will not take CPU time for low priority tasks, because it is executed only once in 100ms.
Upvotes: 1
Reputation: 126
You don't say which port you are using. Fundamentally there is nothing wrong with your code, although it is unusual to do that kind of thing. The loop never blocks so it will starve all lower priority tasks of any execution time, and will time slice with tasks of the same priority.
Here are some notes:
A better solution would be to this problem would be:
while( whatever )
{
vTaskDelay( 25 );
DoSomething();
}
debug()
is not a FreeRTOS statement and I have no idea how it is implemented. If you are using some kind of semi hosting then it might be that calling debug() is stalling the execution of you processor (you don't say which) for extended periods of time.
Upvotes: 4