Task appears to get suspended, while it should be unblocked

Hi, I’m using an LPC824 part from NXP (ARM cortex-M0+). I’ve a project with a single task, that’s blocked on a task notification. It has a timeout, which loops back to the beginning: ~~~~~ static void vDSBCommunicationTask (void *pvParameters) { for(;;) { uint32_t events;
    if (xTaskNotifyWait(pdFALSE,UINT32_MAX,&events,pdMS_TO_TICKS(WWDT_DSB_FEED_TIMEOUT_MS))!=pdTRUE) {
        Board_LED_Toggle();
        continue;
    }

    //Do some real work.......
}
~~~~~ Normally this toggles the LED fine. The interrupt notifies the task at various occasions, but one of these seems to suspend the task: ~~~~~ static int16t dsballowcommand(enum dsbcommands command) { //Called in interrupt context switch (command) { case dsbcommandenumerate: xTaskNotifyFromISR(dsbCommunicationTask,dsbcommunicationeventrequestaddress,eSetBits,NULL); return -1; //more case’s….. } } ~~~~~ After this xTaskNotifyFromISR() is called, the LED stops blinking and the task is never unblocked. When I stop the debugger, the vApplicationIdleHook() function is running fine, so the scheduler seems to be running. If I request a context switch from within the dsballowcommand() function, the task does get unblocked, but I don’t understand why it doesn’t work without that context switch request. I would expect that at the next systick event, the scheduler would notice that the task can be unblocked. Why does the task stop working? Thanks in advance. Kind regards, Remco Poelstra

Task appears to get suspended, while it should be unblocked

On the Cortex-M port a tick interrupt will not force a context switch unless: 1) The tick interrupt causes a higher priority task to leave the blocked state (time out), or 2) configUSETIMESLICING is not 0 and there is another task of the same priority as the currently executing task. This is a good point – and needs documenting better. Older ports would context switch on each tick, but the behaviour was changed as an optimisation. Regards.

Task appears to get suspended, while it should be unblocked

Hi, Thanks for your response. I don’t think I fully understand your answer, as I seem unable to explain why the xTaskNotifyWait() will (regularly) timeout before the (I2C) interrupt has occured, and will no longer timeout after the (I2C) interrupt has occured. The task has a priority of tskIDLE_PRIORITY + 1UL, so your point 1) tells me that after the (I2C) interrupt has occured (and the notification is posted) the tick interrupt should notice that the task (with a higher priority than the idle task) has become unblocked. At least it should keep noticing that it times out every now and then, just as it did before the (I2C) interrupt occurs. Regards, Remco Poelstra

Task appears to get suspended, while it should be unblocked

Point (1) says a context switch will occur if the tick interrupt causes a task to unblock. In your case it was not the tick interrupt that caused a task to unblock.
If I request a context switch from within the dsballowcommand() function, the task does get unblocked
So why not do that? You are setting the xHigherPriorityTaskWoken parameter to NULL – but it is intended that parameter is used to determine if a context switch is required or not. Regards.

Task appears to get suspended, while it should be unblocked

Ah, now I see the difference. Yes, I will use that solution. I was wondering whether it was the right solution or just masked the real problem. Thanks for your help. Regards, Remco Poelstra