Message queue send and receive

If you want the task to be flashing the LED at a specified rate, which is gotten from the queue, one option would be to keep track of when the next LED change would be by, and wait on the queue with a timeout delay of how much time is left. If you do get a value, compute the tick count when you next want to change the LED. If you timed out, or the new computation says now is the time, then change the LED.

Ok, so using vTaskSetTimeOutState/vTaskCheckForTimeOut is able to achieve the designed mentioned above, right?

Yes. It should look something like this -

#define LED_TOGGLE_PERIOD pdMS_TO_TICKS( 1000 )

void ReceiverTask(void * pvParameters)
{
    TickType_t xTicksToWait = LED_TOGGLE_PERIOD;
    TimeOut_t xTimeOut;
    BaseType_t xTimedOut = pdFALSE;

    vTaskSetTimeOutState( &xTimeOut );

    for(;;)
    {
        /* Block here waiting for a command. */
        if( pdPASS == xQueueReceive( xQueue_Command,
                                     &command,
                                    xTicksToWait ) )
        {
            /* Process command. */

            /* Adjust xTicksToWait to account for any time that has been spent
             * in the Blocked state within xQueueReceive so far to ensure the
             * total amount of time spent in the Blocked state does not exceed
             * LED_TOGGLE_PERIOD. */
            if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) != pdFALSE )
            {
                /* Timed out. Toggle the LED. */
                xTimedOut = pdTRUE;
            }
        }
        else
        {
            /* Timed out. Toggle the LED. */
            xTimedOut = pdTRUE;
        }

        if( xTimedOut == pdTRUE )
        {
            xTimedOut = pdFALSE;
            vTaskSetTimeOutState( &xTimeOut );
            xTicksToWait = LED_TOGGLE_PERIOD;
        }
    }
}
1 Like

Thanks Gaurav!
I guess doing so the queue will be emptied after the xQueueReceive() is called.