ulTaskNotifyTake returns 0 and doesn’t block, intermittent problem

Hi. My tasks implement a state machine and the task loop looks like this: ~~~ while(ulTaskNotifyTake( pdFALSE, portMAXDELAY)) { } ~~~ I should mention that I’ve also tried with binary semaphores and also with a binary notify, i.e. ulTaskNotifyTake( pdTRUE, portMAXDELAY). with the same results I’m describing here. The problem is that the while loop exits with return value 0 without blocking. It happens occasionally. I have looked for stack errors and other obvious problems but have failed to find anything. Inside the function: uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) at entry: ~~~ xClearCountOnExit == 0 xTicksToWait == 0xffffffff pxCurrentTCB->ucNotifyState == 0 pxCurrentTCB->ulNotifiedValue == 0 ulReturn = 0 ~~~ Top section: ~~~ taskENTERCRITICAL(); { /* Only block if the notification count is not already non-zero. */ if( pxCurrentTCB->ulNotifiedValue == 0UL ) // ==> true { /* Mark this task as waiting for a notification. */ pxCurrentTCB->ucNotifyState = taskWAITINGNOTIFICATION; // ==> set to 1
            if( xTicksToWait > ( TickType_t ) 0 ) // ==> true
            {
                prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE );
                portYIELD_WITHIN_API(); // NOT BLOCKING
~~~ Bottom section: ~~~ ulReturn = pxCurrentTCB->ulNotifiedValue; // ==> 0
        if( ulReturn != 0UL )  // ==> false
/snip/ pxCurrentTCB->ucNotifyState = taskNOTWAITINGNOTIFICATION; // ==> 0 return ulReturn; // ==> 0 ~~~ The task while loop now exits and you get stuck in the task exit trap. Any suggestions what might be going wrong? I’m using FreeRTOS 9.0.0 and it’s working fine most of the time. Thanks! Knut

ulTaskNotifyTake returns 0 and doesn’t block, intermittent problem

The first thing that comes to mind would be an interrupt priority problem. If that is not the case then I will have to do a more detailed study to see how what you describe could occur. First the interrupt priority question: Which device are you running FreeRTOS on? If you are using a Cortex-M, RX100/200/600 or PIC32, does your system include any interrupts that use the FreeRTOS API? If so, what is the/are the interrupt priorities set to, and what is your configMAXSYSCALLINTERRUPT_PRIORITY value set to?

ulTaskNotifyTake returns 0 and doesn’t block, intermittent problem

Which device are you running FreeRTOS on? SiLabs EFR32FG1P, Cortex M4 based chip. If you are using a Cortex-M, RX100/200/600 or PIC32, does your system include any interrupts that use the FreeRTOS API? Yes. Based on a previous discussion I use the deferred ISR method of the timer task for all my ISRs that access FreeRTOS API. There is one exception to this rule. SiLabs API requires a buffer to be returned in an ISR callback during reception. I’m doing this with my own memory pool which contain pre-allocated buffers from FreeRTOS heap4.c. Thus no FreeRTOS API function is called in runtime. If so, what is the/are the interrupt priorities set to, and what is your configMAXSYSCALLINTERRUPT_PRIORITY value set to? ~~~

define configKERNELINTERRUPTPRIORITY ( 255 ) /* equivalent to 0xe0 (224d), or priority 7. (highest, only 3-bits) */

define configMAXSYSCALLINTERRUPT_PRIORITY ( 191 ) /* equivalent to 0xa0 (160d), or priority 5. */

… uint32t maxsyscallprio = configMAXSYSCALLINTERRUPTPRIORITY >> (8 – __NVICPRIOBITS); … NVICSetPriority(GPIOODDIRQn, maxsyscallprio + 1); NVICSetPriority(TIMER0IRQn, maxsyscallprio + 0); ~~~ All my interrupts are set to the same priority as configMAXSYSCALLINTERRUPTPRIORITY or (configMAXSYSCALLINTERRUPT_PRIORITY +1), e.g. one lower priority on ARM CM4. thanks! Knut

ulTaskNotifyTake returns 0 and doesn’t block, intermittent problem

That looks ok so I will have to go into the code in more detail.