Blocking task based on a variable

Hi

is there such feature in FreeRTOS which acts like the following way:

unsigned int var = 0;

if(BlockIfVariableEqualsZero(&var, portMAX_DELAY) == pdPASS) {
//variable is not zero
// switch on and refresh 7 segment display digits
}

I have a fairly busy display task (it has to multiplex a 4 digit 7 segment display, every 5-7 ms). I don’t want this display task to run all the time so I have a function select button task which steps between display functions using a state variable. If the display function state variable is zero then the display task should be blocked to save CPU time for other tasks.

FreeRTOS can’t block waiting for a normal variable change value.

What you could do is test the variable, and if zero block on a semaphore (or a direct-to-task notification) and when you elsewhere set the value non-zero you also give to that semaphore (or give the direct-to-task notification).

Hi Gergo,

welcome, first of all!

What you could do is implement a reader-writer lock (it’s not exactly what you had in mind, but can serve a similar purpose). That’s not a FreeRTOS primitive, but it can be built from FreeRTOS primitives. I do discuss that in my book, unfortunately, it’s in German.

If you want to wade through the sample code, go to FreeRTOS/Cortex book, scroll down to the link that says “Zusatzmaterial” and click it (to my best knowledge, it’s safe, at least the one I submitted to the publisher is). Download and unpack the .zip, navigate to chapter 6\src and open rwlock.c. I’m willing to translate the inner workings for you to English to a certain degree by PM if necessary.

Best of luck!

One possibility is to use the direct to task notification as a lightweight mailbox. The direct to task notifications can only hold a single 32-bit value. You can do anything you want with this value.

The code snippet below will wait forever for any write to the 0’th task notification (there is more than 1). When another task writes to the notification, this function will unblock and check the notification for non-zero. If it is non-zero the display can be refreshed. If it is zero, this can go back to sleep. This function will automatically clear the notification value to zero when it exits so it will always to to sleep with a zero in the notification.

void vAnEventProcessingTask( void *pvParameters )
{
    uint32_t ulNotifiedValue;

    for( ;; )
    {
        xTaskNotifyWaitIndexed( 0,         /* Wait for 0th notification. */
                                0x00,      /* Don't clear any notification bits on entry. */
                                ULONG_MAX, /* Reset the notification value to 0 on exit. */
                                &ulNotifiedValue, /* Notified value pass out in
                                                     ulNotifiedValue. */
                                portMAX_DELAY );  /* Block indefinitely. */

        if( ( ulNotifiedValue ) != 0 )
        {
            // update the display
        }
    }
}

Sadly, this function will wake on ANY write to the notification and not simply writes of non-zero values. But the check for zero is very fast so you will spend most of your time blocked and doing other tasks.

For more information on task notifications follow this link: