]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Demo/Common/Minimal/QueueSet.c
Start to remove unnecessary 'signed char *' casts from strings that are now just...
[freertos] / FreeRTOS / Demo / Common / Minimal / QueueSet.c
index 5ffc45894b9e60b9bc6991d0758bcd1d4c214200..036b98b2ca0b707fe4b88b516f1449b68d4bc927 100644 (file)
@@ -1,5 +1,6 @@
 /*\r
-    FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.\r
+    FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd. \r
+    All rights reserved\r
 \r
     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
 \r
@@ -75,6 +76,7 @@
  * queuesetINITIAL_ISR_TX_VALUE to ULONG_MAX.\r
  */\r
 \r
+\r
 /* Standard includes. */\r
 #include <stdlib.h>\r
 #include <limits.h>\r
@@ -105,15 +107,19 @@ in the range of 0xffff to ULONG_MAX. */
 /* The priorities used in this demo. */\r
 #define queuesetLOW_PRIORITY   ( tskIDLE_PRIORITY )\r
 #define queuesetMEDIUM_PRIORITY ( queuesetLOW_PRIORITY + 1 )\r
-#define queuesetHIGH_PRIORITY  ( queuesetMEDIUM_PRIORITY + 1 )\r
 \r
 /* For test purposes the priority of the sending task is changed after every\r
 queuesetPRIORITY_CHANGE_LOOPS number of values are sent to a queue. */\r
-#define queuesetPRIORITY_CHANGE_LOOPS  100UL\r
+#define queuesetPRIORITY_CHANGE_LOOPS  ( ( queuesetNUM_QUEUES_IN_SET * queuesetQUEUE_LENGTH ) * 2 )\r
 \r
 /* The ISR sends to the queue every queuesetISR_TX_PERIOD ticks. */\r
 #define queuesetISR_TX_PERIOD  ( 100UL )\r
 \r
+/* A delay inserted when the Tx task changes its priority to be above the idle\r
+task priority to ensure the idle priority tasks get some CPU time before the\r
+next iteration of the queue set Tx task. */\r
+#define queuesetTX_LOOP_DELAY  ( 200 / portTICK_RATE_MS )\r
+\r
 /* The allowable maximum deviation between a received value and the expected\r
 received value.  A deviation will occur when data is received from a queue\r
 inside an ISR in between a task receiving from a queue and the task checking\r
@@ -124,6 +130,13 @@ the received value. */
 testing of limits easier (don't have to deal with wrapping values). */\r
 #define queuesetIGNORED_BOUNDARY       ( queuesetALLOWABLE_RX_DEVIATION * 2 )\r
 \r
+typedef enum\r
+{\r
+       eEqualPriority = 0,     /* Tx and Rx tasks have the same priority. */\r
+       eTxHigherPriority,      /* The priority of the Tx task is above that of the Rx task. */\r
+       eTxLowerPriority        /* The priority of the Tx task is below that of the Rx task. */\r
+} eRelativePriorities;\r
+\r
 /*\r
  * The task that periodically sends to the queue set.\r
  */\r
@@ -153,7 +166,7 @@ static void prvSendToQueueInSetFromISR( void );
  * Create the queues and add them to a queue set before resuming the Tx\r
  * task.\r
  */\r
-static void prvSetupTest( xTaskHandle xQueueSetSendingTask );\r
+static void prvSetupTest( void );\r
 \r
 /*\r
  * Checks a value received from a queue falls within the range of expected\r
@@ -161,6 +174,18 @@ static void prvSetupTest( xTaskHandle xQueueSetSendingTask );
  */\r
 static portBASE_TYPE prvCheckReceivedValueWithinExpectedRange( unsigned long ulReceived, unsigned long ulExpectedReceived );\r
 \r
+/*\r
+ * Increase test coverage by occasionally change the priorities of the two tasks\r
+ * relative to each other. */\r
+static void prvChangeRelativePriorities( void );\r
+\r
+/*\r
+ * Local pseudo random number seed and return functions.  Used to avoid calls\r
+ * to the standard library.\r
+ */\r
+static unsigned long prvRand( void );\r
+static void prvSRand( unsigned long ulSeed );\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /* The queues that are added to the set. */\r
@@ -193,17 +218,19 @@ xAreQueeuSetTasksStillRunning() function can check it is incrementing as
 expected. */\r
 static volatile unsigned long ulISRTxValue = queuesetINITIAL_ISR_TX_VALUE;\r
 \r
+/* Used by the pseudo random number generator. */\r
+static unsigned long ulNextRand = 0;\r
+\r
+/* The task handles are stored so their priorities can be changed. */\r
+xTaskHandle xQueueSetSendingTask, xQueueSetReceivingTask;\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 void vStartQueueSetTasks( void )\r
 {\r
-xTaskHandle xQueueSetSendingTask;\r
-\r
-       /* Create the two queues.  The handle of the sending task is passed into\r
-       the receiving task using the task parameter.  The receiving task uses the\r
-       handle to resume the sending task after it has created the queues. */\r
-       xTaskCreate( prvQueueSetSendingTask, ( signed char * ) "SetTx", configMINIMAL_STACK_SIZE, NULL, queuesetMEDIUM_PRIORITY, &xQueueSetSendingTask );\r
-       xTaskCreate( prvQueueSetReceivingTask, ( signed char * ) "SetRx", configMINIMAL_STACK_SIZE, ( void * ) xQueueSetSendingTask, queuesetMEDIUM_PRIORITY, NULL );\r
+       /* Create the tasks. */\r
+       xTaskCreate( prvQueueSetSendingTask, "SetTx", configMINIMAL_STACK_SIZE, NULL, queuesetMEDIUM_PRIORITY, &xQueueSetSendingTask );\r
+       xTaskCreate( prvQueueSetReceivingTask, "SetRx", configMINIMAL_STACK_SIZE, ( void * ) xQueueSetSendingTask, queuesetMEDIUM_PRIORITY, &xQueueSetReceivingTask );\r
 \r
        /* It is important that the sending task does not attempt to write to a\r
        queue before the queue has been created.  It is therefore placed into the\r
@@ -264,25 +291,24 @@ portBASE_TYPE xReturn = pdPASS, x;
 \r
 static void prvQueueSetSendingTask( void *pvParameters )\r
 {\r
-unsigned long ulTaskTxValue = 0;\r
-portBASE_TYPE xQueueToWriteTo;\r
+unsigned long ulTaskTxValue = 0, ulQueueToWriteTo;\r
 xQueueHandle xQueueInUse;\r
-unsigned portBASE_TYPE uxPriority = queuesetMEDIUM_PRIORITY, ulLoops = 0;\r
 \r
        /* Remove compiler warning about the unused parameter. */\r
        ( void ) pvParameters;\r
 \r
-       srand( ( unsigned int ) &ulTaskTxValue );\r
+       /* Seed mini pseudo random number generator. */\r
+       prvSRand( ( unsigned long ) &ulTaskTxValue );\r
 \r
        for( ;; )\r
        {\r
                /* Generate the index for the queue to which a value is to be sent. */\r
-               xQueueToWriteTo = rand() % queuesetNUM_QUEUES_IN_SET;\r
-               xQueueInUse = xQueues[ xQueueToWriteTo ];\r
+               ulQueueToWriteTo = prvRand() % queuesetNUM_QUEUES_IN_SET;\r
+               xQueueInUse = xQueues[ ulQueueToWriteTo ];\r
 \r
                /* Note which index is being written to to ensure all the queues are\r
                used. */\r
-               ( ulQueueUsedCounter[ xQueueToWriteTo ] )++;\r
+               ( ulQueueUsedCounter[ ulQueueToWriteTo ] )++;\r
 \r
                /* Send to the queue to unblock the task that is waiting for data to\r
                arrive on a queue within the queue set to which this queue belongs. */\r
@@ -293,6 +319,10 @@ unsigned portBASE_TYPE uxPriority = queuesetMEDIUM_PRIORITY, ulLoops = 0;
                        xQueueSetTasksStatus = pdFAIL;\r
                }\r
 \r
+               #if( configUSE_PREEMPTION == 0 )\r
+                       taskYIELD();\r
+               #endif\r
+\r
                ulTaskTxValue++;\r
 \r
                /* If the Tx value has reached the range used by the ISR then set it\r
@@ -302,19 +332,56 @@ unsigned portBASE_TYPE uxPriority = queuesetMEDIUM_PRIORITY, ulLoops = 0;
                        ulTaskTxValue = 0;\r
                }\r
 \r
-               /* Occasionally change the task priority relative to the priority of\r
-               the receiving task. */\r
-               ulLoops++;\r
-               if( ulLoops >= queuesetPRIORITY_CHANGE_LOOPS )\r
-               {\r
-                       ulLoops = 0;\r
-                       uxPriority++;\r
-                       if( uxPriority > queuesetHIGH_PRIORITY )\r
-                       {\r
-                               uxPriority = queuesetLOW_PRIORITY;\r
-                       }\r
+               /* Increase test coverage by occasionally change the priorities of the\r
+               two tasks relative to each other. */\r
+               prvChangeRelativePriorities();\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
 \r
-                       vTaskPrioritySet( NULL, uxPriority );\r
+static void prvChangeRelativePriorities( void )\r
+{\r
+static unsigned portBASE_TYPE ulLoops = 0;\r
+static eRelativePriorities ePriorities = eEqualPriority;\r
+\r
+       /* Occasionally change the task priority relative to the priority of\r
+       the receiving task. */\r
+       ulLoops++;\r
+       if( ulLoops >= queuesetPRIORITY_CHANGE_LOOPS )\r
+       {\r
+               ulLoops = 0;\r
+\r
+               switch( ePriorities )\r
+               {\r
+                       case eEqualPriority:\r
+                               /* Both tasks are running with medium priority.  Now lower the\r
+                               priority of the receiving task so the Tx task has the higher\r
+                               relative priority. */\r
+                               vTaskPrioritySet( xQueueSetReceivingTask, queuesetLOW_PRIORITY );\r
+                               ePriorities = eTxHigherPriority;\r
+                               break;\r
+\r
+                       case eTxHigherPriority:\r
+                               /* The Tx task is running with a higher priority than the Rx\r
+                               task.  Switch the priorities around so the Rx task has the\r
+                               higher relative priority. */\r
+                               vTaskPrioritySet( xQueueSetReceivingTask, queuesetMEDIUM_PRIORITY );\r
+                               vTaskPrioritySet( xQueueSetSendingTask, queuesetLOW_PRIORITY );\r
+                               ePriorities = eTxLowerPriority;\r
+                               break;\r
+\r
+                       case eTxLowerPriority:\r
+                               /* The Tx task is running with a lower priority than the Rx\r
+                               task.  Make the priorities equal again. */\r
+                               vTaskPrioritySet( xQueueSetSendingTask, queuesetMEDIUM_PRIORITY );\r
+                               ePriorities = eEqualPriority;\r
+\r
+                               /* When both tasks are using a non-idle priority the queue set\r
+                               tasks will starve idle priority tasks of execution time - so\r
+                               relax a bit before the next iteration to minimise the impact. */\r
+                               vTaskDelay( queuesetTX_LOOP_DELAY );\r
+\r
+                               break;\r
                }\r
        }\r
 }\r
@@ -324,14 +391,13 @@ static void prvQueueSetReceivingTask( void *pvParameters )
 {\r
 unsigned long ulReceived;\r
 xQueueHandle xActivatedQueue;\r
-xTaskHandle xQueueSetSendingTask;\r
 \r
-       /* The handle to the sending task is passed in using the task parameter. */\r
-       xQueueSetSendingTask = ( xTaskHandle ) pvParameters;\r
+       /* Remove compiler warnings. */\r
+       ( void ) pvParameters;\r
 \r
        /* Create the queues and add them to the queue set before resuming the Tx\r
        task. */\r
-       prvSetupTest( xQueueSetSendingTask );\r
+       prvSetupTest();\r
 \r
        for( ;; )\r
        {\r
@@ -419,17 +485,11 @@ static unsigned long ulExpectedReceivedFromTask = 0, ulExpectedReceivedFromISR =
                {\r
                        /* The value received is at the lower limit of the expected range.\r
                        Don't test it and expect to receive one higher next time. */\r
-                       ulExpectedReceivedFromISR++;\r
                }\r
                else if( ( ULONG_MAX - ulReceived ) <= queuesetIGNORED_BOUNDARY )\r
                {\r
                        /* The value received is at the higher limit of the expected range.\r
                        Don't test it and expect to wrap soon. */\r
-                       ulExpectedReceivedFromISR++;\r
-                       if( ulExpectedReceivedFromISR == 0 )\r
-                       {\r
-                               ulExpectedReceivedFromISR = queuesetINITIAL_ISR_TX_VALUE;\r
-                       }\r
                }\r
                else\r
                {\r
@@ -438,11 +498,15 @@ static unsigned long ulExpectedReceivedFromTask = 0, ulExpectedReceivedFromISR =
                        {\r
                                xQueueSetTasksStatus = pdFAIL;\r
                        }\r
-                       else\r
-                       {\r
-                               /* It is expected to receive an incrementing value. */\r
-                               ulExpectedReceivedFromISR++;\r
-                       }\r
+               }\r
+\r
+               configASSERT( xQueueSetTasksStatus );\r
+\r
+               /* It is expected to receive an incrementing number. */\r
+               ulExpectedReceivedFromISR++;\r
+               if( ulExpectedReceivedFromISR == 0 )\r
+               {\r
+                       ulExpectedReceivedFromISR = queuesetINITIAL_ISR_TX_VALUE;\r
                }\r
        }\r
        else\r
@@ -452,17 +516,11 @@ static unsigned long ulExpectedReceivedFromTask = 0, ulExpectedReceivedFromISR =
                {\r
                        /* The value received is at the lower limit of the expected range.\r
                        Don't test it, and expect to receive one higher next time. */\r
-                       ulExpectedReceivedFromTask++;\r
                }\r
                else if( ( ( queuesetINITIAL_ISR_TX_VALUE - 1 ) - ulReceived ) <= queuesetIGNORED_BOUNDARY )\r
                {\r
                        /* The value received is at the higher limit of the expected range.\r
                        Don't test it and expect to wrap soon. */\r
-                       ulExpectedReceivedFromTask++;\r
-                       if( ulExpectedReceivedFromTask >= queuesetINITIAL_ISR_TX_VALUE )\r
-                       {\r
-                               ulExpectedReceivedFromTask = 0;\r
-                       }\r
                }\r
                else\r
                {\r
@@ -471,11 +529,15 @@ static unsigned long ulExpectedReceivedFromTask = 0, ulExpectedReceivedFromISR =
                        {\r
                                xQueueSetTasksStatus = pdFAIL;\r
                        }\r
-                       else\r
-                       {\r
-                               /* It is expected to receive an incrementing value. */\r
-                               ulExpectedReceivedFromTask++;\r
-                       }\r
+               }\r
+\r
+               configASSERT( xQueueSetTasksStatus );\r
+\r
+               /* It is expected to receive an incrementing number. */\r
+               ulExpectedReceivedFromTask++;\r
+               if( ulExpectedReceivedFromTask >= queuesetINITIAL_ISR_TX_VALUE )\r
+               {\r
+                       ulExpectedReceivedFromTask = 0;\r
                }\r
        }\r
 }\r
@@ -555,7 +617,7 @@ static portBASE_TYPE xQueueToWriteTo = 0;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-static void prvSetupTest( xTaskHandle xQueueSetSendingTask )\r
+static void prvSetupTest( void )\r
 {\r
 portBASE_TYPE x;\r
 unsigned long ulValueToSend = 0;\r
@@ -637,3 +699,17 @@ unsigned long ulValueToSend = 0;
        /* Let the ISR access the queues also. */\r
        xSetupComplete = pdTRUE;\r
 }\r
+/*-----------------------------------------------------------*/\r
+\r
+static unsigned long prvRand( void )\r
+{\r
+       ulNextRand = ( ulNextRand * 1103515245UL ) + 12345UL;\r
+    return ( ulNextRand / 65536UL ) % 32768UL;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvSRand( unsigned long ulSeed )\r
+{\r
+    ulNextRand = ulSeed;\r
+}\r
+\r