]> git.sur5r.net Git - freertos/commitdiff
Add additional event group tests - and update implementation as required by test...
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Fri, 22 Nov 2013 10:58:25 +0000 (10:58 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Fri, 22 Nov 2013 10:58:25 +0000 (10:58 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2114 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

FreeRTOS/Demo/Common/Minimal/EventGroupsDemo.c
FreeRTOS/Demo/WIN32-MSVC/FreeRTOSConfig.h
FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj
FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj.filters
FreeRTOS/Demo/WIN32-MSVC/main_full.c
FreeRTOS/Source/event_groups.c

index abbf0699183dc71ef13d0444baa235223dbba8d4..b7365e09190a9e5c063f51045684b6f118c372ab 100644 (file)
@@ -110,6 +110,11 @@ that synchronise with the xEventGroupSync() function. */
 /* A 5ms delay. */\r
 #define ebSHORT_DELAY  ( 5 / portTICK_RATE_MS )\r
 \r
+/* Used in the selective bits test which checks no, one or both tasks blocked on\r
+event bits in a group are unblocked as appropriate as different bits get set. */\r
+#define ebSELECTIVE_BITS_1             0x03\r
+#define ebSELECTIVE_BITS_2             0x05\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /*\r
@@ -137,6 +142,14 @@ static void prvSyncTask( void *pvParameters );
  */\r
 static portBASE_TYPE prvSingleTaskTests( void );\r
 \r
+/*\r
+ * Functions used in a test that blocks two tasks on various different bits\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
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /* Variables that are incremented by the tasks on each cycle provided no errors\r
@@ -151,7 +164,7 @@ static xTaskHandle xSyncTask1 = NULL, xSyncTask2 = NULL;
 \r
 /*-----------------------------------------------------------*/\r
 \r
-void vStartEventBitTasks( void )\r
+void vStartEventGroupTasks( void )\r
 {\r
 xTaskHandle xWaitBitsTaskHandle;\r
 \r
@@ -161,10 +174,6 @@ xTaskHandle xWaitBitsTaskHandle;
         * event groups API.\r
         */\r
 \r
-       /* Create the event bits that will be used by the tasks. */\r
-       xEventBits = xEventGroupCreate();\r
-       configASSERT( xEventBits );\r
-\r
        xTaskCreate( prvWaitBitsTask, ( signed char * ) "WaitO", configMINIMAL_STACK_SIZE, NULL, ebWAIT_BIT_TASK_PRIORITY, &xWaitBitsTaskHandle );\r
        xTaskCreate( prvSetBitsTask, ( signed char * ) "SetB", configMINIMAL_STACK_SIZE, ( void * ) xWaitBitsTaskHandle, ebSET_BIT_TASK_PRIORITY, NULL );\r
        xTaskCreate( prvSyncTask, ( signed char * ) "Rndv", configMINIMAL_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_1_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask1 );\r
@@ -373,6 +382,9 @@ xEventBitsType uxSynchronisationBit, uxReturned;
        passed in as the task parameter. */\r
        uxSynchronisationBit = ( xEventBitsType ) 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
@@ -540,10 +552,27 @@ xTaskHandle xWaitBitsTaskHandle = ( xTaskHandle ) pvParameters;
        /* 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 only require a single task. */\r
        xError = prvSingleTaskTests();\r
 \r
+       if( xError == pdFALSE )\r
+       {\r
+               /* Perform the tests that block two tasks on different combinations of\r
+               bits, then set each bit in turn and check the correct tasks unblock at\r
+               the correct times. */\r
+               xError = prvTestSelectiveBits();\r
+       }\r
+\r
        for( ;; )\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
@@ -831,10 +860,6 @@ xTaskHandle xWaitBitsTaskHandle = ( xTaskHandle ) pvParameters;
                }\r
 \r
 \r
-               /* Recreate the event group ready for the next cycle. */\r
-               xEventBits = xEventGroupCreate();\r
-               configASSERT( xEventBits );\r
-\r
                if( xError == pdFALSE )\r
                {\r
                        ulSetBitCycles++;\r
@@ -845,8 +870,120 @@ xTaskHandle xWaitBitsTaskHandle = ( xTaskHandle ) pvParameters;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+static void prvPreSyncSelectiveWakeTest( void )\r
+{\r
+xEventBitsType uxPendBits, uxReturned;\r
+\r
+       if( xTaskGetCurrentTaskHandle() == xSyncTask1 )\r
+       {\r
+               uxPendBits = ebSELECTIVE_BITS_1;\r
+       }\r
+       else\r
+       {\r
+               uxPendBits = ebSELECTIVE_BITS_2;\r
+       }\r
+\r
+       for( ;; )\r
+       {\r
+               vTaskSuspend( NULL );\r
+               uxReturned = xEventGroupWaitBits( xEventBits, uxPendBits, pdTRUE, pdFALSE, portMAX_DELAY );\r
+\r
+               if( uxReturned == ( xEventBitsType ) 0 )\r
+               {\r
+                       break;\r
+               }\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portBASE_TYPE prvTestSelectiveBits( void )\r
+{\r
+portBASE_TYPE xError = pdFALSE;\r
+xEventBitsType uxBit;\r
+\r
+       /* Both tasks should start in the suspended state. */\r
+       if( eTaskGetState( xSyncTask1 ) != eSuspended )\r
+       {\r
+               xError = pdTRUE;\r
+       }\r
+\r
+       if( eTaskGetState( xSyncTask2 ) != eSuspended )\r
+       {\r
+               xError = pdTRUE;\r
+       }\r
+\r
+       /* Test each bit in the byte individually. */\r
+       for( uxBit = 0x01; uxBit < 0x100; uxBit <<= 1 )\r
+       {\r
+               /* Resume both tasks. */\r
+               vTaskResume( xSyncTask1 );\r
+               vTaskResume( xSyncTask2 );\r
+\r
+               /* Now both tasks should be blocked on the event group. */\r
+               if( eTaskGetState( xSyncTask1 ) != eBlocked )\r
+               {\r
+                       xError = pdTRUE;\r
+               }\r
+\r
+               if( eTaskGetState( xSyncTask2 ) != eBlocked )\r
+               {\r
+                       xError = pdTRUE;\r
+               }\r
+\r
+               /* Set one bit. */\r
+               xEventGroupSetBits( xEventBits, 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
+               if( ( uxBit & ebSELECTIVE_BITS_1 ) == 0 )\r
+               {\r
+                       /* Task should not have unblocked. */\r
+                       if( eTaskGetState( xSyncTask1 ) != eBlocked )\r
+                       {\r
+                               xError = pdTRUE;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       /* Task should have unblocked and returned to the suspended state. */\r
+                       if( eTaskGetState( xSyncTask1 ) != eSuspended )\r
+                       {\r
+                               xError = pdTRUE;\r
+                       }\r
+               }\r
+\r
+               /* Same checks for the second sync task. */\r
+               if( ( uxBit & ebSELECTIVE_BITS_2 ) == 0 )\r
+               {\r
+                       /* Task should not have unblocked. */\r
+                       if( eTaskGetState( xSyncTask2 ) != eBlocked )\r
+                       {\r
+                               xError = pdTRUE;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       /* Task should have unblocked and returned to the suspended state. */\r
+                       if( eTaskGetState( xSyncTask2 ) != eSuspended )\r
+                       {\r
+                               xError = pdTRUE;\r
+                       }\r
+               }\r
+       }\r
+\r
+       /* Ensure both tasks are blocked on the event group again, then delete the\r
+       event group so the other tasks leave this portion of the test. */\r
+       vTaskResume( xSyncTask1 );\r
+       vTaskResume( xSyncTask2 );\r
+\r
+       vEventGroupDelete( xEventBits );\r
+\r
+       return xError;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
 /* This is called to check that all the created tasks are still running. */\r
-portBASE_TYPE xAreEventBitTasksStillRunning( void )\r
+portBASE_TYPE xAreEventGroupTasksStillRunning( void )\r
 {\r
 static unsigned long ulPreviousWaitBitCycles = 0, ulPreviousSetBitCycles = 0;\r
 portBASE_TYPE xStatus = pdPASS;\r
index 27aad4219da7bb37ccdd19e935599aa080e25ab7..b5e49564c8746f2360d4ef96c6494eb6681b2382 100644 (file)
@@ -132,6 +132,7 @@ to exclude the API function. */
 #define INCLUDE_pcTaskGetTaskName                              1\r
 #define INCLUDE_eTaskGetState                                  1\r
 #define INCLUDE_xSemaphoreGetMutexHolder               1\r
+#define INCLUDE_xTimerPendCallbackFromISR              1\r
 \r
 /* Standard assert semantics. */\r
 extern void vAssertCalled( unsigned long ulLine, const char * const pcFileName );\r
index 8d25ac5fd81307eeb097ba383a0fafd22ea68546..c5b25c845c049b5bbf3c12ef114c04ec484b41f4 100644 (file)
     <ClCompile Include="..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-Trace\trcKernelPort.c" />\r
     <ClCompile Include="..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-Trace\trcUser.c" />\r
     <ClCompile Include="..\..\Source\croutine.c" />\r
+    <ClCompile Include="..\..\Source\event_groups.c" />\r
     <ClCompile Include="..\..\Source\portable\MemMang\heap_4.c" />\r
     <ClCompile Include="..\..\Source\timers.c" />\r
     <ClCompile Include="..\Common\Minimal\BlockQ.c" />\r
     <ClCompile Include="..\Common\Minimal\countsem.c" />\r
     <ClCompile Include="..\Common\Minimal\death.c" />\r
     <ClCompile Include="..\Common\Minimal\dynamic.c" />\r
+    <ClCompile Include="..\Common\Minimal\EventGroupsDemo.c" />\r
     <ClCompile Include="..\Common\Minimal\flop.c" />\r
     <ClCompile Include="..\Common\Minimal\GenQTest.c" />\r
     <ClCompile Include="..\Common\Minimal\integer.c" />\r
index e4e21ab207309571565611c0aa5d88f05a8c115e..b897c343bebd03265cdbb5c553722b78cffc64dd 100644 (file)
     <ClCompile Include="main_blinky.c">\r
       <Filter>Demo App Source</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\Common\Minimal\EventGroupsDemo.c">\r
+      <Filter>Demo App Source\Common Demo Tasks</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\Source\event_groups.c">\r
+      <Filter>FreeRTOS Source\Source</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="FreeRTOSConfig.h">\r
index 654de2ad0c35db1fe6f1d1df5899692c4f507521..62600fee46e163fce5e0159ee41ab64099101268 100644 (file)
 #include "dynamic.h"\r
 #include "QueueSet.h"\r
 #include "QueueOverwrite.h"\r
+#include "EventGroupsDemo.h"\r
 \r
 /* Priorities at which the tasks are created. */\r
 #define mainCHECK_TASK_PRIORITY                        ( configMAX_PRIORITIES - 1 )\r
@@ -196,6 +197,7 @@ int main_full( void )
        vStartQueueSetTasks();\r
        vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY );       \r
        xTaskCreate( prvDemoQueueSpaceFunctions, ( signed char * ) "QSpace", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
+       vStartEventGroupTasks();\r
 \r
        #if( configUSE_PREEMPTION != 0  )\r
        {\r
@@ -250,7 +252,11 @@ const portTickType xCycleFrequency = 2500 / portTICK_RATE_MS;
                }\r
                #endif\r
 \r
-           if( xAreIntegerMathsTaskStillRunning() != pdTRUE )\r
+               if( xAreEventGroupTasksStillRunning() != pdTRUE )\r
+               {\r
+                       pcStatusMessage = "Error: EventGroup";\r
+               }\r
+           else if( xAreIntegerMathsTaskStillRunning() != pdTRUE )\r
            {\r
                        pcStatusMessage = "Error: IntMath";\r
            }   \r
index eb186c191b143ae6b49059acb33458561fc91af1..a49d0a1f65e4ecc9bb4188d2ef6979105d163bae 100644 (file)
@@ -93,15 +93,15 @@ privileged Vs unprivileged linkage and placement. */
 \r
 \r
 #if configUSE_16_BIT_TICKS == 1\r
-       #define taskCLEAR_EVENTS_ON_EXIT_BIT            0x0100U\r
-       #define taskUNBLOCKED_DUE_TO_BIT_SET_BIT        0x0200U\r
-       #define taskWAIT_FOR_ALL_BITS                           0x0400U\r
-       #define taskEVENT_BITS_CONTROL_BYTES            0xff00U\r
+       #define taskCLEAR_EVENTS_ON_EXIT_BIT    0x0100U\r
+       #define taskUNBLOCKED_DUE_TO_BIT_SET    0x0200U\r
+       #define taskWAIT_FOR_ALL_BITS                   0x0400U\r
+       #define taskEVENT_BITS_CONTROL_BYTES    0xff00U\r
 #else\r
-       #define taskCLEAR_EVENTS_ON_EXIT_BIT            0x01000000UL\r
-       #define taskUNBLOCKED_DUE_TO_BIT_SET_BIT        0x02000000UL\r
-       #define taskWAIT_FOR_ALL_BITS                           0x04000000UL\r
-       #define taskEVENT_BITS_CONTROL_BYTES            0xff000000UL\r
+       #define taskCLEAR_EVENTS_ON_EXIT_BIT    0x01000000UL\r
+       #define taskUNBLOCKED_DUE_TO_BIT_SET    0x02000000UL\r
+       #define taskWAIT_FOR_ALL_BITS                   0x04000000UL\r
+       #define taskEVENT_BITS_CONTROL_BYTES    0xff000000UL\r
 #endif\r
 \r
 typedef struct EventBitsDefinition\r
@@ -190,7 +190,7 @@ portBASE_TYPE xYieldedAlready;
                event list item, and they should now be retrieved then cleared. */\r
                uxReturn = uxTaskResetEventItemValue();\r
 \r
-               if( ( uxReturn & taskUNBLOCKED_DUE_TO_BIT_SET_BIT ) == ( xEventBitsType ) 0 )\r
+               if( ( uxReturn & taskUNBLOCKED_DUE_TO_BIT_SET ) == ( xEventBitsType ) 0 )\r
                {\r
                        /* The task timed out, just return the current event bit value. */\r
                        uxReturn = pxEventBits->uxEventBits;\r
@@ -288,7 +288,7 @@ xEventBitsType uxReturn, uxControlBits = 0;
                event list item, and they should now be retrieved then cleared. */\r
                uxReturn = uxTaskResetEventItemValue();\r
 \r
-               if( ( uxReturn & taskUNBLOCKED_DUE_TO_BIT_SET_BIT ) == ( xEventBitsType ) 0 )\r
+               if( ( uxReturn & taskUNBLOCKED_DUE_TO_BIT_SET ) == ( xEventBitsType ) 0 )\r
                {\r
                        /* The task timed out, just return the current event bit value. */\r
                        uxReturn = pxEventBits->uxEventBits;\r
@@ -356,6 +356,7 @@ portBASE_TYPE xMatchFound = pdFALSE;
                {\r
                        pxNext = listGET_NEXT( pxListItem );\r
                        uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem );\r
+                       xMatchFound = pdFALSE;\r
 \r
                        /* Split the bits waited for from the control bits. */\r
                        uxControlBits = uxBitsWaitedFor & taskEVENT_BITS_CONTROL_BYTES;\r
@@ -389,10 +390,10 @@ portBASE_TYPE xMatchFound = pdFALSE;
 \r
                                /* Store the actual event flag value in the task's event list\r
                                item before removing the task from the event list.  The\r
-                               taskUNBLOCKED_DUE_TO_BIT_SET_BIT bit is set so the task knows\r
+                               taskUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows\r
                                that is was unblocked due to its required bits matching, rather\r
                                than because it timed out. */\r
-                               ( void ) xTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | taskUNBLOCKED_DUE_TO_BIT_SET_BIT );\r
+                               ( void ) xTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | taskUNBLOCKED_DUE_TO_BIT_SET );\r
                        }\r
 \r
                        /* Move onto the next list item.  Note pxListItem->pxNext is not\r
@@ -423,7 +424,7 @@ const xList *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
                        /* Unblock the task, returning 0 as the event list is being deleted\r
                        and     cannot therefore have any bits set. */\r
                        configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( xListItem * ) &( pxTasksWaitingForBits->xListEnd ) );\r
-                       ( void ) xTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, ( portTickType ) 0 );\r
+                       ( void ) xTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, ( portTickType ) taskUNBLOCKED_DUE_TO_BIT_SET );\r
                }\r
 \r
                vPortFree( pxEventBits );\r