/*
    FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
    All rights reserved

    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

    This file is part of the FreeRTOS distribution.

    FreeRTOS is free software; you can redistribute it and/or modify it under
    the terms of the GNU General Public License (version 2) as published by the
    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.

    ***************************************************************************
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
    >>!   obliged to provide the source code for proprietary components     !<<
    >>!   outside of the FreeRTOS kernel.                                   !<<
    ***************************************************************************

    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
    link: http://www.freertos.org/a00114.html

    ***************************************************************************
     *                                                                       *
     *    FreeRTOS provides completely free yet professionally developed,    *
     *    robust, strictly quality controlled, supported, and cross          *
     *    platform software that is more than just the market leader, it     *
     *    is the industry's de facto standard.                               *
     *                                                                       *
     *    Help yourself get started quickly while simultaneously helping     *
     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
     *    tutorial book, reference manual, or both:                          *
     *    http://www.FreeRTOS.org/Documentation                              *
     *                                                                       *
    ***************************************************************************

    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
    the FAQ page "My application does not run, what could be wrong?".  Have you
    defined configASSERT()?

    http://www.FreeRTOS.org/support - In return for receiving this top quality
    embedded software for free we request you assist our global community by
    participating in the support forum.

    http://www.FreeRTOS.org/training - Investing in training allows your team to
    be as productive as possible as early as possible.  Now you can receive
    FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
    Ltd, and the world's leading authority on the world's leading RTOS.

    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
    compatible FAT file system, and our tiny thread aware UDP/IP stack.

    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.

    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
    licenses offer ticketed support, indemnification and commercial middleware.

    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
    engineered and independently SIL3 certified version for use in safety and
    mission critical applications that require provable dependability.

    1 tab == 4 spaces!
*/



/*
* This file contains fairly comprehensive checks on the behaviour of event
* groups.  It is not intended to be a user friendly demonstration of the
* event groups API.
*
* NOTE:  The tests implemented in this file are informal 'sanity' tests
* only and are not part of the module tests that make use of the
* mtCOVERAGE_TEST_MARKER macro within the event groups implementation.
*/


/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"

/* Demo app includes. */
#include "EventGroupsDemo.h"

#if( INCLUDE_eTaskGetState != 1 )
	#error INCLUDE_eTaskGetState must be set to 1 in FreeRTOSConfig.h to use this demo file.
#endif

/* Priorities used by the tasks. */
#define ebSET_BIT_TASK_PRIORITY		( tskIDLE_PRIORITY )
#define ebWAIT_BIT_TASK_PRIORITY	( tskIDLE_PRIORITY + 1 )

/* Generic bit definitions. */
#define ebBIT_0		( 0x01UL )
#define ebBIT_1		( 0x02UL )
#define ebBIT_2		( 0x04UL )
#define ebBIT_3		( 0x08UL )
#define ebBIT_4		( 0x10UL )
#define ebBIT_5		( 0x20UL )
#define ebBIT_6		( 0x40UL )
#define ebBIT_7		( 0x80UL )

/* Combinations of bits used in the demo. */
#define ebCOMBINED_BITS ( ebBIT_1 | ebBIT_5 | ebBIT_7 )
#define ebALL_BITS ( ebBIT_0 | ebBIT_1 | ebBIT_2 | ebBIT_3 | ebBIT_4 | ebBIT_5 | ebBIT_6 | ebBIT_7 )

/* Associate a bit to each task.  These bits are used to identify all the tasks
that synchronise with the xEventGroupSync() function. */
#define ebSET_BIT_TASK_SYNC_BIT			ebBIT_0
#define ebWAIT_BIT_TASK_SYNC_BIT		ebBIT_1
#define ebRENDESVOUS_TASK_1_SYNC_BIT	ebBIT_2
#define ebRENDESVOUS_TASK_2_SYNC_BIT	ebBIT_3
#define ebALL_SYNC_BITS ( ebSET_BIT_TASK_SYNC_BIT | ebWAIT_BIT_TASK_SYNC_BIT | ebRENDESVOUS_TASK_1_SYNC_BIT | ebRENDESVOUS_TASK_2_SYNC_BIT )

/* A block time of zero simply means "don't block". */
#define ebDONT_BLOCK	( 0 )

/* A 5ms delay. */
#define ebSHORT_DELAY	( 5 / portTICK_PERIOD_MS )

/* Used in the selective bits test which checks no, one or both tasks blocked on
event bits in a group are unblocked as appropriate as different bits get set. */
#define ebSELECTIVE_BITS_1		0x03
#define ebSELECTIVE_BITS_2		0x05

/*-----------------------------------------------------------*/

/*
 * NOTE:  The tests implemented in this function are informal 'sanity' tests
 * only and are not part of the module tests that make use of the
 * mtCOVERAGE_TEST_MARKER macro within the event groups implementation.
 *
 * The master test task.  This task:
 *
 * 1) Calls prvSelectiveBitsTestMasterFunction() to test the behaviour when two
 *    tasks are blocked on different bits in an event group.  The counterpart of
 *    this test is implemented by the prvSelectiveBitsTestSlaveFunction()
 *    function (which is called by the two tasks that block on the event group).
 *
 * 2) Calls prvBitCombinationTestMasterFunction() to test the behaviour when
 *    just one task is blocked on various combinations of bits within an event
 *    group.  The counterpart of this test is implemented within the 'test
 *    slave' task.
 *
 * 3) Calls prvPerformTaskSyncTests() to test task synchronisation behaviour.
 */
static void prvTestMasterTask( void *pvParameters );

/*
 * A helper task that enables the 'test master' task to perform several
 * behavioural tests.  See the comments above the prvTestMasterTask() prototype
 * above.
 */
static void prvTestSlaveTask( void *pvParameters );

/*
 * The part of the test that is performed between the 'test master' task and the
 * 'test slave' task to test the behaviour when the slave blocks on various
 * event bit combinations.
 */
static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle );

/*
 * The part of the test that uses all the tasks to test the task synchronisation
 * behaviour.
 */
static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle );

/*
 * Two instances of prvSyncTask() are created.  They start by calling
 * prvSelectiveBitsTestSlaveFunction() to act as slaves when the test master is
 * executing the prvSelectiveBitsTestMasterFunction() function.  They then loop
 * to test the task synchronisation (rendezvous) behaviour.
 */
static void prvSyncTask( void *pvParameters );

/*
 * Functions used in a test that blocks two tasks on various different bits
 * within an event group - then sets each bit in turn and checks that the
 * correct tasks unblock at the correct times.
 */
static BaseType_t prvSelectiveBitsTestMasterFunction( void );
static void prvSelectiveBitsTestSlaveFunction( void );

/*-----------------------------------------------------------*/

/* Variables that are incremented by the tasks on each cycle provided no errors
have been found.  Used to detect an error or stall in the test cycling. */
static volatile uint32_t ulTestMasterCycles = 0, ulTestSlaveCycles = 0, ulISRCycles = 0;

/* The event group used by all the task based tests. */
static EventGroupHandle_t xEventGroup = NULL;

/* The event group used by the interrupt based tests. */
static EventGroupHandle_t xISREventGroup = NULL;

/* Handles to the tasks that only take part in the synchronisation calls. */
static TaskHandle_t xSyncTask1 = NULL, xSyncTask2 = NULL;

/*-----------------------------------------------------------*/

void vStartEventGroupTasks( void )
{
TaskHandle_t xTestSlaveTaskHandle;

	/*
	 * This file contains fairly comprehensive checks on the behaviour of event
	 * groups.  It is not intended to be a user friendly demonstration of the
	 * event groups API.
	 *
	 * NOTE:  The tests implemented in this file are informal 'sanity' tests
	 * only and are not part of the module tests that make use of the
	 * mtCOVERAGE_TEST_MARKER macro within the event groups implementation.
	 *
	 * Create the test tasks as described at the top of this file.
	 */
	xTaskCreate( prvTestSlaveTask, "WaitO", configMINIMAL_STACK_SIZE, NULL, ebWAIT_BIT_TASK_PRIORITY, &xTestSlaveTaskHandle );
	xTaskCreate( prvTestMasterTask, "SetB", configMINIMAL_STACK_SIZE, ( void * ) xTestSlaveTaskHandle, ebSET_BIT_TASK_PRIORITY, NULL );
	xTaskCreate( prvSyncTask, "Rndv", configMINIMAL_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_1_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask1 );
	xTaskCreate( prvSyncTask, "Rndv", configMINIMAL_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_2_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask2 );

	/* If the last task was created then the others will have been too. */
	configASSERT( xSyncTask2 );

	/* Create the event group used by the ISR tests.  The event group used by
	the tasks is created by the tasks themselves. */
	xISREventGroup = xEventGroupCreate();
	configASSERT( xISREventGroup );
}
/*-----------------------------------------------------------*/

static void prvTestMasterTask( void *pvParameters )
{
BaseType_t xError;

/* The handle to the slave task is passed in as the task parameter. */
TaskHandle_t xTestSlaveTaskHandle = ( TaskHandle_t ) pvParameters;

	/* Avoid compiler warnings. */
	( void ) pvParameters;

	/* Create the event group used by the tasks ready for the initial tests. */
	xEventGroup = xEventGroupCreate();
	configASSERT( xEventGroup );

	/* Perform the tests that block two tasks on different combinations of bits,
	then set each bit in turn and check the correct tasks unblock at the correct
	times. */
	xError = prvSelectiveBitsTestMasterFunction();

	for( ;; )
	{
		/* Recreate the event group ready for the next cycle. */
		xEventGroup = xEventGroupCreate();
		configASSERT( xEventGroup );

		/* Perform the tests that check the behaviour when a single task is
		blocked on various combinations of event bits. */
		xError = prvBitCombinationTestMasterFunction( xError, xTestSlaveTaskHandle );

		/* Perform the task synchronisation tests. */
		xError = prvPerformTaskSyncTests( xError, xTestSlaveTaskHandle );

		/* Delete the event group. */
		vEventGroupDelete( xEventGroup );

		/* Now all the other tasks should have completed and suspended
		themselves ready for the next go around the loop. */
		if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
		{
			xError = pdTRUE;
		}

		if( eTaskGetState( xSyncTask1 ) != eSuspended )
		{
			xError = pdTRUE;
		}

		if( eTaskGetState( xSyncTask2 ) != eSuspended )
		{
			xError = pdTRUE;
		}

		/* Only increment the cycle variable if no errors have been detected. */
		if( xError == pdFALSE )
		{
			ulTestMasterCycles++;
		}

		configASSERT( xError == pdFALSE );
	}
}
/*-----------------------------------------------------------*/

static void prvSyncTask( void *pvParameters )
{
EventBits_t uxSynchronisationBit, uxReturned;

	/* A few tests that check the behaviour when two tasks are blocked on
	various different bits within an event group are performed before this task
	enters its infinite loop to carry out its main demo function. */
	prvSelectiveBitsTestSlaveFunction();

	/* The bit to use to indicate this task is at the synchronisation point is
	passed in as the task parameter. */
	uxSynchronisationBit = ( EventBits_t ) pvParameters;

	for( ;; )
	{
		/* Now this task takes part in a task synchronisation - sometimes known
		as a 'rendezvous'.  Its execution pattern is controlled by the 'test
		master' task, which is responsible for taking this task out of the
		Suspended state when it is time to test the synchronisation behaviour.
		See: http://www.freertos.org/xEventGroupSync.html. */
		vTaskSuspend( NULL );

		/* Set the bit that indicates this task is at the synchronisation
		point.  The first time this is done the 'test master' task has a lower
		priority than this task so this task will get to the sync point before
		the set bits task. */
		uxReturned = xEventGroupSync( xEventGroup,	/* The event group used for the synchronisation. */
									uxSynchronisationBit, /* The bit to set in the event group to indicate this task is at the sync point. */
									ebALL_SYNC_BITS,/* The bits to wait for - these bits are set by the other tasks taking part in the sync. */
									portMAX_DELAY );/* The maximum time to wait for the sync condition to be met before giving up. */

		/* A max delay was used, so this task should only exit the above
		function call when the sync condition is met.  Check this is the
		case. */
		configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS );

		/* Remove compiler warning if configASSERT() is not defined. */
		( void ) uxReturned;

		/* Wait until the 'test master' task unsuspends this task again. */
		vTaskSuspend( NULL );

		/* Set the bit that indicates this task is at the synchronisation
		point again.  This time the 'test master' task has a higher priority
		than this task so will get to the sync point before this task. */
		uxReturned = xEventGroupSync( xEventGroup, uxSynchronisationBit, ebALL_SYNC_BITS, portMAX_DELAY );

		/* Again a max delay was used, so this task should only exit the above
		function call when the sync condition is met.  Check this is the
		case. */
		configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS );

		/* Block on the event group again.  This time the event group is going
		to be deleted while this task is blocked on it so it is expected that 0
		be returned. */
		uxReturned = xEventGroupWaitBits( xEventGroup, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY );
		configASSERT( uxReturned == 0 );
	}
}
/*-----------------------------------------------------------*/

static void prvTestSlaveTask( void *pvParameters )
{
EventBits_t uxReturned;
BaseType_t xError = pdFALSE;

	/* Avoid compiler warnings. */
	( void ) pvParameters;

	for( ;; )
	{
		/**********************************************************************
		* Part 1:  This section is the counterpart to the
		* prvBitCombinationTestMasterFunction() function which is called by the
		* test master task.
		***********************************************************************

		This task is controller by the 'test master' task (which is
		implemented by prvTestMasterTask()).  Suspend until resumed by the
		'test master' task. */
		vTaskSuspend( NULL );

		/* Wait indefinitely for one of the bits in ebCOMBINED_BITS to get
		set.  Clear the bit on exit. */
		uxReturned = xEventGroupWaitBits( xEventGroup,	/* The event group that contains the event bits being queried. */
										 ebBIT_1,		/* The bit to wait for. */
										 pdTRUE,		/* Clear the bit on exit. */
										 pdTRUE,		/* Wait for all the bits (only one in this case anyway). */
										 portMAX_DELAY ); /* Block indefinitely to wait for the condition to be met. */

		/* The 'test master' task set all the bits defined by ebCOMBINED_BITS,
		only one of which was being waited for by this task.  The return value
		shows the state of the event bits when the task was unblocked, however
		because the task was waiting for ebBIT_1 and 'clear on exit' was set to
		the current state of the event bits will have ebBIT_1 clear.  */
		if( uxReturned != ebCOMBINED_BITS )
		{
			xError = pdTRUE;
		}

		/* Now call xEventGroupWaitBits() again, this time waiting for all the
		bits in ebCOMBINED_BITS to be set.  This call should block until the
		'test master' task sets ebBIT_1 - which was the bit cleared in the call
		to xEventGroupWaitBits() above. */
		uxReturned = xEventGroupWaitBits( xEventGroup,
										 ebCOMBINED_BITS, /* The bits being waited on. */
										 pdFALSE,		  /* Don't clear the bits on exit. */
										 pdTRUE,		  /* All the bits must be set to unblock. */
										 portMAX_DELAY );

		/* Were all the bits set? */
		if( ( uxReturned & ebCOMBINED_BITS ) != ebCOMBINED_BITS )
		{
			xError = pdTRUE;
		}

		/* Suspend again to wait for the 'test master' task. */
		vTaskSuspend( NULL );

		/* Now call xEventGroupWaitBits() again, again waiting for all the bits
		in ebCOMBINED_BITS to be set, but this time clearing the bits when the
		task is unblocked. */
		uxReturned = xEventGroupWaitBits( xEventGroup,
									 ebCOMBINED_BITS, /* The bits being waited on. */
									 pdTRUE,		  /* Clear the bits on exit. */
									 pdTRUE,		  /* All the bits must be set to unblock. */
									 portMAX_DELAY );

		/* The 'test master' task set all the bits in the event group, so that
		is the value that should have been returned.  The bits defined by
		ebCOMBINED_BITS will have been clear again in the current value though
		as 'clear on exit' was set to pdTRUE. */
		if( uxReturned != ebALL_BITS )
		{
			xError = pdTRUE;
		}





		/**********************************************************************
		* Part 2:  This section is the counterpart to the
		* prvPerformTaskSyncTests() function which is called by the
		* test master task.
		***********************************************************************


		Once again wait for the 'test master' task to unsuspend this task
		when it is time for the next test. */
		vTaskSuspend( NULL );

		/* Now peform a synchronisation with all the other tasks.  At this point
		the 'test master' task has the lowest priority so will get to the sync
		point after all the other synchronising tasks. */
		uxReturned = xEventGroupSync( xEventGroup,		/* The event group used for the sync. */
									ebWAIT_BIT_TASK_SYNC_BIT, /* The bit in the event group used to indicate this task is at the sync point. */
									ebALL_SYNC_BITS,	/* The bits to wait for.  These bits are set by the other tasks taking part in the sync. */
									portMAX_DELAY );	/* The maximum time to wait for the sync condition to be met before giving up. */

		/* A sync with a max delay should only exit when all the synchronisation
		bits are set... */
		if( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
		{
			xError = pdTRUE;
		}

		/* ...but now the synchronisation bits should be clear again.  Read back
		the current value of the bits within the event group to check that is
		the case.  Setting the bits to zero will return the bits previous value
		then leave all the bits clear. */
		if( xEventGroupSetBits( xEventGroup, 0x00 ) != 0 )
		{
			xError = pdTRUE;
		}

		/* Check the bits are indeed 0 now by simply reading then. */
		if( xEventGroupGetBits( xEventGroup ) != 0 )
		{
			xError = pdTRUE;
		}

		if( xError == pdFALSE )
		{
			/* This task is still cycling without finding an error. */
			ulTestSlaveCycles++;
		}

		vTaskSuspend( NULL );

		/* This time sync when the 'test master' task has the highest priority
		at the point where it sets its sync bit - so this time the 'test master'
		task will get to the sync point before this task. */
		uxReturned = xEventGroupSync( xEventGroup, ebWAIT_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );

		/* A sync with a max delay should only exit when all the synchronisation
		bits are set... */
		if( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
		{
			xError = pdTRUE;
		}

		/* ...but now the sync bits should be clear again. */
		if( xEventGroupSetBits( xEventGroup, 0x00 ) != 0 )
		{
			xError = pdTRUE;
		}

		/* Block on the event group again.  This time the event group is going
		to be deleted while this task is blocked on it, so it is expected that 0
		will be returned. */
		uxReturned = xEventGroupWaitBits( xEventGroup, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY );

		if( uxReturned != 0 )
		{
			xError = pdTRUE;
		}

		if( xError == pdFALSE )
		{
			/* This task is still cycling without finding an error. */
			ulTestSlaveCycles++;
		}

		configASSERT( xError == pdFALSE );
	}
}
/*-----------------------------------------------------------*/

static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle )
{
EventBits_t uxBits;

	/* The three tasks that take part in the synchronisation (rendezvous) are
	expected to be in the suspended state at the start of the test. */
	if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask1 ) != eSuspended )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask2 ) != eSuspended )
	{
		xError = pdTRUE;
	}

	/* Try a synch with no other tasks involved.  First set all the bits other
	than this task's bit. */
	xEventGroupSetBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) );

	/* Then wait on just one bit - the bit that is being set. */
	uxBits = xEventGroupSync( xEventGroup,			/* The event group used for the synchronisation. */
							ebSET_BIT_TASK_SYNC_BIT,/* The bit set by this task when it reaches the sync point. */
							ebSET_BIT_TASK_SYNC_BIT,/* The bits to wait for - in this case it is just waiting for itself. */
							portMAX_DELAY );		/* The maximum time to wait for the sync condition to be met. */

	/* A sync with a max delay should only exit when all the synchronise
	bits are set...check that is the case.  In this case there is only one
	sync bit anyway. */
	if( ( uxBits & ebSET_BIT_TASK_SYNC_BIT ) != ebSET_BIT_TASK_SYNC_BIT )
	{
		xError = pdTRUE;
	}

	/* ...but now the sync bits should be clear again, leaving all the other
	bits set (as only one bit was being waited for). */
	if( xEventGroupGetBits( xEventGroup ) != ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) )
	{
		xError = pdTRUE;
	}

	/* Clear all the bits to zero again. */
	xEventGroupClearBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) );
	if( xEventGroupGetBits( xEventGroup ) != 0 )
	{
		xError = pdTRUE;
	}

	/* Unsuspend the other tasks then check they have executed up to the
	synchronisation point. */
	vTaskResume( xTestSlaveTaskHandle );
	vTaskResume( xSyncTask1 );
	vTaskResume( xSyncTask2 );

	if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask1 ) != eBlocked )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask2 ) != eBlocked )
	{
		xError = pdTRUE;
	}

	/* Set this task's sync bit. */
	uxBits = xEventGroupSync( xEventGroup,			/* The event group used for the synchronisation. */
							ebSET_BIT_TASK_SYNC_BIT,/* The bit set by this task when it reaches the sync point. */
							ebALL_SYNC_BITS,		/* The bits to wait for - these bits are set by the other tasks that take part in the sync. */
							portMAX_DELAY );		/* The maximum time to wait for the sync condition to be met. */

	/* A sync with a max delay should only exit when all the synchronise
	bits are set...check that is the case. */
	if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
	{
		xError = pdTRUE;
	}

	/* ...but now the sync bits should be clear again. */
	if( xEventGroupGetBits( xEventGroup ) != 0 )
	{
		xError = pdTRUE;
	}


	/* The other tasks should now all be suspended again, ready for the next
	synchronisation. */
	if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask1 ) != eSuspended )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask2 ) != eSuspended )
	{
		xError = pdTRUE;
	}


	/* Sync again - but this time set the last necessary bit as the
	highest priority task, rather than the lowest priority task.  Unsuspend
	the other tasks then check they have executed up to the	synchronisation
	point. */
	vTaskResume( xTestSlaveTaskHandle );
	vTaskResume( xSyncTask1 );
	vTaskResume( xSyncTask2 );

	if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask1 ) != eBlocked )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask2 ) != eBlocked )
	{
		xError = pdTRUE;
	}

	/* Raise the priority of this task above that of the other tasks. */
	vTaskPrioritySet( NULL, ebWAIT_BIT_TASK_PRIORITY + 1 );

	/* Set this task's sync bit. */
	uxBits = xEventGroupSync( xEventGroup, ebSET_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );

	/* A sync with a max delay should only exit when all the synchronisation
	bits are set... */
	if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
	{
		xError = pdTRUE;
	}

	/* ...but now the sync bits should be clear again. */
	if( xEventGroupGetBits( xEventGroup ) != 0 )
	{
		xError = pdTRUE;
	}


	/* The other tasks should now all be in the ready state again, but not
	executed yet as this task still has a higher relative priority. */
	if( eTaskGetState( xTestSlaveTaskHandle ) != eReady )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask1 ) != eReady )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask2 ) != eReady )
	{
		xError = pdTRUE;
	}


	/* Reset the priority of this task back to its original value. */
	vTaskPrioritySet( NULL, ebSET_BIT_TASK_PRIORITY );

	/* Now all the other tasks should have reblocked on the event bits
	to test the behaviour when the event bits are deleted. */
	if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask1 ) != eBlocked )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask2 ) != eBlocked )
	{
		xError = pdTRUE;
	}

	return xError;
}
/*-----------------------------------------------------------*/

static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle )
{
EventBits_t uxBits;

	/* Resume the other task.  It will block, pending a single bit from
	within ebCOMBINED_BITS. */
	vTaskResume( xTestSlaveTaskHandle );

	/* Ensure the other task is blocked on the task. */
	if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
	{
		xError = pdTRUE;
	}

	/* Set all the bits in ebCOMBINED_BITS - the 'test slave' task is only
	blocked waiting for one of them. */
	xEventGroupSetBits( xEventGroup, ebCOMBINED_BITS );

	/* The 'test slave' task should now have executed, clearing ebBIT_1 (the
	bit it was blocked on), then re-entered the Blocked state to wait for
	all the other bits in ebCOMBINED_BITS to be set again.  First check
	ebBIT_1 is clear. */
	uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );

	if( uxBits != ( ebCOMBINED_BITS & ~ebBIT_1 ) )
	{
		xError = pdTRUE;
	}

	/* Ensure the other task is still in the blocked state. */
	if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
	{
		xError = pdTRUE;
	}

	/* Set all the bits other than ebBIT_1 - which is the bit that must be
	set before the other task unblocks. */
	xEventGroupSetBits( xEventGroup, ebALL_BITS & ~ebBIT_1 );

	/* Ensure all the expected bits are still set. */
	uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );

	if( uxBits != ( ebALL_BITS & ~ebBIT_1 ) )
	{
		xError = pdTRUE;
	}

	/* Ensure the other task is still in the blocked state. */
	if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
	{
		xError = pdTRUE;
	}

	/* Now also set ebBIT_1, which should unblock the other task, which will
	then suspend itself. */
	xEventGroupSetBits( xEventGroup, ebBIT_1 );

	/* Ensure the other task is suspended. */
	if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
	{
		xError = pdTRUE;
	}

	/* The other task should not have cleared the bits - so all the bits
	should still be set. */
	if( xEventGroupSetBits( xEventGroup, 0x00 ) != ebALL_BITS )
	{
		xError = pdTRUE;
	}

	/* Clear ebBIT_1 again. */
	if( xEventGroupClearBits( xEventGroup, ebBIT_1 ) != ebALL_BITS )
	{
		xError = pdTRUE;
	}

	/* Resume the other task - which will wait on all the ebCOMBINED_BITS
	again - this time clearing the bits when it is unblocked. */
	vTaskResume( xTestSlaveTaskHandle );

	/* Ensure the other task is blocked once again. */
	if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
	{
		xError = pdTRUE;
	}

	/* Set the bit the other task is waiting for. */
	xEventGroupSetBits( xEventGroup, ebBIT_1 );

	/* Ensure the other task is suspended once again. */
	if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
	{
		xError = pdTRUE;
	}

	/* The other task should have cleared the bits in ebCOMBINED_BITS.
	Clear the remaining bits. */
	uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );

	if( uxBits != ( ebALL_BITS & ~ebCOMBINED_BITS ) )
	{
		xError = pdTRUE;
	}

	/* Clear all bits ready for the sync with the other three tasks.  The
	value returned is the value prior to the bits being cleared. */
	if( xEventGroupClearBits( xEventGroup, ebALL_BITS ) != ( ebALL_BITS & ~ebCOMBINED_BITS ) )
	{
		xError = pdTRUE;
	}

	/* The bits should be clear now. */
	if( xEventGroupGetBits( xEventGroup ) != 0x00 )
	{
		xError = pdTRUE;
	}

	return xError;
}
/*-----------------------------------------------------------*/

static void prvSelectiveBitsTestSlaveFunction( void )
{
EventBits_t uxPendBits, uxReturned;

	/* Used in a test that blocks two tasks on various different bits within an
	event group - then sets each bit in turn and checks that the correct tasks
	unblock at the correct times.

	This function is called by two different tasks - each of which will use a
	different bit.  Check the task handle to see which task the function was
	called by. */
	if( xTaskGetCurrentTaskHandle() == xSyncTask1 )
	{
		uxPendBits = ebSELECTIVE_BITS_1;
	}
	else
	{
		uxPendBits = ebSELECTIVE_BITS_2;
	}

	for( ;; )
	{
		/* Wait until it is time to perform the next cycle of the test.  The
		task is unsuspended by the tests implemented in the
		prvSelectiveBitsTestMasterFunction() function. */
		vTaskSuspend( NULL );
		uxReturned = xEventGroupWaitBits( xEventGroup, uxPendBits, pdTRUE, pdFALSE, portMAX_DELAY );

		if( uxReturned == ( EventBits_t ) 0 )
		{
			break;
		}
	}
}
/*-----------------------------------------------------------*/

static BaseType_t prvSelectiveBitsTestMasterFunction( void )
{
BaseType_t xError = pdFALSE;
EventBits_t uxBit;

	/* Used in a test that blocks two tasks on various different bits within an
	event group - then sets each bit in turn and checks that the correct tasks
	unblock at the correct times.  The two other tasks (xSyncTask1 and
	xSyncTask2) call prvSelectiveBitsTestSlaveFunction() to perform their parts in
	this test.

	Both other tasks should start in the suspended state. */
	if( eTaskGetState( xSyncTask1 ) != eSuspended )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask2 ) != eSuspended )
	{
		xError = pdTRUE;
	}

	/* Test each bit in the byte individually. */
	for( uxBit = 0x01; uxBit < 0x100; uxBit <<= 1 )
	{
		/* Resume both tasks. */
		vTaskResume( xSyncTask1 );
		vTaskResume( xSyncTask2 );

		/* Now both tasks should be blocked on the event group. */
		if( eTaskGetState( xSyncTask1 ) != eBlocked )
		{
			xError = pdTRUE;
		}

		if( eTaskGetState( xSyncTask2 ) != eBlocked )
		{
			xError = pdTRUE;
		}

		/* Set one bit. */
		xEventGroupSetBits( xEventGroup, uxBit );

		/* Is the bit set in the first set of selective bits?  If so the first
		sync task should have unblocked and returned to the suspended state. */
		if( ( uxBit & ebSELECTIVE_BITS_1 ) == 0 )
		{
			/* Task should not have unblocked. */
			if( eTaskGetState( xSyncTask1 ) != eBlocked )
			{
				xError = pdTRUE;
			}
		}
		else
		{
			/* Task should have unblocked and returned to the suspended state. */
			if( eTaskGetState( xSyncTask1 ) != eSuspended )
			{
				xError = pdTRUE;
			}
		}

		/* Same checks for the second sync task. */
		if( ( uxBit & ebSELECTIVE_BITS_2 ) == 0 )
		{
			/* Task should not have unblocked. */
			if( eTaskGetState( xSyncTask2 ) != eBlocked )
			{
				xError = pdTRUE;
			}
		}
		else
		{
			/* Task should have unblocked and returned to the suspended state. */
			if( eTaskGetState( xSyncTask2 ) != eSuspended )
			{
				xError = pdTRUE;
			}
		}
	}

	/* Ensure both tasks are blocked on the event group again, then delete the
	event group so the other tasks leave this portion of the test. */
	vTaskResume( xSyncTask1 );
	vTaskResume( xSyncTask2 );

	/* Deleting the event group is the signal that the two other tasks should
	leave the prvSelectiveBitsTestSlaveFunction() function and continue to the main
	part of their functionality. */
	vEventGroupDelete( xEventGroup );

	return xError;
}
/*-----------------------------------------------------------*/

void vPeriodicEventGroupsProcessing( void )
{
static BaseType_t xCallCount = 0, xISRTestError = pdFALSE;
const BaseType_t xSetBitCount = 100, xGetBitsCount = 200, xClearBitsCount = 300;
const EventBits_t uxBitsToSet = 0x12U;
EventBits_t uxReturned;
BaseType_t xMessagePosted;

	/* Called periodically from the tick hook to exercise the "FromISR"
	functions. */

	xCallCount++;

	if( xCallCount == xSetBitCount )
	{
		/* All the event bits should start clear. */
		uxReturned = xEventGroupGetBitsFromISR( xISREventGroup );
		if( uxReturned != 0x00 )
		{
			xISRTestError = pdTRUE;
		}
		else
		{
			/* Set the bits.  This is called from the tick hook so it is not
			necessary to use the last parameter to ensure a context switch
			occurs immediately. */
			xMessagePosted = xEventGroupSetBitsFromISR( xISREventGroup, uxBitsToSet, NULL );
			if( xMessagePosted != pdPASS )
			{
				xISRTestError = pdTRUE;
			}
		}
	}
	else if( xCallCount == xGetBitsCount )
	{
		/* Check the bits were set as expected. */
		uxReturned = xEventGroupGetBitsFromISR( xISREventGroup );
		if( uxReturned != uxBitsToSet )
		{
			xISRTestError = pdTRUE;
		}
	}
	else if( xCallCount == xClearBitsCount )
	{
		/* Clear the bits again. */
		uxReturned = xEventGroupClearBitsFromISR( xISREventGroup, uxBitsToSet );

		/* Check the message was posted. */
		if( uxReturned != pdPASS )
		{
			xISRTestError = pdTRUE;
		}

		/* Go back to the start. */
		xCallCount = 0;

		/* If no errors have been detected then increment the count of test
		cycles. */
		if( xISRTestError == pdFALSE )
		{
			ulISRCycles++;
		}
	}
	else
	{
		/* Nothing else to do. */
	}
}

/*-----------------------------------------------------------*/
/* This is called to check that all the created tasks are still running. */
BaseType_t xAreEventGroupTasksStillRunning( void )
{
static uint32_t ulPreviousWaitBitCycles = 0, ulPreviousSetBitCycles = 0, ulPreviousISRCycles = 0;
BaseType_t xStatus = pdPASS;

	/* Check the tasks are still cycling without finding any errors. */
	if( ulPreviousSetBitCycles == ulTestMasterCycles )
	{
		xStatus = pdFAIL;
	}
	ulPreviousSetBitCycles = ulTestMasterCycles;

	if( ulPreviousWaitBitCycles == ulTestSlaveCycles )
	{
		xStatus = pdFAIL;
	}
	ulPreviousWaitBitCycles = ulTestSlaveCycles;

	if( ulPreviousISRCycles == ulISRCycles )
	{
		xStatus = pdFAIL;
	}
	ulPreviousISRCycles = ulISRCycles;

	return xStatus;
}



