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.
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
static SemaphoreHandlet _semmainTask;
if ( 0 != configSUPPORTSTATICALLOCATION )
static StaticSemaphoret _semmainTask_buffer;
TaskHandle_t mainTaskHandle = NULL;
static void Task_Main( void pvParameters )
(void) pvParameters; / not used */
int test = 5;
long sleep = SLEEP;
BaseType_t _semGiven = pdFALSE;
_semGiven = xSemaphoreTake(_sem_mainTask, ( TickType_t )SLEEP);
if( _semGiven == pdTRUE)
void TaskMainInitialize( TaskHandlet *taskhandle )
//void TaskMainInitialize( 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 */
//create the binary semaphore
#if ( 1 != configSUPPORT_STATIC_ALLOCATION )
_sem_mainTask = xSemaphoreCreateBinaryStatic( &_sem_mainTask_buffer );
#else /* configSUPPORT_DYNAMIC_ALLOCATION */
_sem_mainTask = xSemaphoreCreateBinary();
//give the binary semaphore to kick it off
xSemaphoreGive( _sem_mainTask );
//dedicated to yielding to the main task
//CLEARN THE INTERRUPT FLAG!!!!
PIT_ClearStatusFlags(PIT, 1, kPIT_TimerFlag);
//go to sleeping task
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 portYIELDFROMISR() function for the PIC24? Other than
that, I can't see anything standing out as being wrong. Can you step
into the portYIELDFROMISR() 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.
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.
In which case the if statement:
is not required. The if is done for you inside the portYIELDFROMISR()
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).
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
xSemaphoreTake() for a non-existing semaphore.
Can you try swap the two statements?