ISR handler task starving other lower priority task

Hi, I’m using FreeRTOS on Xilinx Zynq Soc, c++ compiler. I have 2 tasks. Task 1 is the handler task to service ISRs. It is created with a priority of say, 4. Task 2 is another task doing other work totally unrelated to ISRs/Task1 and created with priority 3. Task1 // priority 4 { while (1) { SemaphoreTake(xbinary); do something(); } } ISR() { SemaphoreGive(xbinary); Context Switch(); //to make Task1() run } Task2() // priority 3 { while(1) { do something else() } } In the above scheme, Task2() is not running even though the higher priority Task1() is blocked on a semaphore. Any ideas?? If I create Task2() with the same priority as the handler Task1(), then both of them run; but I would like to keep Task2() at lower priority than the handler Task.

ISR handler task starving other lower priority task

Hi Sean, ~~~~~ static xSemaphoreHandle xISREventSemaphore; void ISRhandler( void ) { BaseTypet xHigherPriorityTaskWoken = pdFALSE;
/* Beside setting the semaphore, also make sure that the
same ISR won't re-occur immediately after returning (IRET).
In some cases this is automatic: the CPU or peripheral
denotes the interrupt as "handled" just before calling the
ISR.
In other cases, you must write a '1' to some flag which
triggered this interrupt (timer-interrupt), or read a byte
(UART RX interrupt), see the manual. */
if( xISREventSemaphore != NULL )
{
    //to make Task1() run
    xSemaphoreGiveFromISR( xISREventSemaphore,
        &xHigherPriorityTaskWoken );
    portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
} void Task1( void *pvParameters ) // priority 4 { BaseType_t xTicksSecond = 1000 / portTICK_PERIOD_MS;
vSemaphoreCreateBinary( xISREventSemaphore );
install_ISR();

while (1)
{
    if( SemaphoreTake( xISREventSemaphore, xTicksSecond ) != pdFALSE )
    {
        /* An ISR has occurred. */
        do_something();
    }
    else
    {
        /* A time-out occurred while waiting for an ISR event. */
    }
}
} void Task2( void *pvParameters ) // priority 3 { BaseType_t xSleepTicks = 10 / portTICK_PERIOD_MS; xSemaphoreHandle xTask2Semaphore;
vSemaphoreCreateBinary( xTask2Semaphore );
while(1)
{
    /* Let it sleep for 10 ms. */
    SemaphoreTake( xTask2Semaphore, xSleepTicks );
    /* and do something else. */
    do_something_else();
}
} ~~~~~ If you look carefully at the above example, you might find the answer to your question. Regards.

ISR handler task starving other lower priority task

Hein, Thanks for responding and the nicely formatted code example. I don’t think I understand what you are trying to tell me. Please note that even though Task2() is of lower priority, the other higher priority Task1() is blocked on a Semaphore, so, shouldn’t that relinquish some CPU to the lower priority Task2()? Thanks in advance.

ISR handler task starving other lower priority task

Sean,
I don’t think I understand what you are trying to tell me
The fact that your lower-priority task-2 doesn’t get attention, probably means that either the ISR or task-1 is consuming all CPU time. Maybe task-1 takes all CPU time because it does not sleep (when xBlockTime == 0) Maybe your ISR takes all CPU time because the cause of the interrupt is not properly reset / cleared. Could you compare the code that I provided with your own implementation, line-by-line? And if you can NOT find the cause, you might want to submit some real C-code that you are using. Regards, Hein

ISR handler task starving other lower priority task

Thanks. The tick interrupt is 1000Hz, the external interrupt is fired every 1ms. Since the scheduler can only run at 1 ms, I suppose the context switch from Task1 to Task2 cannot happen sooner than that. So, I increased the tick interrupt to 2000 Hz, but it still did not help. I’m looking into this statement “Maybe your ISR takes all CPU time because the cause of the interrupt is not properly reset / cleared.” I’ll report back.

ISR handler task starving other lower priority task

Who says the scheduler can only run at 1 ms? The scheduler will be run whenever it is called! The timer tick will force a scheduler run (if premeption is allowed) to let multiple tasks at the same priority automatically share time. The scheduler will also run whenever a task blocks. An ISR can also request the scheduler to run (details on how are port specific) when it has unblocked a higher priority task, thus switching to it immediately.

ISR handler task starving other lower priority task

Thanks Hein and Richard. This problem is now resolved. The issue was same what Hein suspected. The Interrupt was not getting cleared properly. We were configuring the interrupt for ACTIVE LOW where as it was required to be configured ACTIVE HIGH or rising edge. Once we resolved this, we are able to get multiple tasks with different priorities working without problems. Thanks for your support.