Notifying task in blocked state

swichu91 wrote on Wednesday, March 06, 2019:

Hello,

I am using task notifications as event groups. Most of events are passed from interrupt but I also need to send one bit from different task in order to perform safe clean and task exit.

Task is responsible for processing audio samples and then place them in StreamBuffer. This is where problems begin. If I notify task which is in blocked state waiting for free space in StreamBuffer then somehow it is ignored. It never unblocks task. If I change code to non blocking by setting timeouts to 0 everything is working correctly.

It’s something obvious that I am missing here…

    while(1)
    {
    	xTaskNotifyWait( 0x00,               /* Don't clear any bits on entry. */
		                         UINT32_MAX,          /* Clear all bits on exit. */
		                         &ulNotificationValue, /* Receives the notification value. */
		                         portMAX_DELAY );    /* Block indefinitely. */

        if(ulNotificationValue & EventStop){
            goto cleanup;
        }

        if(ulNotificationValue & EventOutBufferHalfFull){
                // Code here will blocked until there is free space in StreamBuffer
        }

        if(ulNotificationValue & EventOutBufferFull){
               // Same as above
        }
    }
    
    cleanup:
    // clean and vTaskDelete(NULL)

Interrupt routine:

void IRQ(void)
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    codec_event_t state = EventInBufferHalfFull;

    /* Notify the task that the transmission is complete. */
    if(codec_in_worker_handler){
        xTaskNotifyFromISR(codec_in_worker_handler,state,eSetBits , &xHigherPriorityTaskWoken);
    }
    
    ....
}

And Stop event being send from another task:

    codec_event_t state = EventStop;

    // Send close event to worker
        xTaskNotify(codec_in_worker_handler,state,eSetBits);
    

Any ideas ?

Best regards
Mateusz Piesta

richarddamon wrote on Thursday, March 07, 2019:

I haven’t dug deeply into the code for message buffers, but my understanding from a quick look at them is that they use the direct to task notifications in their implementation, and as such eat all such notifications that have been sent to the task before or during the blocking on the buffer. It might have been better in the design of the buffers (and not sure if it is possible to override the existing implementation) to have the buffer code use just the high order bit in the notification word and only consume that bit as a binary semaphore, instead of using it as a counting semaphore and consuming the whole word.

rtel wrote on Thursday, March 07, 2019:

As I recall, but without double checking, and perhaps dependent on the
version, the stream/message buffers will use the notification state but
not change the notification bits.

The direct to task notification mechanism is now used in many more
scenarios than its original intended purpose, and the intent is to
extend the feature so you have an array of notifications per task,
rather than just one. That way the application writer can decide which
notification number to use for what.

richarddamon wrote on Friday, March 08, 2019:

Looking back at the code, 10.0.0 would clear the notification condition, but at least this has been changed in 10.2.0. I remember looking at the StreamBuffer/MessageBuffer features when they first came out, and noticed how they were using the Notification Feature and saw that it would interfear with how we are using it already. It looks like the later changes may fix that issue, so I may look at them again.