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


Probs w/ xSemaphoreGiveFromISR & on ...

Posted by Richard Gibbs on March 5, 2010
I have an ISR that communicates with a task via a semaphore. If I use xSemaphoreGive in the ISR (against the documentation), everything works fine. However, if I use xSemaphoreGiveFromISR and (conditionally) call vPortYieldFromISR as I should, the scheduler becomes confused after the first interrupt and never finds a task to schedule after the waiting task blocks, even though there's another task that's always ready to run.

The scenario is as follows:

There are two tasks -- a low-priority task that does something to cause an interrupt, and a higher priority task that's waiting on a semaphore. The ISR simply posts to the semaphore. In the case were I use the correct "FromISR" functions from the ISR, the waiting task wakes up, performs it's function (nothing) , and goes back to waiting for the semaphore. The low-priority task never gets scheduled again. However, if I use the INCORRECT function in the ISR, everything works smoothly, and the low-priority task gets scheduled after the waiting task re-waits.

I'm using the GCC/ARM_CM3 port on a ARM Cortex-M3 target. I'm actually pre-silicon and am running on RTL/VCS simulations.

Any help would be greatly appreciated.

RE: Probs w/ xSemaphoreGiveFromISR & on ...

Posted by Richard Gibbs on March 5, 2010
I found the previous post where you using binary semaphores fixed the problem. I tried a binary semaphore with no success. Further, I need counting semaphores in this instance.

RE: Probs w/ xSemaphoreGiveFromISR & on ...

Posted by Dave on March 6, 2010
Which CM3 will you use when it is ready.

Are you sure your simulator is working correctly? Many don't when simulating an RTOS.

RE: Probs w/ xSemaphoreGiveFromISR & on ...

Posted by Dave on March 6, 2010
Also, can you post the code of the two tasks, which sound like they are only a few lines of code. Use the
 tags to keep the formatting.

RE: Probs w/ xSemaphoreGiveFromISR & on ...

Posted by Richard Gibbs on March 8, 2010
Per your question about the simulator, I have never had a problem with the simulator before. The simulator is VCS and it's simulating the M3 processor from the RTL, so it should be cycle-accurate. And I've been simulating other things under freeRTOS and other RTOS's with this simulator with no problems.

Per your question about which CM3 I'll be using, I'm writing code for a new chip incorporating a Cortex-M3.

The task and the ISR are shown below, somewhat simplified.

Thanks for your help with this.


* GPIOHelpersTask is the task that performs most of the functionality for
* all GPIO interrupts. It spends most of its time waiting on a signal
* from the ISR that an interrupt has occurred. When it receives a signal
* (actually a "put" on its semaphore), it processes all GPIO interrupts
* that have occurred since the last signal.
* void GPIOHelpersTask(void)
void GPIOHelpersTask(void)
uint32_t retCode;
uint32_t i;
uint8_t lclIntPending[HW_MAX_GPIO];

/* init the gpio and the ISR-to-this-task counting semaphore*/

/* this is the main task loop; it runs off of a counting semaphore so it doesn't miss any semaphore posts */
while (pdTRUE)
/* wait on semaphore */
retCode = xSemaphoreTake(((posixSemaphore *)gpioHelpersSema)->handle,0xffffffff);

if (retCode < 0)
/***TODO***log an error***/
while (1) {};

/* process "pending" interrupts */

/* first pick up all pending interrupts and save them locally */
/* to avoid multiple interrupt enable/disables */
for (i = 0 ; i < HW_MAX_GPIO ; i++)
lclIntPending = gpioHelper.gpioPendInt;
gpioHelper.gpioPendInt = 0;

/* process each entry in table (comparing to pending mask for that gpio) ***/
/* note: races shouldn't be an issue here, as count is never decrementing */
/* and all other change, we'll either get before or after, but not */
/* inconsistent state. */
for (i = 0 ; i < gpioHelper.gpioHandleCount ; i++)
/* check each entry against the corresponding pending interrupt bits */
if ((lclIntPending[gpioHelper.configTable.gpioNum] &
gpioHelper.configTable.mask) &&
gpioHelper.configTable.IOType > GPIO_INT_TYPES)
/* found one, now process it (call call-back) */
} /* if (lclIntPending[gpioHelper.configTable.gpioNum] & ... */
} /* while (pdTRUE) */
/*** should never get here ***/

* GPIOISR is the interrupt service routine for the GPIO blocks. It fields
* all GPIO interrupts and signals the background function to determine what
* to do with the interrupt.
* void GPIOISR(void)

void GPIOISR(void)
uint32_t retCode;
uint8_t IRQNum;
uint8_t gpioNum;
uint8_t intsPending;
portBASE_TYPE preEmptionRequired = pdFALSE;

/* determine which GPIO is firing */
IRQNum = get_irq_in_process();

/* convert IRQ to gpio # and check validity */
gpioNum = HW_IRQ2GPIO(IRQNum);
if (gpioNum > HW_MAX_GPIO)
/*****BAD ERROR -- should never get here. IGNORE THIS *****/
/***** or, during debug, hang ***/
while (pdTRUE){};

/* pick up its pending interrupts and "or" it into the saved */
/* pending interrupts then clear the interrupts in GPIO. */
/* NOTE: "pend" in NVIC is automatically cleared when an */
/* the isr is entered, so it doesn't need to be cleared, and */
/* in fact, shouldn't be cleared, as it means another intrupt*/
/* has arrived after the current one was active. Also, the */
/* "active" bit is read-only and automagically set & cleared */
/* by the NVIC. */
intsPending = GPIO_MIS_R(gpioNum);
gpioHelper.gpioPendInt[gpioNum] |= intsPending;

/* now notify the gpio helper task that it's got work to do */
given = xSemaphoreGiveFromISR(sem->handle,&preEmptionRequired);
/****handle pre-emption****/
if (preEmptionRequired != pdFALSE)


RE: Probs w/ xSemaphoreGiveFromISR & on ...

Posted by Richard Gibbs on March 10, 2010
Is anyone successfully using xSemaphoreGiveFromISR/vPortYieldFromISR on a counting semaphore on a CORTEX_M3?

RE: Probs w/ xSemaphoreGiveFromISR & on ...

Posted by Richard Gibbs on March 16, 2010
Problem solved. This was my problem and NOT a freeRTOS problem.

I had configSYSCALL_INTERRUPT_PRIORITY set at lower priority (higher priority # on ARM CORTEX M3) than my GPIO interrupt was running at. When I fixed this, the problem went away.


[ 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