Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training


Strange behaviour after portEND_SWITCHING_ISR

Posted by Amon-Ra on March 12, 2012
Hello. I am using GCC STM32F103VE.
I came across some odd behaviour of my firmware after calling portEND_SWITCHING_ISR - there are two tasks, one for processing data, low priority, and another for delayed interrupt handling, high priority.
So, high priority task is waiting for counting semaphore, xSemaphoreTake(IRQSemph, portMAX_DELAY);

ISR text is provided below:

void EXTI15_10_IRQHandler() //IRQ
portBASE_TYPE xHigherPriorityTaskWoken;
xSemaphoreGiveFromISR(IRQSemph, &xHigherPriorityTaskWoken);

When entering ISR first time both tasks are blocked, awaiting different events. So, It works great, context is switched to High Priority task, which is unblocked by IRQSemph counting semaphore. But while processing this task, I suppose, this interrupt is being called once more.

Here is my question: due to mistype, I always passed TRUE to portEND_SWITCHING_ISR, causing context switch even when I shouldn't.

But this caused odd effect - high priority task never unblocked.
This seems wrong to me - even after unexpected context switch - there are no more candidates for running, low priority task is blocked all the time, then why sheduler does not return to High Priority task, why is High Priority task still awaiting semaphore, when semaphore is already being given?
I checked return value of xSemaphoreGiveFromISR, it retrurns success.
When I fixed code and started passing *real* xHigherPriorityTaskWoken value instead of 1, it began to work.

RE: Strange behaviour after portEND_SWITCHING_ISR

Posted by Richard on March 12, 2012
In your code, you have forgotten to initialise the xHigherPriorityTaskWoken. It needs to be initialised to pdFALSE on interrupt entry.

The behaviour you observed is the expected behaviour. If giving the semaphore has the potential to unblock a semaphore then the xHigherPriorityTaskWoken is checked, and if it is found to be false, the task is unblocked and xHigherPriorityTaskWoken is set to pdTRUE. If xHigherPriorityTaskWoken was already pdTRUE, then it is assumed that a task has already been unblocked, and no action is taken.

This prevents multiple tasks being unblocked by a single semaphore give, as only one task will process the semaphore, leaving the other unblocked tasks with nothing to do but return to the Blocked state.


RE: Strange behaviour after portEND_SWITCHING_ISR

Posted by Amon-Ra on March 12, 2012
Thanks alot, now it is clear!

RE: Strange behaviour after portEND_SWITCHING_ISR

Posted by Richard Damon on March 12, 2012
One question, if an interrupt does two operations that unblock tasks (say different queues), and happens to unblock the lower priority (but still above the current running priority) first, then when does the higher one wake?

Or, do you need a separate flag for each queue and test if any of them got set?

RE: Strange behaviour after portEND_SWITCHING_ISR

Posted by Richard on March 12, 2012
If you want a task to unblock more than one task from one queue then reset xHigherPriorityTaskWoken to pdFALSE in between each semaphore give. In any case - the task that is unblocked first will always be the highest priority task that was blocked on the semaphore as tasks are unblocked in priority order.

If you have a single interrupt operating on multiple queues and/or semaphores, and you wish one task to be unblocked from each queue/semaphore that is processes, then use a separate flag for each, and OR the flag values when they are passed into portEND_SWITCHING_ISR()/portYIELD_FROM_ISR().


RE: Strange behaviour after portEND_SWITCHING_ISR

Posted by Paul Coleman on March 13, 2012
So is the following not correct?

portBASE_TYPE higherPriorityTaskWoken = pdFALSE;

if(some event)
xSemaphoreGiveFromISR(semA, &higherPriorityTaskWoken);

if(some other event)
xSemaphoreGiveFromISR(semB, &higherPriorityTaskWoken);


Should both semaphore gives use different flags?

Thanks, Paul.

RE: Strange behaviour after portEND_SWITCHING_ISR

Posted by Richard on March 13, 2012
Hang on! Looking at the code I think my reply above is not correct. The higher priority task woken flag being pdTRUE should not effect whether any further tasks are unblocked or not. If more than one task is unblocked then any unblocked tasks that find the reason they were unblocked no longer exists (the semaphore or queue has been processed by a different task) will simply put themselves back to sleep again for the remains of the block task.

Sorry for any confusion caused!


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

Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.

Free TCP/IP and file system demos for the RTOS

Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑

FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists