FreeRTOS Event groups

lciummo wrote on Friday, September 11, 2015:

I’ve have to port several Freescale SDK drivers that make use of Event Groups to SafeRTOS, which doesn’t support Events. I can complete remove the event bit code and replace it with semaphore OR I can type to emulate event bits in an OSAL function.

Any ideas and issues with removing them would be appreciated.

Thanks
Larry

heinbali01 wrote on Saturday, September 12, 2015:

Hi Larry,

That is an interesting challenge!

It depends on the way in which Event Groups are being used by the Freescale SDK drivers. Some properties of the Event Groups are much more difficult to simulate than others.

Simplicity: the simulation of Event Groups would be easier if you have the following limitations:

  • event groups are not being accessed from an interrupt
  • there is one Taker ( a task constantly calling xEventGroupWaitBits() )
  • there are many Givers ( calling xEventGroupSetBits() ).

In that case, I would store the following information in a struct:

    typedef struct {
        /* The event bits. */
        EventBits_t uxEventBits;
        /* Information about the waiting task. */
        QueueHandle_t xWaitQueue;
        EventBits_t uxBitsToWaitFor;
    } EventGroupInfo_t;

Here below a rough scatch. it is far from safe and it is far from complete. Please make a study of the existing event_groups.c to understand the exact functioning.

/* The xEventGroupWaitBits() function. */
EventBits_t xEventGroupWaitBits(
    EventGroupInfo_t *pxEventGroup,
    const EventBits_t uxBitsToWaitFor,
    const BaseType_t xClearOnExit,
    const BaseType_t xWaitForAllBits,
    TickType_t xTicksToWait )
{
EventBits_t xResult;
BaseType_t xWaitConditionMet;

    /* Suspend the scheduler, or use taskENTER_CRITICAL() in
    case the Event Groups are accessible from an interrupt. */
    vTaskSuspendAll();
    {
        /* Source code of prvTestWaitCondition() : see event_groups.c ) */
        xWaitConditionMet = prvTestWaitCondition( pxEventGroup->uxEventBits,
            uxBitsToWaitFor, xWaitForAllBits );

        if( xWaitConditionMet == pdFALSE )
        {
            /* This API is about to block until the condition has been met,
            or until a time-out has been reached.  Tell what it is waiting for. */
            pxEventGroup->uxBitsToWaitFor = uxBitsToWaitFor;
            if( xWaitForAllBits != pdFALSE )
            {
                pxEventGroup->uxBitsToWaitFor |= eventWAIT_FOR_ALL_BITS;
            }

            xTaskResumeAll();
            xSemaphoreTake( pxEventGroup->xWaitQueue, xTicksToWait );
            vTaskSuspendAll();

            /* We're not waiting any more. */
            pxEventGroup->uxBitsToWaitFor = 0;

            /* Now test again of the conditions are met. */
            xWaitConditionMet = prvTestWaitCondition( pxEventGroup->uxEventBits,
                uxBitsToWaitFor, xWaitForAllBits );
        }
        if( xWaitConditionMet != pdFALSE )
        {
            /* Apply 'xClearOnExit', if set. */
            xResult = ...
        }
        else
        {
            xResult = 0ul;
        }
    }
    xTaskResumeAll();
    return xResult;
}

EventBits_t xEventGroupSetBits( EventGroupInfo_t *pxEventGroup, const EventBits_t uxBitsToSet )
{
    /* Set the bits from 'uxBitsToSet'. */
    /* If the condition has been reached, wake up the Waiter: */
    if( condition_is_met... )
    {
        SemaphoreGive( pxEventGroup->xWaitQueue );    
    }
}

EventBits_t xEventGroupClearBits( EventGroupInfo_t *pxEventGroup, const EventBits_t uxBitsToClear )
{
EventBits_t uxReturn;

    /* Suspend the scheduler, or use taskENTER_CRITICAL() if necessary. */
    vTaskSuspendAll();
    {
        /* The value returned is the event group value prior to the bits being
        cleared. */
        uxReturn = pxEventGroup->uxEventBits;

        /* Clear the bits. */
        pxEventGroup->uxEventBits &= ~uxBitsToClear;
    }
    xTaskResumeAll();

    return uxReturn;
}

Once again: the above code is far from correct and far from complete. The simulation misses the most important aspect of FreeRTOS’ Event Groups: several tasks waiting for the same event group.

Regards.