Quality RTOS & Embedded Software

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


Question about taskYIELD()

Posted by Dan on August 3, 2007

In xQueueSend() (and xTaskResumeAll() and some others) there is a call to
taskYIELD() inside a taskENTER_CRITICAL()/taskEXIT_CRITICAL() section. In
our implementation interrupts are disabled inside the critical section, so
our tick interrupt won't run. We're running preemptive as well. Is there
any possible problems with getting tasks to switch, or losing ticks?

Dan Searles

RE: Question about taskYIELD()

Posted by Richard on August 3, 2007
It is the intended behaviour that the context switch occurs within the critical section - this allows the use of the scheduler locking mechanism. Each task should maintain its own interrupt status. Therefore a task that has interrupts disabled can call taskYIELD(), and switch to a task that may have interrupts enabled. When the original task next runs it starts with the interrupts in the state in which it expects to find them - disabled. Therefore this mechanism does not mean that interrupts remain disabled until the task executes again.


RE: Question about taskYIELD()

Posted by Igor Polevoy on March 12, 2008
Hi there,
I'm trying to port FreeRTOS now to CEVA DSP and I have a question which seems to me to be a compliment to the above discussion:
In my understanding taskYield() should always be called from the critical section since it actually performs context switch.
However in the code of the task.c there are places where taskYield() is called outside the portENTER_CRITICAL/portEXIT_CRITICAL macros. E.g. in the vTaskSuspend method, xTaskresumeAll and some other places.
Was this done intentionally ? If yes, what is the reason?

Thank you,

RE: Question about taskYIELD()

Posted by Richard on March 12, 2008
taskYIELD() absolutely MUST be implemented so that it can be called either from within a critical section OR from outside of a critical section.

If called from within a critical section then when the task that made the taskYIELD() call next runs it must re-start also from within the same critical section (with interrupts disabled).

If called from outside a critical section, then when the task that made the taskYIELD() call next runs it must re-start also from outside a critical section (with interrupt enabled).


Question about taskYIELD()

Posted by nestwave on November 24, 2015

Since taskYIELD can be called from outside critical section, and since taskYIELD typically calls vTaskSwitchContext, then vTaskSwitchContext may end up being called from outside critical section.

This appears to be the case in the GCC ATMega323 port, for example (cf. below).

Could you explain if it's OK for vTaskSwitchContext to occur outside critical section?


~~~~ void vPortYield( void ) attribute ( ( naked ) ); void vPortYield( void ) { portSAVECONTEXT(); vTaskSwitchContext(); portRESTORECONTEXT();

asm volatile ( "ret" );

} ~~~~

Question about taskYIELD()

Posted by davedoors on November 24, 2015

This is a VERY old thread and VERY specific to the FreeRTOS port. In the AVR portSAVE_CONTEXT() disables interrupts so vTaskSwitchContext() is protected.

Question about taskYIELD()

Posted by nestwave on November 24, 2015

OK, I see that interrupts are disabled at the beginning of portSAVE_CONTEXT (cli instruction, I guess).

So in general ports, interrupts should be (re)disabled around start of vPortYield, and not assume that they are already disabled?

Question about taskYIELD()

Posted by rtel on November 24, 2015

Each port has a different mechanism for yielding to a different task, and each case has to be considered on its own.

More often than not, yielding is done using a standard or software interrupt, in which cases the hardware will either itself disable interrupts on interrupt entry, or otherwise the interrupt priority mechanism and/or asm code is used to manage interrupt nesting to ensure the context switch can occur cleanly.

Also, some ports can/must yield in a critical section and the RTOS must save/restore the critical section nesting as part of the task context, while other ports (Cortex-M and RX for example) can't possibly yield from a critical section.

You are looking at a very basic port (as its a basic microcontroller), in which yielding is performed using a function call, and in that case interrupts are disabled manually. This is not really a critical section - the RTOS manages the yield, so is responsible for ensuring interrupts are left in the correct state when a task starts to run.

[ 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.

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.


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


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