Quality RTOS & Embedded Software

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


Loading

taskYIELD from highest priority task.

Posted by Nobody/Anonymous on February 1, 2007
In my highest priority task I wait for an interrupt to occur in the following way:

static uint8_t volatile timerOVF;

//a lot of other code here

void WaitForSecond()
{
//Service the watchdog before and after the loop
asm("WDR");

while( timerOVF == 0 )
vTaskDelay(1);

asm("WDR");

//Reset flag
timerOVF = 0;
}

__interrupt void Timer0_Overflow( void )
{
timerOVF = 1;
}


As can been seen I use vTaskDelay(1) to force a context switch. For some strange reason calling taskYIELD() does not change the context (actually it does, but the new context is the same as the current context). As a result all other tasks are starved from processing time.
The task calling WaitForSecond() has the highest priority, so I can understand why the yield might pick it as the next task (this might be considered a bug). What I do not understand is why vTaskDelay is able to create an actual context switch.

Can anyone help me out on this one?

Regards,

Sytse.

RE: taskYIELD from highest priority task.

Posted by Nobody/Anonymous on February 1, 2007
This is exactly the expected behavior. taskYIELD() will cause the scheduler to select the highest priority task that is in the Ready state to run. Calling taskYIELD() places the calling task in the ready state, if it is the highest priority task in the ready state it will immediately get selected as the task to run again and lower priority tasks will never run.

Calling vTaskDelay(1) places the calling task in the Blocked state for 1 tick. The scheduler cannot therefore select the calling task again until 1 tick later, allowing lower priority tasks to run.

However this is very inefficient code, and there is probably a much better way of achieving what you want to do. What exactly does the code do? It looks like you reset the watchdog simply because a timer overflows, is this all it does?

Dave.

RE: taskYIELD from highest priority task.

Posted by Nobody/Anonymous on February 1, 2007
The task containing this code is my scheduling routine for various computations/outputs. Every second the timer overflows thereby exiting the while loop. I opted for this implementation instead of a binary semaphore because of the memory overhead of the semaphore. The watchdog OVF is set to about 1.9 secs. So I need to service it at least once in this routine.

The behavior of taskYIELD is explainable, but a task telling it wants to yield should be yielded, not reloaded. I think I'll make an extra yield routine, forcing a context switch to the next TCB.

Regards,

Sytse.

RE: taskYIELD from highest priority task.

Posted by Nobody/Anonymous on February 1, 2007
> The task containing this code is my scheduling routine for various
> computations/outputs. Every second the timer overflows thereby exiting the while
> loop. I opted for this implementation instead of a binary semaphore because
> of the memory overhead of the semaphore. The watchdog OVF is set to about 1.9
> secs. So I need to service it at least once in this routine.

In your implementation every 1 tick the task will be woken then block again, taking up processing time. I don't know how fast you tick is running, but the faster the tick the more processor time will be used.

If you are requiring periodic execution, rather than an exact synchronisation with your interrupt, you could use vTaskDelayUntil() instead. This can be used to place the task into a blocked state until the exact time at which you wish to run again. The task will stay in the blocked state so not use any processing time.


> The behavior of taskYIELD is explainable, but a task telling it wants to yield
> should be yielded, not reloaded.

On the contrary - the task should be reloaded if it is the highest priority task in the system that is in the Ready state. If there is more than one task of the same priority in the running state then the yield will cause a different task be selected. If there is only one task of that priority then the same task will be selected. This is the wanted behaviour.

>I think I'll make an extra yield routine, forcing
> a context switch to the next TCB.

So you will select a lower priority task when a higher priority task is able to run? At what point will you select the higher priority task again?

Regards.

RE: taskYIELD from highest priority task.

Posted by Richard on February 1, 2007
That last post we me by the way if it was not obvious - seemed to get logged out between posts.

Regards.

RE: taskYIELD from highest priority task.

Posted by HAR on February 1, 2007
I think you're missing a definition here. A task saying it wants to yield is giving way ONLY IF THERE IS ANYONE ELSE TO YIELD TO. It's just like coming to a "yield" sign on the road when there's no traffic - you can come to a dead stop and look really carefully, and then the first car away from the intersection will still be *you*.

If you expect a different task to run when this task yields, then (without knowing anything about your code) I'd look at the following:

- Check that priority level assignments are right for the situation. I would make the watchdog timer post very low priority, practically an idle task / screen saver, which means that there are enough cycles to do the job and still take a breath now and then. In that case it doesn't even have to explicitly yield, because it will be pre-empted. The loop is:

pre-loop: save the first time

Get curent time
Compare to saved time
If close enough, watchdog is OK
move current time to saved time
lather, rinse, repeat

- Should the "yielding" task actually be waiting for something specific, or sleeping (not just yielding) until woken up by an interrupt? Well, no, if it's just doing the watchdog, so next point:

- How long is your watchdog timer supposed to be? Try making that delay loop half of the watchdog time (since a delay may actually be longer than requested). As shown you're virtually in a CPU spin loop polling on that timer, so it's no wonder your other processes are starving.

-DutchUncle


[ 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