Task does not take semaphore given by ISR

psjapex wrote on Monday, February 06, 2017:

Hi, I’ve been banging my head against the wall on this problem for a while now and need some advice or clarity on what should be a simple problem.

I have a ‘main task’ that takes a static binary semaphore. The semaphore is supposed to be given or released by a PIT timer ISR. In debug, I can see that the ISR is correctly giving the semaphore, and I can also see that contex is being given directly back to the main task. However once back in the main task, the task never takes the semaphore and seemingly continues to sleep on it even though it was given by the ISR.

**Edit:
I noticed that after the ISR gives the semaphore, the uxMessageWaiting variable (inside the semaphore/queue struct) is 1 (as it should be since there is an item given in the queue). But after returning to the main task, the variable is changed to 0. So when the main task tries to take the semaphore, it looks and see’s uxMessageWaiting is still 0. I’m thinking there may be a stack or memory issue at hand here. Any advice is welcome.

The following is my code; the task is initialized in main.c.

#define SLEEP 0xFFFF

/*Semaphore handles*/
static SemaphoreHandle_t _sem_mainTask;
#if ( 0 != configSUPPORT_STATIC_ALLOCATION )
static StaticSemaphore_t _sem_mainTask_buffer;
#endif

TaskHandle_t mainTaskHandle = NULL;

static void Task_Main( void *pvParameters )
{
    (void) pvParameters; /* not used */

    int test = 5;

    for(;;)
    {

        long sleep = SLEEP;
        BaseType_t _semGiven = pdFALSE;

        _semGiven = xSemaphoreTake(_sem_mainTask, ( TickType_t )SLEEP);

        if( _semGiven == pdTRUE)
        {

            test++;
            //vTaskSuspend(NULL);

        }
    }
}

void Task_Main_Initialize( TaskHandle_t *task_handle )
//void Task_Main_Initialize( void )
{
    /* Create RTOS task */
    xTaskCreate( Task_Main, /* task function */
          "main", /* name of task */
            256, /* stack space */
            NULL, /* no private parameters to pass into the task */
            10,     /* priority */
            task_handle
             );


       //create the binary semaphore
    #if ( 1 != configSUPPORT_STATIC_ALLOCATION )
        _sem_mainTask = xSemaphoreCreateBinaryStatic( &_sem_mainTask_buffer );
    #else /* configSUPPORT_DYNAMIC_ALLOCATION */
        _sem_mainTask = xSemaphoreCreateBinary();
    #endif

    //give the binary semaphore to kick it off
    xSemaphoreGive( _sem_mainTask );
}

//dedicated to yielding to the main task
void PIT1_IRQHandler(void)
{

    //CLEARN THE INTERRUPT FLAG!!!!
    PIT_StopTimer(PIT, 1);
    PIT_ClearStatusFlags(PIT, 1, kPIT_TimerFlag);
    PIT_StartTimer(PIT,1);
    
    BaseType_t reschedule;
    
    xSemaphoreGiveFromISR(_sem_mainTask, &reschedule);
    if(reschedule){
    //go to sleeping task
    portYIELD_FROM_ISR(reschedule);
    }
  
}

rtel wrote on Monday, February 06, 2017:

Is this a PIC24? Guessing from the way the ISR is written.

Not related to your problem, but reschedule (the variable) should be
initialised to pdFALSE (0) before it is used in xSemaphoreGiveFromISR.

Is there a portYIELD_FROM_ISR() function for the PIC24? Other than
that, I can’t see anything standing out as being wrong. Can you step
into the portYIELD_FROM_ISR() function to see what happens? If this is
a PIC24 it should take you into the function the task being unblocked is
blocked in - from there you might be able to see why its not executing.

psjapex wrote on Monday, February 06, 2017:

This is actually an K64 Arm cortex m4 chip on a custom board. This is being built out in Kinetis Design Studio IDE. Based on the functionality, I feel like theres an underlying memory issue in my system that is overwriting the semaphore values. See edit in original post.

rtel wrote on Monday, February 06, 2017:

In which case the if statement:

if(reschedule){
}

is not required. The if is done for you inside the portYIELD_FROM_ISR()
macro.

On this device the yield should pend the PendSV interrupt. Is the
interrupt being entered?

If so, the handler will call vTaskSwitchContext(). Is
vTaskSwitchContext() selecting the task you expect? (I think you said
it was, but want to be sure).

heinbali01 wrote on Tuesday, February 07, 2017:

Not sure if it matters, but you create a task that will use a semaphore that hasn’t been created yet.

Task_Main has a high priority of 10. If Task_Main_Initialize runs at a lower priority, chances are big that Task_Main calls xSemaphoreTake() for a non-existing semaphore.

Can you try swap the two statements?

heinbali01 wrote on Wednesday, February 08, 2017:

Any news Peter?