\r
\r
/*\r
- * This file contains fairly comprehensive checks on the behaviour of event\r
- * groups. It is not intended to be a user friendly demonstration of the event\r
- * groups API.\r
- */\r
-\r
+* This file contains fairly comprehensive checks on the behaviour of event\r
+* groups. It is not intended to be a user friendly demonstration of the\r
+* event groups API.\r
+*\r
+* NOTE: The tests implemented in this file are informal 'sanity' tests \r
+* only and are not part of the module tests that make use of the \r
+* mtCOVERAGE_TEST_MARKER macro within the event groups implementation.\r
+*/\r
\r
\r
/* Scheduler include files. */\r
#include "task.h"\r
#include "event_groups.h"\r
\r
+/* Demo app includes. */\r
+#include "EventGroupsDemo.h"\r
+\r
/* Priorities used by the tasks. */\r
#define ebSET_BIT_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
#define ebWAIT_BIT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
#define ebBIT_6 ( 0x40UL )\r
#define ebBIT_7 ( 0x80UL )\r
\r
-/* Combinations of bits used in the tests. */\r
+/* Combinations of bits used in the demo. */\r
#define ebCOMBINED_BITS ( ebBIT_1 | ebBIT_5 | ebBIT_7 )\r
#define ebALL_BITS ( ebBIT_0 | ebBIT_1 | ebBIT_2 | ebBIT_3 | ebBIT_4 | ebBIT_5 | ebBIT_6 | ebBIT_7 )\r
\r
/*-----------------------------------------------------------*/\r
\r
/*\r
- * The primary task that manages and controls all the behavioural tests.\r
+ * NOTE: The tests implemented in this function are informal 'sanity' tests \r
+ * only and are not part of the module tests that make use of the \r
+ * mtCOVERAGE_TEST_MARKER macro within the event groups implementation.\r
+ *\r
+ * The master test task. This task:\r
+ *\r
+ * 1) Calls prvSelectiveBitsTestMasterFunction() to test the behaviour when two \r
+ * tasks are blocked on different bits in an event group. The counterpart of \r
+ * this test is implemented by the prvSelectiveBitsTestSlaveFunction() \r
+ * function (which is called by the two tasks that block on the event group).\r
+ *\r
+ * 2) Calls prvBitCombinationTestMasterFunction() to test the behaviour when\r
+ * just one task is blocked on various combinations of bits within an event \r
+ * group. The counterpart of this test is implemented within the 'test \r
+ * slave' task.\r
+ *\r
+ * 3) Calls prvPerformTaskSyncTests() to test task synchronisation behaviour.\r
+ */\r
+static void prvTestMasterTask( void *pvParameters );\r
+\r
+/*\r
+ * A helper task that enables the 'test master' task to perform several \r
+ * behavioural tests. See the comments above the prvTestMasterTask() prototype\r
+ * above.\r
*/\r
-static void prvSetBitsTask( void *pvParameters );\r
+static void prvTestSlaveTask( void *pvParameters );\r
\r
/*\r
- * The task that participates in most of the non 'single task' tests performed\r
- * by prvSetBitsTask().\r
+ * The part of the test that is performed between the 'test master' task and the\r
+ * 'test slave' task to test the behaviour when the slave blocks on various\r
+ * event bit combinations.\r
*/\r
-static void prvWaitBitsTask( void *pvParameters );\r
+static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle );\r
\r
/*\r
- * Two instances of prvSyncTask() are created. Their only purpose is to\r
- * participate in synchronisations and test the behaviour when an event group on\r
- * which they are blocked is deleted.\r
+ * The part of the test that uses all the tasks to test the task synchronisation\r
+ * behaviour.\r
+ */\r
+static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle );\r
+\r
+/*\r
+ * Two instances of prvSyncTask() are created. They start by calling \r
+ * prvSelectiveBitsTestSlaveFunction() to act as slaves when the test master is\r
+ * executing the prvSelectiveBitsTestMasterFunction() function. They then loop\r
+ * to test the task synchronisation (rendezvous) behaviour.\r
*/\r
static void prvSyncTask( void *pvParameters );\r
\r
* within an event group - then sets each bit in turn and checks that the \r
* correct tasks unblock at the correct times.\r
*/\r
-static portBASE_TYPE prvTestSelectiveBits( void );\r
-static void prvPreSyncSelectiveWakeTest( void );\r
+static BaseType_t prvSelectiveBitsTestMasterFunction( void );\r
+static void prvSelectiveBitsTestSlaveFunction( void );\r
\r
/*-----------------------------------------------------------*/\r
\r
/* Variables that are incremented by the tasks on each cycle provided no errors\r
have been found. Used to detect an error or stall in the test cycling. */\r
-static volatile unsigned long ulSetBitCycles = 0, ulWaitBitCycles = 0;\r
+static volatile unsigned long ulTestMasterCycles = 0, ulTestSlaveCycles = 0, ulISRCycles = 0;\r
\r
-/* The event group used by all the tests. */\r
-static EventGroupHandle_t xEventBits = NULL;\r
+/* The event group used by all the task based tests. */\r
+static EventGroupHandle_t xEventGroup = NULL;\r
+\r
+/* The event group used by the interrupt based tests. */\r
+static EventGroupHandle_t xISREventGroup = NULL;\r
\r
/* Handles to the tasks that only take part in the synchronisation calls. */\r
-static xTaskHandle xSyncTask1 = NULL, xSyncTask2 = NULL;\r
+static TaskHandle_t xSyncTask1 = NULL, xSyncTask2 = NULL;\r
\r
/*-----------------------------------------------------------*/\r
\r
void vStartEventGroupTasks( void )\r
{\r
-xTaskHandle xWaitBitsTaskHandle;\r
+TaskHandle_t xTestSlaveTaskHandle;\r
\r
/*\r
* This file contains fairly comprehensive checks on the behaviour of event\r
* groups. It is not intended to be a user friendly demonstration of the\r
* event groups API.\r
+ *\r
+ * NOTE: The tests implemented in this file are informal 'sanity' tests \r
+ * only and are not part of the module tests that make use of the \r
+ * mtCOVERAGE_TEST_MARKER macro within the event groups implementation.\r
+ *\r
+ * Create the test tasks as described at the top of this file.\r
*/\r
-\r
- xTaskCreate( prvWaitBitsTask, "WaitO", configMINIMAL_STACK_SIZE, NULL, ebWAIT_BIT_TASK_PRIORITY, &xWaitBitsTaskHandle );\r
- xTaskCreate( prvSetBitsTask, "SetB", configMINIMAL_STACK_SIZE, ( void * ) xWaitBitsTaskHandle, ebSET_BIT_TASK_PRIORITY, NULL );\r
+ xTaskCreate( prvTestSlaveTask, "WaitO", configMINIMAL_STACK_SIZE, NULL, ebWAIT_BIT_TASK_PRIORITY, &xTestSlaveTaskHandle );\r
+ xTaskCreate( prvTestMasterTask, "SetB", configMINIMAL_STACK_SIZE, ( void * ) xTestSlaveTaskHandle, ebSET_BIT_TASK_PRIORITY, NULL );\r
xTaskCreate( prvSyncTask, "Rndv", configMINIMAL_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_1_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask1 );\r
xTaskCreate( prvSyncTask, "Rndv", configMINIMAL_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_2_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask2 );\r
\r
/* If the last task was created then the others will have been too. */\r
configASSERT( xSyncTask2 );\r
+\r
+ /* Create the event group used by the ISR tests. The event group used by\r
+ the tasks is created by the tasks themselves. */\r
+ xISREventGroup = xEventGroupCreate();\r
+ configASSERT( xISREventGroup );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvTestMasterTask( void *pvParameters )\r
+{\r
+BaseType_t xError;\r
+\r
+/* The handle to the slave task is passed in as the task parameter. */\r
+TaskHandle_t xTestSlaveTaskHandle = ( TaskHandle_t ) pvParameters;\r
+\r
+ /* Avoid compiler warnings. */\r
+ ( void ) pvParameters;\r
+\r
+ /* Create the event group used by the tasks ready for the initial tests. */\r
+ xEventGroup = xEventGroupCreate();\r
+ configASSERT( xEventGroup );\r
+\r
+ /* Perform the tests that block two tasks on different combinations of bits, \r
+ then set each bit in turn and check the correct tasks unblock at the correct \r
+ times. */\r
+ xError = prvSelectiveBitsTestMasterFunction();\r
+\r
+ for( ;; )\r
+ {\r
+ /* Recreate the event group ready for the next cycle. */\r
+ xEventGroup = xEventGroupCreate();\r
+ configASSERT( xEventGroup );\r
+\r
+ /* Perform the tests that check the behaviour when a single task is\r
+ blocked on various combinations of event bits. */\r
+ xError = prvBitCombinationTestMasterFunction( xError, xTestSlaveTaskHandle );\r
+\r
+ /* Perform the task synchronisation tests. */\r
+ xError = prvPerformTaskSyncTests( xError, xTestSlaveTaskHandle );\r
+\r
+ /* Delete the event group. */\r
+ vEventGroupDelete( xEventGroup );\r
+\r
+ /* Now all the other tasks should have completed and suspended\r
+ themselves ready for the next go around the loop. */\r
+ if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
+\r
+ if( eTaskGetState( xSyncTask1 ) != eSuspended )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
+\r
+ if( eTaskGetState( xSyncTask2 ) != eSuspended )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
+\r
+ /* Only increment the cycle variable if no errors have been detected. */\r
+ if( xError == pdFALSE )\r
+ {\r
+ ulTestMasterCycles++;\r
+ }\r
+\r
+ configASSERT( xError == pdFALSE );\r
+ }\r
}\r
/*-----------------------------------------------------------*/\r
\r
{\r
EventBits_t uxSynchronisationBit, uxReturned;\r
\r
+ /* A few tests that check the behaviour when two tasks are blocked on \r
+ various different bits within an event group are performed before this task\r
+ enters its infinite loop to carry out its main demo function. */\r
+ prvSelectiveBitsTestSlaveFunction();\r
+\r
/* The bit to use to indicate this task is at the synchronisation point is\r
passed in as the task parameter. */\r
uxSynchronisationBit = ( EventBits_t ) pvParameters;\r
\r
- /* A few tests are performed before entering the main demo loop. */\r
- prvPreSyncSelectiveWakeTest();\r
-\r
for( ;; )\r
{\r
- /* Wait until the 'set bit' task unsuspends this task. */\r
+ /* Now this task takes part in a task synchronisation - sometimes known \r
+ as a 'rendezvous'. Its execution pattern is controlled by the 'test \r
+ master' task, which is responsible for taking this task out of the \r
+ Suspended state when it is time to test the synchronisation behaviour. \r
+ See: http://www.freertos.org/xEventGroupSync.html. */\r
vTaskSuspend( NULL );\r
\r
/* Set the bit that indicates this task is at the synchronisation\r
- point. The first time this is done the 'set bit' task has a lower\r
- priority than this task. */\r
- uxReturned = xEventGroupSync( xEventBits, uxSynchronisationBit, ebALL_SYNC_BITS, portMAX_DELAY );\r
+ point. The first time this is done the 'test master' task has a lower\r
+ priority than this task so this task will get to the sync point before\r
+ the set bits task. */\r
+ uxReturned = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */\r
+ uxSynchronisationBit, /* The bit to set in the event group to indicate this task is at the sync point. */\r
+ ebALL_SYNC_BITS,/* The bits to wait for - these bits are set by the other tasks taking part in the sync. */\r
+ portMAX_DELAY );/* The maximum time to wait for the sync condition to be met before giving up. */\r
+\r
+ /* A max delay was used, so this task should only exit the above\r
+ function call when the sync condition is met. Check this is the \r
+ case. */\r
configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS );\r
\r
- /* Wait until the 'set bit' task unsuspends this task again. */\r
+ /* Wait until the 'test master' task unsuspends this task again. */\r
vTaskSuspend( NULL );\r
\r
/* Set the bit that indicates this task is at the synchronisation\r
- point again. This time the 'set bit' task has a higher priority than\r
- this task. */\r
- uxReturned = xEventGroupSync( xEventBits, uxSynchronisationBit, ebALL_SYNC_BITS, portMAX_DELAY );\r
+ point again. This time the 'test master' task has a higher priority \r
+ than this task so will get to the sync point before this task. */\r
+ uxReturned = xEventGroupSync( xEventGroup, uxSynchronisationBit, ebALL_SYNC_BITS, portMAX_DELAY );\r
+\r
+ /* Again a max delay was used, so this task should only exit the above\r
+ function call when the sync condition is met. Check this is the \r
+ case. */\r
configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS );\r
\r
/* Block on the event group again. This time the event group is going\r
- to be deleted, so 0 should be returned. */\r
- uxReturned = xEventGroupWaitBits( xEventBits, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY );\r
+ to be deleted while this task is blocked on it so it is expected that 0 \r
+ be returned. */\r
+ uxReturned = xEventGroupWaitBits( xEventGroup, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY );\r
configASSERT( uxReturned == 0 );\r
}\r
}\r
/*-----------------------------------------------------------*/\r
\r
-static void prvWaitBitsTask( void *pvParameters )\r
+static void prvTestSlaveTask( void *pvParameters )\r
{\r
EventBits_t uxReturned;\r
-portBASE_TYPE xError = pdFALSE;\r
+BaseType_t xError = pdFALSE;\r
\r
/* Avoid compiler warnings. */\r
( void ) pvParameters;\r
\r
for( ;; )\r
{\r
- /* This task is controller by the prvSetBitsTask(). Suspend until resumed\r
- by prvSetBitsTask(). */\r
+ /**********************************************************************\r
+ * Part 1: This section is the counterpart to the \r
+ * prvBitCombinationTestMasterFunction() function which is called by the\r
+ * test master task.\r
+ ***********************************************************************\r
+\r
+ /* This task is controller by the 'test master' task (which is \r
+ implemented by prvTestMasterTask()). Suspend until resumed by the \r
+ 'test master' task. */\r
vTaskSuspend( NULL );\r
\r
/* Wait indefinitely for one of the bits in ebCOMBINED_BITS to get\r
set. Clear the bit on exit. */\r
- uxReturned = xEventGroupWaitBits( xEventBits, /* The event bits being queried. */\r
- ebBIT_1, /* The bit to wait for. */\r
- pdTRUE, /* Clear the bit on exit. */\r
- pdTRUE, /* Wait for all the bits (only one in this case anyway. */\r
- portMAX_DELAY );\r
-\r
- /* Should unblock after the 'set bit' task has set all the bits in the\r
- ebCOMBINED_BITS constant, therefore ebCOMBINED_BITS is what should have\r
- been returned. */\r
+ uxReturned = xEventGroupWaitBits( xEventGroup, /* The event group that contains the event bits being queried. */\r
+ ebBIT_1, /* The bit to wait for. */\r
+ pdTRUE, /* Clear the bit on exit. */\r
+ pdTRUE, /* Wait for all the bits (only one in this case anyway). */\r
+ portMAX_DELAY ); /* Block indefinitely to wait for the condition to be met. */\r
+\r
+ /* The 'test master' task set all the bits defined by ebCOMBINED_BITS, \r
+ only one of which was being waited for by this task. The return value\r
+ shows the state of the event bits when the task was unblocked, however\r
+ because the task was waiting for ebBIT_1 and 'clear on exit' was set to \r
+ the current state of the event bits will have ebBIT_1 clear. */\r
if( uxReturned != ebCOMBINED_BITS )\r
{\r
xError = pdTRUE;\r
}\r
\r
- /* Now call xEventGroupWaitBits() again, this time waiting for all the bits\r
- in ebCOMBINED_BITS to be set. This call should block until the 'set\r
- bits' task sets ebBIT_1 - which was the bit cleared in the call to\r
- xEventGroupWaitBits() above. */\r
- uxReturned = xEventGroupWaitBits( xEventBits,\r
- ebCOMBINED_BITS, /* The bits being waited on. */\r
- pdFALSE, /* Don't clear the bits on exit. */\r
- pdTRUE, /* All the bits must be set to unblock. */\r
- portMAX_DELAY );\r
+ /* Now call xEventGroupWaitBits() again, this time waiting for all the \r
+ bits in ebCOMBINED_BITS to be set. This call should block until the \r
+ 'test master' task sets ebBIT_1 - which was the bit cleared in the call \r
+ to xEventGroupWaitBits() above. */\r
+ uxReturned = xEventGroupWaitBits( xEventGroup,\r
+ ebCOMBINED_BITS, /* The bits being waited on. */\r
+ pdFALSE, /* Don't clear the bits on exit. */\r
+ pdTRUE, /* All the bits must be set to unblock. */\r
+ portMAX_DELAY );\r
\r
/* Were all the bits set? */\r
if( ( uxReturned & ebCOMBINED_BITS ) != ebCOMBINED_BITS )\r
xError = pdTRUE;\r
}\r
\r
- /* Suspend again to wait for the 'set bit' task. */\r
+ /* Suspend again to wait for the 'test master' task. */\r
vTaskSuspend( NULL );\r
\r
- /* Now call xEventGroupWaitBits() again, again waiting for all the bits in\r
- ebCOMBINED_BITS to be set, but this time clearing the bits when the task\r
- is unblocked. */\r
- uxReturned = xEventGroupWaitBits( xEventBits,\r
+ /* Now call xEventGroupWaitBits() again, again waiting for all the bits \r
+ in ebCOMBINED_BITS to be set, but this time clearing the bits when the \r
+ task is unblocked. */\r
+ uxReturned = xEventGroupWaitBits( xEventGroup,\r
ebCOMBINED_BITS, /* The bits being waited on. */\r
pdTRUE, /* Clear the bits on exit. */\r
pdTRUE, /* All the bits must be set to unblock. */\r
portMAX_DELAY );\r
\r
-\r
+ /* The 'test master' task set all the bits in the event group, so that \r
+ is the value that should have been returned. The bits defined by\r
+ ebCOMBINED_BITS will have been clear again in the current value though\r
+ as 'clear on exit' was set to pdTRUE. */\r
if( uxReturned != ebALL_BITS )\r
{\r
xError = pdTRUE;\r
}\r
\r
+\r
+\r
+\r
+\r
+ /**********************************************************************\r
+ * Part 2: This section is the counterpart to the \r
+ * prvPerformTaskSyncTests() function which is called by the\r
+ * test master task.\r
+ ***********************************************************************\r
+\r
+\r
+ /* Once again wait for the 'test master' task to unsuspend this task \r
+ when it is time for the next test. */\r
vTaskSuspend( NULL );\r
\r
- /* Now to synchronise with when 'set bit' task has the lowest\r
- priority. */\r
- uxReturned = xEventGroupSync( xEventBits, ebWAIT_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );\r
+ /* Now peform a synchronisation with all the other tasks. At this point\r
+ the 'test master' task has the lowest priority so will get to the sync \r
+ point after all the other synchronising tasks. */\r
+ uxReturned = xEventGroupSync( xEventGroup, /* The event group used for the sync. */\r
+ ebWAIT_BIT_TASK_SYNC_BIT, /* The bit in the event group used to indicate this task is at the sync point. */\r
+ ebALL_SYNC_BITS, /* The bits to wait for. These bits are set by the other tasks taking part in the sync. */\r
+ portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met before giving up. */\r
\r
/* A sync with a max delay should only exit when all the synchronisation\r
bits are set... */\r
xError = pdTRUE;\r
}\r
\r
- /* ...but now the synchronisation bits should be clear again. */\r
- if( xEventGroupSetBits( xEventBits, 0x00 ) != 0 )\r
+ /* ...but now the synchronisation bits should be clear again. Read back\r
+ the current value of the bits within the event group to check that is\r
+ the case. Setting the bits to zero will return the bits previous value\r
+ then leave all the bits clear. */\r
+ if( xEventGroupSetBits( xEventGroup, 0x00 ) != 0 )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
+\r
+ /* Check the bits are indeed 0 now by simply reading then. */\r
+ if( xEventGroupGetBits( xEventGroup ) != 0 )\r
{\r
xError = pdTRUE;\r
}\r
if( xError == pdFALSE )\r
{\r
/* This task is still cycling without finding an error. */\r
- ulWaitBitCycles++;\r
+ ulTestSlaveCycles++;\r
}\r
\r
vTaskSuspend( NULL );\r
\r
- /* This time sync when the 'set bit' task has the highest priority\r
- at the point where it sets its sync bit. */\r
- uxReturned = xEventGroupSync( xEventBits, ebWAIT_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );\r
+ /* This time sync when the 'test master' task has the highest priority\r
+ at the point where it sets its sync bit - so this time the 'test master' \r
+ task will get to the sync point before this task. */\r
+ uxReturned = xEventGroupSync( xEventGroup, ebWAIT_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );\r
\r
/* A sync with a max delay should only exit when all the synchronisation\r
bits are set... */\r
}\r
\r
/* ...but now the sync bits should be clear again. */\r
- if( xEventGroupSetBits( xEventBits, 0x00 ) != 0 )\r
+ if( xEventGroupSetBits( xEventGroup, 0x00 ) != 0 )\r
{\r
xError = pdTRUE;\r
}\r
\r
/* Block on the event group again. This time the event group is going\r
- to be deleted, so 0 should be returned. */\r
- uxReturned = xEventGroupWaitBits( xEventBits, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY );\r
+ to be deleted while this task is blocked on it, so it is expected that 0 \r
+ will be returned. */\r
+ uxReturned = xEventGroupWaitBits( xEventGroup, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY );\r
\r
if( uxReturned != 0 )\r
{\r
if( xError == pdFALSE )\r
{\r
/* This task is still cycling without finding an error. */\r
- ulWaitBitCycles++;\r
+ ulTestSlaveCycles++;\r
}\r
\r
configASSERT( xError == pdFALSE );\r
}\r
/*-----------------------------------------------------------*/\r
\r
-static void prvSetBitsTask( void *pvParameters )\r
+static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle )\r
{\r
EventBits_t uxBits;\r
-portBASE_TYPE xError;\r
-\r
-/* The handle to the other task is passed in as the task parameter. */\r
-xTaskHandle xWaitBitsTaskHandle = ( xTaskHandle ) pvParameters;\r
-\r
- /* Avoid compiler warnings. */\r
- ( void ) pvParameters;\r
\r
- /* Create the event group ready for the initial tests. */\r
- xEventBits = xEventGroupCreate();\r
- configASSERT( xEventBits );\r
-\r
- /* Perform the tests that block two tasks on different combinations of bits, \r
- then set each bit in turn and check the correct tasks unblock at the correct \r
- times. */\r
- xError = prvTestSelectiveBits();\r
-\r
- for( ;; )\r
+ /* The three tasks that take part in the synchronisation (rendezvous) are\r
+ expected to be in the suspended state at the start of the test. */\r
+ if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )\r
{\r
- /* Recreate the event group ready for the next cycle. */\r
- xEventBits = xEventGroupCreate();\r
- configASSERT( xEventBits );\r
-\r
- /* Resume the other task. It will block, pending a single bit from\r
- within ebCOMBINED_BITS. */\r
- vTaskResume( xWaitBitsTaskHandle );\r
-\r
- /* Ensure the other task is blocked on the task. */\r
- if( eTaskGetState( xWaitBitsTaskHandle ) != eBlocked )\r
- {\r
- xError = pdTRUE;\r
- }\r
-\r
- /* Set all the bits in ebCOMBINED_BITS - the 'wait bits' task is only\r
- blocked waiting for one of them. */\r
- xEventGroupSetBits( xEventBits, ebCOMBINED_BITS );\r
-\r
- /* The 'wait bits' task should now have executed, clearing ebBIT_1 (the\r
- bit it was blocked on), then re-entered the Blocked state to wait for\r
- all the other bits in ebCOMBINED_BITS to be set again. First check\r
- ebBIT_1 is clear. */\r
- uxBits = xEventGroupWaitBits( xEventBits, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );\r
-\r
- if( uxBits != ( ebCOMBINED_BITS & ~ebBIT_1 ) )\r
- {\r
- xError = pdTRUE;\r
- }\r
-\r
- /* Ensure the other task is still in the blocked state. */\r
- if( eTaskGetState( xWaitBitsTaskHandle ) != eBlocked )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ xError = pdTRUE;\r
+ }\r
\r
- /* Set all the bits other than ebBIT_1 - which is the bit that must be\r
- set before the other task unblocks. */\r
- xEventGroupSetBits( xEventBits, ebALL_BITS & ~ebBIT_1 );\r
+ if( eTaskGetState( xSyncTask1 ) != eSuspended )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- /* Ensure all the expected bits are still set. */\r
- uxBits = xEventGroupWaitBits( xEventBits, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );\r
+ if( eTaskGetState( xSyncTask2 ) != eSuspended )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- if( uxBits != ( ebALL_BITS & ~ebBIT_1 ) )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ /* Unsuspend the other tasks then check they have executed up to the\r
+ synchronisation point. */\r
+ vTaskResume( xTestSlaveTaskHandle );\r
+ vTaskResume( xSyncTask1 );\r
+ vTaskResume( xSyncTask2 );\r
\r
- /* Ensure the other task is still in the blocked state. */\r
- if( eTaskGetState( xWaitBitsTaskHandle ) != eBlocked )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- /* Now also set ebBIT_1, which should unblock the other task, which will\r
- then suspend itself. */\r
- xEventGroupSetBits( xEventBits, ebBIT_1 );\r
+ if( eTaskGetState( xSyncTask1 ) != eBlocked )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- /* Ensure the other task is suspended. */\r
- if( eTaskGetState( xWaitBitsTaskHandle ) != eSuspended )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ if( eTaskGetState( xSyncTask2 ) != eBlocked )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- /* The other task should not have cleared the bits - so all the bits\r
- should still be set. */\r
- if( xEventGroupSetBits( xEventBits, 0x00 ) != ebALL_BITS )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ /* Set this task's sync bit. */\r
+ uxBits = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */\r
+ ebSET_BIT_TASK_SYNC_BIT,/* The bit set by this task when it reaches the sync point. */\r
+ ebALL_SYNC_BITS, /* The bits to wait for - these bits are set by the other tasks that take part in the sync. */\r
+ portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met. */\r
\r
- /* Clear ebBIT_1 again. */\r
- if( xEventGroupClearBits( xEventBits, ebBIT_1 ) != ebALL_BITS )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ /* A sync with a max delay should only exit when all the synchronise\r
+ bits are set...check that is the case. */\r
+ if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- /* Resume the other task - which will wait on all the ebCOMBINED_BITS\r
- again - this time clearing the bits when it is unblocked. */\r
- vTaskResume( xWaitBitsTaskHandle );\r
+ /* ...but now the sync bits should be clear again. */\r
+ if( xEventGroupGetBits( xEventGroup ) != 0 )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- /* Ensure the other task is blocked once again. */\r
- if( eTaskGetState( xWaitBitsTaskHandle ) != eBlocked )\r
- {\r
- xError = pdTRUE;\r
- }\r
\r
- /* Set the bit the other task is waiting for. */\r
- xEventGroupSetBits( xEventBits, ebBIT_1 );\r
+ /* The other tasks should now all be suspended again, ready for the next\r
+ synchronisation. */\r
+ if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- /* Ensure the other task is suspended once again. */\r
- if( eTaskGetState( xWaitBitsTaskHandle ) != eSuspended )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ if( eTaskGetState( xSyncTask1 ) != eSuspended )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- /* The other task should have cleared the bits in ebCOMBINED_BITS.\r
- Clear the remaining bits. */\r
- uxBits = xEventGroupWaitBits( xEventBits, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );\r
+ if( eTaskGetState( xSyncTask2 ) != eSuspended )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- if( uxBits != ( ebALL_BITS & ~ebCOMBINED_BITS ) )\r
- {\r
- xError = pdTRUE;\r
- }\r
\r
- /* Clear all bits ready for the sync with the other three tasks. The\r
- value returned is the value prior to the bits being cleared. */\r
- if( xEventGroupClearBits( xEventBits, ebALL_BITS ) != ( ebALL_BITS & ~ebCOMBINED_BITS ) )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ /* Sync again - but this time set the last necessary bit as the\r
+ highest priority task, rather than the lowest priority task. Unsuspend\r
+ the other tasks then check they have executed up to the synchronisation\r
+ point. */\r
+ vTaskResume( xTestSlaveTaskHandle );\r
+ vTaskResume( xSyncTask1 );\r
+ vTaskResume( xSyncTask2 );\r
\r
- /* The bits should be clear now. */\r
- if( xEventGroupGetBits( xEventBits ) != 0x00 )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- /* Check the other three tasks are suspended. */\r
- if( eTaskGetState( xWaitBitsTaskHandle ) != eSuspended )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ if( eTaskGetState( xSyncTask1 ) != eBlocked )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- if( eTaskGetState( xSyncTask1 ) != eSuspended )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ if( eTaskGetState( xSyncTask2 ) != eBlocked )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- if( eTaskGetState( xSyncTask2 ) != eSuspended )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ /* Raise the priority of this task above that of the other tasks. */\r
+ vTaskPrioritySet( NULL, ebWAIT_BIT_TASK_PRIORITY + 1 );\r
\r
- /* Unsuspend the other tasks then check they have executed up to the\r
- synchronisation point. */\r
- vTaskResume( xWaitBitsTaskHandle );\r
- vTaskResume( xSyncTask1 );\r
- vTaskResume( xSyncTask2 );\r
+ /* Set this task's sync bit. */\r
+ uxBits = xEventGroupSync( xEventGroup, ebSET_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );\r
\r
- if( eTaskGetState( xWaitBitsTaskHandle ) != eBlocked )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ /* A sync with a max delay should only exit when all the synchronisation\r
+ bits are set... */\r
+ if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- if( eTaskGetState( xSyncTask1 ) != eBlocked )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ /* ...but now the sync bits should be clear again. */\r
+ if( xEventGroupGetBits( xEventGroup ) != 0 )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- if( eTaskGetState( xSyncTask2 ) != eBlocked )\r
- {\r
- xError = pdTRUE;\r
- }\r
\r
- /* Set this task's sync bit. */\r
- uxBits = xEventGroupSync( xEventBits, ebSET_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );\r
+ /* The other tasks should now all be in the ready state again, but not\r
+ executed yet as this task still has a higher relative priority. */\r
+ if( eTaskGetState( xTestSlaveTaskHandle ) != eReady )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- /* A sync with a max delay should only exit when all the synchronise\r
- bits are set... */\r
- if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ if( eTaskGetState( xSyncTask1 ) != eReady )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- /* ...but now the sync bits should be clear again. */\r
- if( xEventGroupSetBits( xEventBits, 0x00 ) != 0 )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ if( eTaskGetState( xSyncTask2 ) != eReady )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
\r
- /* The other tasks should now all be suspended again, ready for the next\r
- synchronisation. */\r
- if( eTaskGetState( xWaitBitsTaskHandle ) != eSuspended )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ /* Reset the priority of this task back to its original value. */\r
+ vTaskPrioritySet( NULL, ebSET_BIT_TASK_PRIORITY );\r
\r
- if( eTaskGetState( xSyncTask1 ) != eSuspended )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ /* Now all the other tasks should have reblocked on the event bits\r
+ to test the behaviour when the event bits are deleted. */\r
+ if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- if( eTaskGetState( xSyncTask2 ) != eSuspended )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ if( eTaskGetState( xSyncTask1 ) != eBlocked )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
+ if( eTaskGetState( xSyncTask2 ) != eBlocked )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- /* Sync again - but this time set the last necessary bit as the\r
- highest priority task, rather than the lowest priority task. Unsuspend\r
- the other tasks then check they have executed up to the synchronisation\r
- point. */\r
- vTaskResume( xWaitBitsTaskHandle );\r
- vTaskResume( xSyncTask1 );\r
- vTaskResume( xSyncTask2 );\r
+ return xError;\r
+}\r
+/*-----------------------------------------------------------*/\r
\r
- if( eTaskGetState( xWaitBitsTaskHandle ) != eBlocked )\r
- {\r
- xError = pdTRUE;\r
- }\r
+static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle )\r
+{\r
+EventBits_t uxBits;\r
\r
- if( eTaskGetState( xSyncTask1 ) != eBlocked )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ /* Resume the other task. It will block, pending a single bit from\r
+ within ebCOMBINED_BITS. */\r
+ vTaskResume( xTestSlaveTaskHandle );\r
\r
- if( eTaskGetState( xSyncTask2 ) != eBlocked )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ /* Ensure the other task is blocked on the task. */\r
+ if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- /* Raise the priority of this task above that of the other tasks. */\r
- vTaskPrioritySet( NULL, ebWAIT_BIT_TASK_PRIORITY + 1 );\r
+ /* Set all the bits in ebCOMBINED_BITS - the 'test slave' task is only\r
+ blocked waiting for one of them. */\r
+ xEventGroupSetBits( xEventGroup, ebCOMBINED_BITS );\r
\r
- /* Set this task's sync bit. */\r
- uxBits = xEventGroupSync( xEventBits, ebSET_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );\r
+ /* The 'test slave' task should now have executed, clearing ebBIT_1 (the\r
+ bit it was blocked on), then re-entered the Blocked state to wait for\r
+ all the other bits in ebCOMBINED_BITS to be set again. First check\r
+ ebBIT_1 is clear. */\r
+ uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );\r
\r
- /* A sync with a max delay should only exit when all the synchronisation\r
- bits are set... */\r
- if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ if( uxBits != ( ebCOMBINED_BITS & ~ebBIT_1 ) )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- /* ...but now the sync bits should be clear again. */\r
- if( xEventGroupSetBits( xEventBits, 0x00 ) != 0 )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ /* Ensure the other task is still in the blocked state. */\r
+ if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
+ /* Set all the bits other than ebBIT_1 - which is the bit that must be\r
+ set before the other task unblocks. */\r
+ xEventGroupSetBits( xEventGroup, ebALL_BITS & ~ebBIT_1 );\r
\r
- /* The other tasks should now all be in the ready state again, but not\r
- executed yet as this task still has a higher relative priority. */\r
- if( eTaskGetState( xWaitBitsTaskHandle ) != eReady )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ /* Ensure all the expected bits are still set. */\r
+ uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );\r
\r
- if( eTaskGetState( xSyncTask1 ) != eReady )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ if( uxBits != ( ebALL_BITS & ~ebBIT_1 ) )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- if( eTaskGetState( xSyncTask2 ) != eReady )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ /* Ensure the other task is still in the blocked state. */\r
+ if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
+ /* Now also set ebBIT_1, which should unblock the other task, which will\r
+ then suspend itself. */\r
+ xEventGroupSetBits( xEventGroup, ebBIT_1 );\r
\r
- /* Reset the priority of this task back to its original value. */\r
- vTaskPrioritySet( NULL, ebSET_BIT_TASK_PRIORITY );\r
+ /* Ensure the other task is suspended. */\r
+ if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- /* Now all the other tasks should have reblocked on the event bits\r
- to test the behaviour when the event bits are deleted. */\r
- if( eTaskGetState( xWaitBitsTaskHandle ) != eBlocked )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ /* The other task should not have cleared the bits - so all the bits\r
+ should still be set. */\r
+ if( xEventGroupSetBits( xEventGroup, 0x00 ) != ebALL_BITS )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- if( eTaskGetState( xSyncTask1 ) != eBlocked )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ /* Clear ebBIT_1 again. */\r
+ if( xEventGroupClearBits( xEventGroup, ebBIT_1 ) != ebALL_BITS )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- if( eTaskGetState( xSyncTask2 ) != eBlocked )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ /* Resume the other task - which will wait on all the ebCOMBINED_BITS\r
+ again - this time clearing the bits when it is unblocked. */\r
+ vTaskResume( xTestSlaveTaskHandle );\r
\r
- /* Delete the event group. */\r
- vEventGroupDelete( xEventBits );\r
+ /* Ensure the other task is blocked once again. */\r
+ if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- /* Now all the other tasks should have completed and suspended\r
- themselves ready for the next go around the loop. */\r
- if( eTaskGetState( xWaitBitsTaskHandle ) != eSuspended )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ /* Set the bit the other task is waiting for. */\r
+ xEventGroupSetBits( xEventGroup, ebBIT_1 );\r
\r
- if( eTaskGetState( xSyncTask1 ) != eSuspended )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ /* Ensure the other task is suspended once again. */\r
+ if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- if( eTaskGetState( xSyncTask2 ) != eSuspended )\r
- {\r
- xError = pdTRUE;\r
- }\r
+ /* The other task should have cleared the bits in ebCOMBINED_BITS.\r
+ Clear the remaining bits. */\r
+ uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );\r
\r
+ if( uxBits != ( ebALL_BITS & ~ebCOMBINED_BITS ) )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- if( xError == pdFALSE )\r
- {\r
- ulSetBitCycles++;\r
- }\r
+ /* Clear all bits ready for the sync with the other three tasks. The\r
+ value returned is the value prior to the bits being cleared. */\r
+ if( xEventGroupClearBits( xEventGroup, ebALL_BITS ) != ( ebALL_BITS & ~ebCOMBINED_BITS ) )\r
+ {\r
+ xError = pdTRUE;\r
+ }\r
\r
- configASSERT( xError == pdFALSE );\r
+ /* The bits should be clear now. */\r
+ if( xEventGroupGetBits( xEventGroup ) != 0x00 )\r
+ {\r
+ xError = pdTRUE;\r
}\r
+\r
+ return xError;\r
}\r
/*-----------------------------------------------------------*/\r
\r
-static void prvPreSyncSelectiveWakeTest( void )\r
+static void prvSelectiveBitsTestSlaveFunction( void )\r
{\r
EventBits_t uxPendBits, uxReturned;\r
\r
+ /* Used in a test that blocks two tasks on various different bits within an \r
+ event group - then sets each bit in turn and checks that the correct tasks \r
+ unblock at the correct times.\r
+\r
+ This function is called by two different tasks - each of which will use a\r
+ different bit. Check the task handle to see which task the function was\r
+ called by. */\r
if( xTaskGetCurrentTaskHandle() == xSyncTask1 )\r
{\r
uxPendBits = ebSELECTIVE_BITS_1;\r
\r
for( ;; )\r
{\r
+ /* Wait until it is time to perform the next cycle of the test. The\r
+ task is unsuspended by the tests implemented in the \r
+ prvSelectiveBitsTestMasterFunction() function. */\r
vTaskSuspend( NULL );\r
- uxReturned = xEventGroupWaitBits( xEventBits, uxPendBits, pdTRUE, pdFALSE, portMAX_DELAY );\r
+ uxReturned = xEventGroupWaitBits( xEventGroup, uxPendBits, pdTRUE, pdFALSE, portMAX_DELAY );\r
\r
if( uxReturned == ( EventBits_t ) 0 )\r
{\r
}\r
/*-----------------------------------------------------------*/\r
\r
-static portBASE_TYPE prvTestSelectiveBits( void )\r
+static BaseType_t prvSelectiveBitsTestMasterFunction( void )\r
{\r
-portBASE_TYPE xError = pdFALSE;\r
+BaseType_t xError = pdFALSE;\r
EventBits_t uxBit;\r
\r
- /* Both tasks should start in the suspended state. */\r
+ /* Used in a test that blocks two tasks on various different bits within an \r
+ event group - then sets each bit in turn and checks that the correct tasks \r
+ unblock at the correct times. The two other tasks (xSyncTask1 and \r
+ xSyncTask2) call prvSelectiveBitsTestSlaveFunction() to perform their parts in\r
+ this test.\r
+\r
+ Both other tasks should start in the suspended state. */\r
if( eTaskGetState( xSyncTask1 ) != eSuspended )\r
{\r
xError = pdTRUE;\r
}\r
\r
/* Set one bit. */\r
- xEventGroupSetBits( xEventBits, uxBit );\r
+ xEventGroupSetBits( xEventGroup, uxBit );\r
\r
/* Is the bit set in the first set of selective bits? If so the first\r
sync task should have unblocked and returned to the suspended state. */\r
vTaskResume( xSyncTask1 );\r
vTaskResume( xSyncTask2 );\r
\r
- vEventGroupDelete( xEventBits );\r
+ /* Deleting the event group is the signal that the two other tasks should\r
+ leave the prvSelectiveBitsTestSlaveFunction() function and continue to the main\r
+ part of their functionality. */\r
+ vEventGroupDelete( xEventGroup );\r
\r
return xError;\r
}\r
/*-----------------------------------------------------------*/\r
\r
+void vPeriodicEventGroupsProcessing( void )\r
+{\r
+static BaseType_t xCallCount = 0, xISRTestError = pdFALSE;\r
+const BaseType_t xSetBitCount = 100, xGetBitsCount = 200, xClearBitsCount = 300;\r
+const EventBits_t uxBitsToSet = 0x12U;\r
+EventBits_t uxReturned;\r
+BaseType_t xMessagePosted;\r
+\r
+ /* Called periodically from the tick hook to exercise the "FromISR" \r
+ functions. */\r
+\r
+ xCallCount++;\r
+\r
+ if( xCallCount == xSetBitCount )\r
+ {\r
+ /* All the event bits should start clear. */\r
+ uxReturned = xEventGroupGetBitsFromISR( xISREventGroup );\r
+ if( uxReturned != 0x00 )\r
+ {\r
+ xISRTestError = pdTRUE;\r
+ }\r
+ else\r
+ {\r
+ /* Set the bits. This is called from the tick hook so it is not\r
+ necessary to use the last parameter to ensure a context switch\r
+ occurs immediately. */\r
+ xMessagePosted = xEventGroupSetBitsFromISR( xISREventGroup, uxBitsToSet, NULL );\r
+ if( xMessagePosted != pdPASS )\r
+ {\r
+ xISRTestError = pdTRUE;\r
+ }\r
+ }\r
+ }\r
+ else if( xCallCount == xGetBitsCount )\r
+ {\r
+ /* Check the bits were set as expected. */\r
+ uxReturned = xEventGroupGetBitsFromISR( xISREventGroup );\r
+ if( uxReturned != uxBitsToSet )\r
+ {\r
+ xISRTestError = pdTRUE;\r
+ }\r
+ }\r
+ else if( xCallCount == xClearBitsCount )\r
+ {\r
+ /* Clear the bits again. */\r
+ uxReturned = xEventGroupClearBitsFromISR( xISREventGroup, uxBitsToSet );\r
+\r
+ /* The returned value should be the value before the bits were cleaed.*/\r
+ if( uxReturned != uxBitsToSet )\r
+ {\r
+ xISRTestError = pdTRUE;\r
+ }\r
+\r
+ /* Go back to the start. */\r
+ xCallCount = 0;\r
+\r
+ /* If no errors have been detected then increment the count of test\r
+ cycles. */\r
+ if( xISRTestError == pdFALSE )\r
+ {\r
+ ulISRCycles++;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Nothing else to do. */\r
+ }\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
/* This is called to check that all the created tasks are still running. */\r
-portBASE_TYPE xAreEventGroupTasksStillRunning( void )\r
+BaseType_t xAreEventGroupTasksStillRunning( void )\r
{\r
-static unsigned long ulPreviousWaitBitCycles = 0, ulPreviousSetBitCycles = 0;\r
-portBASE_TYPE xStatus = pdPASS;\r
+static unsigned long ulPreviousWaitBitCycles = 0, ulPreviousSetBitCycles = 0, ulPreviousISRCycles = 0;\r
+BaseType_t xStatus = pdPASS;\r
\r
/* Check the tasks are still cycling without finding any errors. */\r
- if( ulPreviousSetBitCycles == ulSetBitCycles )\r
+ if( ulPreviousSetBitCycles == ulTestMasterCycles )\r
+ {\r
+ xStatus = pdFAIL;\r
+ }\r
+ ulPreviousSetBitCycles = ulTestMasterCycles;\r
+\r
+ if( ulPreviousWaitBitCycles == ulTestSlaveCycles )\r
{\r
xStatus = pdFAIL;\r
}\r
- ulPreviousSetBitCycles = ulSetBitCycles;\r
+ ulPreviousWaitBitCycles = ulTestSlaveCycles;\r
\r
- if( ulPreviousWaitBitCycles == ulWaitBitCycles )\r
+ if( ulPreviousISRCycles == ulISRCycles )\r
{\r
xStatus = pdFAIL;\r
}\r
- ulPreviousWaitBitCycles = ulWaitBitCycles;\r
+ ulPreviousISRCycles = ulISRCycles;\r
\r
return xStatus;\r
}\r