Quality RTOS & Embedded Software

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


Loading

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.

Richard


/**
* 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*/
gpioHelpers_sysInit();


/* 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 */
taskENTER_CRITICAL();
for (i = 0 ; i < HW_MAX_GPIO ; i++)
{
lclIntPending = gpioHelper.gpioPendInt;
gpioHelper.gpioPendInt = 0;
}
taskEXIT_CRITICAL();

/* 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) */
((gpio_callback_t)gpioHelper.configTable.notifier)
(
GPIO_DATA_R(gpioHelper.configTable.gpioNum,
gpioHelper.configTable.basePin,
BIT_MASK(gpioHelper.configTable.numPins))
);
}
} /* 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){};
return;
}

/* 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;
GPIO_INTCLR_W(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)
{
vPortYieldFromISR();
}

}



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.

Richard


[ 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