--- /dev/null
+/*\r
+ FreeRTOS.org V5.0.0 - Copyright (C) 2003-2008 Richard Barry.\r
+\r
+ This file is part of the FreeRTOS.org distribution.\r
+\r
+ FreeRTOS.org is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; either version 2 of the License, or\r
+ (at your option) any later version.\r
+\r
+ FreeRTOS.org is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License\r
+ along with FreeRTOS.org; if not, write to the Free Software\r
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+\r
+ A special exception to the GPL can be applied should you wish to distribute\r
+ a combined work that includes FreeRTOS.org, without being obliged to provide\r
+ the source code for any proprietary components. See the licensing section\r
+ of http://www.FreeRTOS.org for full details of how and when the exception\r
+ can be applied.\r
+\r
+ ***************************************************************************\r
+ ***************************************************************************\r
+ * *\r
+ * SAVE TIME AND MONEY! We can port FreeRTOS.org to your own hardware, *\r
+ * and even write all or part of your application on your behalf. *\r
+ * See http://www.OpenRTOS.com for details of the services we provide to *\r
+ * expedite your project. *\r
+ * *\r
+ ***************************************************************************\r
+ ***************************************************************************\r
+\r
+ Please ensure to read the configuration and relevant port sections of the\r
+ online documentation.\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and \r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety \r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting, \r
+ licensing and training services.\r
+*/\r
+\r
+/* Standard includes. */\r
+#include <string.h>\r
+\r
+/* SafeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "queue.h"\r
+#include "task.h"\r
+\r
+/* Demo app includes. */\r
+#include "IntQueue.h"\r
+#include "IntQueueTimer.h"\r
+\r
+/* Priorities used by test tasks. */\r
+#define intqHIGHER_PRIORITY 1\r
+#define intqLOWER_PRIORITY 0\r
+\r
+/* The number of values to send/receive before checking that all values were\r
+processed as expected. */\r
+#define intqNUM_VALUES_TO_LOG ( 200 )\r
+#define intqSHORT_DELAY ( 75 )\r
+\r
+/* The delay used by the polling task. A short delay is used for code \r
+coverage. */\r
+#define intqONE_TICK_DELAY ( 1 )\r
+\r
+#define intqHIGH_PRIROITY_TASK1 ( ( unsigned portBASE_TYPE ) 1 )\r
+#define intqHIGH_PRIROITY_TASK2 ( ( unsigned portBASE_TYPE ) 2 )\r
+#define intqLOW_PRIROITY_TASK ( ( unsigned portBASE_TYPE ) 3 )\r
+#define intqFIRST_INTERRUPT ( ( unsigned portBASE_TYPE ) 4 )\r
+#define intqSECOND_INTERRUPT ( ( unsigned portBASE_TYPE ) 5 )\r
+#define intqQUEUE_LENGTH ( ( unsigned portBASE_TYPE ) 10 )\r
+\r
+\r
+#define intqMIN_ACCEPTABLE_TASK_COUNT ( 5 )\r
+\r
+\r
+#define timerNORMALLY_EMPTY_TX() \\r
+ if( xQueueIsQueueFullFromISR( xNormallyEmptyQueue ) != pdTRUE ) \\r
+ { \\r
+ unsigned portBASE_TYPE uxSavedInterruptStatus; \\r
+ uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \\r
+ { \\r
+ xQueueSendFromISR( xNormallyEmptyQueue, ( void * ) &uxValueForNormallyEmptyQueue, &xHigherPriorityTaskWoken ); \\r
+ uxValueForNormallyEmptyQueue++; \\r
+ } \\r
+ portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \\r
+ } \\r
+\r
+#define timerNORMALLY_FULL_TX() \\r
+ if( xQueueIsQueueFullFromISR( xNormallyFullQueue ) != pdTRUE ) \\r
+ { \\r
+ unsigned portBASE_TYPE uxSavedInterruptStatus; \\r
+ uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \\r
+ { \\r
+ xQueueSendFromISR( xNormallyFullQueue, ( void * ) &uxValueForNormallyFullQueue, &xHigherPriorityTaskWoken ); \\r
+ uxValueForNormallyFullQueue++; \\r
+ } \\r
+ portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \\r
+ } \\r
+\r
+#define timerNORMALLY_EMPTY_RX() \\r
+ if( xQueueReceiveFromISR( xNormallyEmptyQueue, &uxRxedValue, &xHigherPriorityTaskWoken ) != pdPASS ) \\r
+ { \\r
+ prvQueueAccessLogError( __LINE__ ); \\r
+ } \\r
+ else \\r
+ { \\r
+ prvRecordValue_NormallyEmpty( uxRxedValue, intqSECOND_INTERRUPT ); \\r
+ }\r
+\r
+#define timerNORMALLY_FULL_RX() \\r
+ if( xQueueReceiveFromISR( xNormallyFullQueue, &uxRxedValue, &xHigherPriorityTaskWoken ) == pdPASS ) \\r
+ { \\r
+ prvRecordValue_NormallyFull( uxRxedValue, intqSECOND_INTERRUPT ); \\r
+ } \\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* The two queues used by the test. */\r
+static xQueueHandle xNormallyEmptyQueue, xNormallyFullQueue;\r
+\r
+/* Variables used to detect a stall in one of the tasts. */\r
+static unsigned portBASE_TYPE uxHighPriorityLoops1 = 0, uxHighPriorityLoops2 = 0, uxLowPriorityLoops1 = 0, uxLowPriorityLoops2 = 0;\r
+\r
+/* Any unexpected behaviour sets xErrorStatus to fail and log the line that\r
+caused the error in xErrorLine. */\r
+static portBASE_TYPE xErrorStatus = pdPASS;\r
+static unsigned portBASE_TYPE xErrorLine = ( unsigned portBASE_TYPE ) 0;\r
+\r
+static portBASE_TYPE xWasSuspended = pdFALSE;\r
+\r
+/* The values that are sent to the queues. An incremented value is sent each\r
+time to each queue. */\r
+volatile unsigned portBASE_TYPE uxValueForNormallyEmptyQueue = 0, uxValueForNormallyFullQueue = 0;\r
+\r
+/* A handle to some of the tasks is required so they can be suspended/resumed. */\r
+xTaskHandle xHighPriorityNormallyEmptyTask1, xHighPriorityNormallyEmptyTask2, xHighPriorityNormallyFullTask1, xHighPriorityNormallyFullTask2;\r
+\r
+/* When a value is received in a queue the value is ticked off in the array\r
+the array position of the vlaue is set to a 1. This way missing or duplicate\r
+values can be detected. */\r
+static unsigned portCHAR ucNormallyEmptyReceivedValues[ intqNUM_VALUES_TO_LOG ] = { 0 };\r
+static unsigned portCHAR ucNormallyFullReceivedValues[ intqNUM_VALUES_TO_LOG ] = { 0 };\r
+\r
+/* The test tasks themselves. */\r
+static void prvLowerPriorityNormallyEmptyTask( void *pvParameters );\r
+static void prvLowerPriorityNormallyFullTask( void *pvParameters );\r
+static void prvHigherPriorityNormallyEmptyTask( void *pvParameters );\r
+static void prv1stHigherPriorityNormallyFullTask( void *pvParameters );\r
+static void prv2ndHigherPriorityNormallyFullTask( void *pvParameters );\r
+\r
+static void prvRecordValue_NormallyEmpty( unsigned portBASE_TYPE uxValue, unsigned portBASE_TYPE uxSource );\r
+static void prvRecordValue_NormallyFull( unsigned portBASE_TYPE uxValue, unsigned portBASE_TYPE uxSource );\r
+\r
+/* Logs the line on which an error occurred. */\r
+static void prvQueueAccessLogError( unsigned portBASE_TYPE uxLine );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vStartInterruptQueueTasks( void )\r
+{\r
+ /* Start the test tasks. */\r
+ xTaskCreate( prvHigherPriorityNormallyEmptyTask, ( signed portCHAR * ) "H1QRx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIROITY_TASK1, intqHIGHER_PRIORITY, &xHighPriorityNormallyEmptyTask1 );\r
+ xTaskCreate( prvHigherPriorityNormallyEmptyTask, ( signed portCHAR * ) "H2QRx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIROITY_TASK2, intqHIGHER_PRIORITY, &xHighPriorityNormallyEmptyTask2 );\r
+ xTaskCreate( prvLowerPriorityNormallyEmptyTask, ( signed portCHAR * ) "LQRx", configMINIMAL_STACK_SIZE, NULL, intqLOWER_PRIORITY, NULL );\r
+ xTaskCreate( prv1stHigherPriorityNormallyFullTask, ( signed portCHAR * ) "H1QTx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIROITY_TASK1, intqHIGHER_PRIORITY, &xHighPriorityNormallyFullTask1 );\r
+ xTaskCreate( prv2ndHigherPriorityNormallyFullTask, ( signed portCHAR * ) "H1QTx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIROITY_TASK2, intqHIGHER_PRIORITY, &xHighPriorityNormallyFullTask2 );\r
+ xTaskCreate( prvLowerPriorityNormallyFullTask, ( signed portCHAR * ) "LQRx", configMINIMAL_STACK_SIZE, NULL, intqLOWER_PRIORITY, NULL );\r
+\r
+ /* Create the queues that are accessed by multiple tasks and multiple \r
+ interrupts. */\r
+ xNormallyFullQueue = xQueueCreate( intqQUEUE_LENGTH, ( unsigned portBASE_TYPE ) sizeof( unsigned portBASE_TYPE ) );\r
+ xNormallyEmptyQueue = xQueueCreate( intqQUEUE_LENGTH, ( unsigned portBASE_TYPE ) sizeof( unsigned portBASE_TYPE ) );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvRecordValue_NormallyFull( unsigned portBASE_TYPE uxValue, unsigned portBASE_TYPE uxSource )\r
+{\r
+ if( uxValue < intqNUM_VALUES_TO_LOG )\r
+ {\r
+ /* We don't expect to receive the same value twice, so if the value\r
+ has already been marked as recieved an error has occurred. */\r
+ if( ucNormallyFullReceivedValues[ uxValue ] != 0x00 )\r
+ {\r
+ prvQueueAccessLogError( __LINE__ );\r
+ }\r
+ \r
+ /* Log that this value has been received. */\r
+ ucNormallyFullReceivedValues[ uxValue ] = uxSource;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvRecordValue_NormallyEmpty( unsigned portBASE_TYPE uxValue, unsigned portBASE_TYPE uxSource )\r
+{\r
+ if( uxValue < intqNUM_VALUES_TO_LOG )\r
+ {\r
+ /* We don't expect to receive the same value twice, so if the value\r
+ has already been marked as recieved an error has occurred. */\r
+ if( ucNormallyEmptyReceivedValues[ uxValue ] != 0x00 )\r
+ {\r
+ prvQueueAccessLogError( __LINE__ );\r
+ }\r
+ \r
+ /* Log that this value has been received. */\r
+ ucNormallyEmptyReceivedValues[ uxValue ] = uxSource;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvQueueAccessLogError( unsigned portBASE_TYPE uxLine )\r
+{\r
+ /* Latch the line number that caused the error. */\r
+ xErrorLine = uxLine;\r
+ xErrorStatus = pdFAIL;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvHigherPriorityNormallyEmptyTask( void *pvParameters )\r
+{\r
+unsigned portBASE_TYPE uxRxed, ux, uxTask1, uxTask2;\r
+\r
+ /* The timer should not be started until after the scheduler has started. \r
+ More than one task is running this code so we check the parameter value\r
+ to determine which task should start the timer. */\r
+ if( ( unsigned portBASE_TYPE ) pvParameters == intqHIGH_PRIROITY_TASK1 )\r
+ {\r
+ vInitialiseTimerForIntQueueTest();\r
+ }\r
+\r
+ for( ;; )\r
+ {\r
+ /* Block waiting to receive a value from the normally empty queue.\r
+ Interrupts will write to the queue so we should receive a value. */\r
+ if( xQueueReceive( xNormallyEmptyQueue, &uxRxed, intqSHORT_DELAY ) != pdPASS )\r
+ {\r
+ prvQueueAccessLogError( __LINE__ );\r
+ }\r
+ else\r
+ {\r
+ /* Note which value was received so we can check all expected\r
+ values are received and no values are duplicated. */\r
+ prvRecordValue_NormallyEmpty( uxRxed, ( unsigned portBASE_TYPE ) pvParameters );\r
+ }\r
+ \r
+ /* Ensure the other task running this code gets a chance to execute. */\r
+ taskYIELD();\r
+ \r
+ if( ( unsigned portBASE_TYPE ) pvParameters == intqHIGH_PRIROITY_TASK1 )\r
+ {\r
+ /* Have we received all the expected values? */\r
+ if( uxValueForNormallyEmptyQueue > ( intqNUM_VALUES_TO_LOG + 50 ) )\r
+ {\r
+ vTaskSuspend( xHighPriorityNormallyEmptyTask2 );\r
+ \r
+ uxTask1 = 0;\r
+ uxTask2 = 0;\r
+ \r
+ /* Loop through the array, checking that both tasks have\r
+ placed values into the array, and that no values are missing. */\r
+ for( ux = 0; ux < intqNUM_VALUES_TO_LOG; ux++ )\r
+ {\r
+ if( ucNormallyEmptyReceivedValues[ ux ] == 0 )\r
+ {\r
+ /* A value is missing. */\r
+ prvQueueAccessLogError( __LINE__ );\r
+ }\r
+ else\r
+ {\r
+ if( ucNormallyEmptyReceivedValues[ ux ] == intqHIGH_PRIROITY_TASK1 )\r
+ {\r
+ /* Value was placed into the array by task 1. */\r
+ uxTask1++;\r
+ }\r
+ else if( ucNormallyEmptyReceivedValues[ ux ] == intqHIGH_PRIROITY_TASK2 )\r
+ {\r
+ /* Value was placed into the array by task 2. */\r
+ uxTask2++;\r
+ }\r
+ }\r
+ }\r
+ \r
+ if( uxTask1 < intqMIN_ACCEPTABLE_TASK_COUNT )\r
+ {\r
+ /* Only task 2 seemed to log any values. */\r
+ prvQueueAccessLogError( __LINE__ );\r
+ }\r
+ \r
+ if( uxTask2 < intqMIN_ACCEPTABLE_TASK_COUNT )\r
+ {\r
+ /* Only task 1 seemed to log any values. */\r
+ prvQueueAccessLogError( __LINE__ );\r
+ }\r
+\r
+ /* Clear the array again, ready to start a new cycle. */\r
+ memset( ucNormallyEmptyReceivedValues, 0x00, sizeof( ucNormallyEmptyReceivedValues ) );\r
+ \r
+ uxHighPriorityLoops1++;\r
+ uxValueForNormallyEmptyQueue = 0;\r
+\r
+ /* Suspend ourselves, allowing the lower priority task to \r
+ actually receive something from the queue. Until now it\r
+ will have been prevented from doing so by the higher\r
+ priority tasks. The lower priority task will resume us\r
+ if it receives something. We will then resume the other\r
+ higher priority task. */\r
+ vTaskSuspend( NULL ); \r
+ vTaskResume( xHighPriorityNormallyEmptyTask2 );\r
+ }\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvLowerPriorityNormallyEmptyTask( void *pvParameters )\r
+{\r
+unsigned portBASE_TYPE uxValue, uxRxed;\r
+portBASE_TYPE xQueueStatus;\r
+\r
+ /* The paramters are not being used so avoid compiler warnings. */\r
+ ( void ) pvParameters;\r
+ \r
+ for( ;; )\r
+ { \r
+ if( ( xQueueStatus = xQueueReceive( xNormallyEmptyQueue, &uxRxed, intqONE_TICK_DELAY ) ) != errQUEUE_EMPTY )\r
+ {\r
+ /* We should only obtain a value when the high priority task is\r
+ suspended. */\r
+ if( xTaskIsTaskSuspended( xHighPriorityNormallyEmptyTask1 ) == pdFALSE )\r
+ {\r
+ prvQueueAccessLogError( __LINE__ );\r
+ }\r
+\r
+ prvRecordValue_NormallyEmpty( uxRxed, intqLOW_PRIROITY_TASK );\r
+ \r
+ /* Wake the higher priority task again. */\r
+ vTaskResume( xHighPriorityNormallyEmptyTask1 );\r
+ uxLowPriorityLoops1++;\r
+ }\r
+ else\r
+ {\r
+ /* Raise our priority while we send so we can preempt the higher\r
+ priority task, and ensure we get the Tx value into the queue. */\r
+ vTaskPrioritySet( NULL, intqHIGHER_PRIORITY + 1 );\r
+ \r
+ portENTER_CRITICAL();\r
+ {\r
+ uxValue = uxValueForNormallyEmptyQueue;\r
+ uxValueForNormallyEmptyQueue++;\r
+ }\r
+ portEXIT_CRITICAL();\r
+ \r
+ if( xQueueSend( xNormallyEmptyQueue, &uxValue, portMAX_DELAY ) != pdPASS )\r
+ {\r
+ prvQueueAccessLogError( __LINE__ );\r
+ }\r
+ \r
+ vTaskPrioritySet( NULL, intqLOWER_PRIORITY );\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xAreIntQueueTasksStillRunning( void )\r
+{\r
+static unsigned portBASE_TYPE uxLastHighPriorityLoops1 = 0, uxLastHighPriorityLoops2 = 0, uxLastLowPriorityLoops1 = 0, uxLastLowPriorityLoops2 = 0;\r
+ \r
+ if( uxHighPriorityLoops1 == uxLastHighPriorityLoops1 )\r
+ {\r
+ prvQueueAccessLogError( __LINE__ );\r
+ }\r
+ \r
+ uxLastHighPriorityLoops1 = uxHighPriorityLoops1;\r
+ \r
+ if( uxHighPriorityLoops2 == uxLastHighPriorityLoops2 )\r
+ {\r
+ prvQueueAccessLogError( __LINE__ );\r
+ }\r
+ \r
+ uxLastHighPriorityLoops2 = uxHighPriorityLoops2;\r
+ \r
+ if( uxLowPriorityLoops1 == uxLastLowPriorityLoops1 )\r
+ {\r
+ prvQueueAccessLogError( __LINE__ );\r
+ }\r
+\r
+ uxLastLowPriorityLoops1 = uxLowPriorityLoops1;\r
+\r
+ if( uxLowPriorityLoops2 == uxLastLowPriorityLoops2 )\r
+ {\r
+ prvQueueAccessLogError( __LINE__ );\r
+ }\r
+\r
+ uxLastLowPriorityLoops2 = uxLowPriorityLoops2;\r
+\r
+ return xErrorStatus;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prv1stHigherPriorityNormallyFullTask( void *pvParameters )\r
+{\r
+unsigned portBASE_TYPE uxValueToTx, ux;\r
+portBASE_TYPE xQueueStatus;\r
+\r
+ /* The paramters are not being used so avoid compiler warnings. */\r
+ ( void ) pvParameters;\r
+ \r
+ /* Make sure the queue starts full or near full. >> 1 as there are two\r
+ high priority tasks. */\r
+ for( ux = 0; ux < ( intqQUEUE_LENGTH >> 1 ); ux++ )\r
+ {\r
+ portENTER_CRITICAL();\r
+ {\r
+ uxValueToTx = uxValueForNormallyFullQueue;\r
+ uxValueForNormallyFullQueue++;\r
+ }\r
+ portEXIT_CRITICAL();\r
+\r
+ xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ); \r
+ }\r
+\r
+ for( ;; )\r
+ {\r
+ portENTER_CRITICAL();\r
+ {\r
+ uxValueToTx = uxValueForNormallyFullQueue;\r
+ uxValueForNormallyFullQueue++;\r
+ }\r
+ portEXIT_CRITICAL();\r
+\r
+ if( ( xQueueStatus = xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ) ) != pdPASS )\r
+ {\r
+ /* intqHIGH_PRIROITY_TASK2 is never suspended so we would not \r
+ expect it to ever time out. */\r
+ prvQueueAccessLogError( __LINE__ );\r
+ }\r
+\r
+ /* Allow the other task running this code to run. */\r
+ taskYIELD();\r
+ \r
+ /* Have all the expected values been sent to the queue? */\r
+ if( uxValueToTx > ( intqNUM_VALUES_TO_LOG + 50 ) )\r
+ {\r
+ /* Make sure the other high priority task completes its send of\r
+ any values below intqNUM_VALUE_TO_LOG. */\r
+ vTaskDelay( intqSHORT_DELAY );\r
+ \r
+ vTaskSuspend( xHighPriorityNormallyFullTask2 );\r
+ \r
+ if( xWasSuspended == pdTRUE )\r
+ {\r
+ /* We would have expected the other high pririty task to have\r
+ set this back to false by now. */\r
+ prvQueueAccessLogError( __LINE__ );\r
+ }\r
+ \r
+ /* Set the suspended flag so an error is not logged if the other\r
+ task recognises a time out when it is unsuspended. */\r
+ xWasSuspended = pdTRUE;\r
+ \r
+ for( ux = 0; ux < intqNUM_VALUES_TO_LOG; ux++ )\r
+ {\r
+ if( ucNormallyFullReceivedValues[ ux ] == 0 )\r
+ {\r
+ /* A value was missing. */\r
+ prvQueueAccessLogError( __LINE__ );\r
+ }\r
+ } \r
+\r
+ /* Reset the array ready for the next cycle. */\r
+ memset( ucNormallyFullReceivedValues, 0x00, sizeof( ucNormallyFullReceivedValues ) ); \r
+ \r
+ uxHighPriorityLoops2++;\r
+ uxValueForNormallyFullQueue = 0;\r
+\r
+ /* Suspend ourselves, allowing the lower priority task to \r
+ actually receive something from the queue. Until now it\r
+ will have been prevented from doing so by the higher\r
+ priority tasks. The lower priority task will resume us\r
+ if it receives something. We will then resume the other\r
+ higher priority task. */\r
+ vTaskSuspend( NULL ); \r
+ vTaskResume( xHighPriorityNormallyFullTask2 );\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prv2ndHigherPriorityNormallyFullTask( void *pvParameters )\r
+{\r
+unsigned portBASE_TYPE uxValueToTx, ux;\r
+portBASE_TYPE xQueueStatus;\r
+\r
+ /* The paramters are not being used so avoid compiler warnings. */\r
+ ( void ) pvParameters;\r
+ \r
+ /* Make sure the queue starts full or near full. >> 1 as there are two\r
+ high priority tasks. */\r
+ for( ux = 0; ux < ( intqQUEUE_LENGTH >> 1 ); ux++ )\r
+ {\r
+ portENTER_CRITICAL();\r
+ {\r
+ uxValueToTx = uxValueForNormallyFullQueue;\r
+ uxValueForNormallyFullQueue++;\r
+ }\r
+ portEXIT_CRITICAL();\r
+\r
+ xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ); \r
+ }\r
+\r
+ for( ;; )\r
+ {\r
+ portENTER_CRITICAL();\r
+ {\r
+ uxValueToTx = uxValueForNormallyFullQueue;\r
+ uxValueForNormallyFullQueue++;\r
+ }\r
+ portEXIT_CRITICAL();\r
+\r
+ if( ( xQueueStatus = xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ) ) != pdPASS )\r
+ {\r
+ if( xWasSuspended != pdTRUE )\r
+ {\r
+ /* It is ok to time out if the task has been suspended. */\r
+ prvQueueAccessLogError( __LINE__ );\r
+ }\r
+ }\r
+\r
+ xWasSuspended = pdFALSE;\r
+ \r
+ taskYIELD();\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvLowerPriorityNormallyFullTask( void *pvParameters )\r
+{\r
+unsigned portBASE_TYPE uxValue, uxTxed = 9999;\r
+portBASE_TYPE xQueueStatus;\r
+\r
+ /* The paramters are not being used so avoid compiler warnings. */\r
+ ( void ) pvParameters;\r
+ \r
+ for( ;; )\r
+ { \r
+ if( ( xQueueStatus = xQueueSend( xNormallyFullQueue, &uxTxed, intqONE_TICK_DELAY ) ) != errQUEUE_FULL )\r
+ {\r
+ /* We would only expect to succeed when the higher priority task\r
+ is suspended. */\r
+ if( xTaskIsTaskSuspended( xHighPriorityNormallyFullTask1 ) == pdFALSE )\r
+ {\r
+ prvQueueAccessLogError( __LINE__ );\r
+ }\r
+\r
+ vTaskResume( xHighPriorityNormallyFullTask1 );\r
+ uxLowPriorityLoops2++;\r
+ }\r
+ else\r
+ {\r
+ /* Raise our priority while we receive so we can preempt the higher\r
+ priority task, and ensure we get the value from the queue. */\r
+ vTaskPrioritySet( NULL, intqHIGHER_PRIORITY + 1 );\r
+ \r
+ if( xQueueReceive( xNormallyFullQueue, &uxValue, portMAX_DELAY ) != pdPASS )\r
+ {\r
+ prvQueueAccessLogError( __LINE__ );\r
+ }\r
+ else\r
+ {\r
+ prvRecordValue_NormallyFull( uxValue, intqLOW_PRIROITY_TASK );\r
+ }\r
+ \r
+ vTaskPrioritySet( NULL, intqLOWER_PRIORITY );\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xFirstTimerHandler( void )\r
+{\r
+portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE, uxRxedValue;\r
+static unsigned portBASE_TYPE uxNextOperation = 0;\r
+\r
+ uxNextOperation++;\r
+ \r
+ if( uxNextOperation & ( unsigned portBASE_TYPE ) 0x01 )\r
+ {\r
+ timerNORMALLY_EMPTY_TX();\r
+ timerNORMALLY_EMPTY_TX(); \r
+ timerNORMALLY_EMPTY_TX();\r
+ }\r
+ else\r
+ {\r
+ timerNORMALLY_FULL_RX();\r
+ timerNORMALLY_FULL_RX();\r
+ timerNORMALLY_FULL_RX();\r
+ }\r
+ \r
+ return xHigherPriorityTaskWoken;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xSecondTimerHandler( void )\r
+{\r
+unsigned portBASE_TYPE uxRxedValue;\r
+portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
+static unsigned portBASE_TYPE uxNextOperation = 0;\r
+\r
+ uxNextOperation++;\r
+ \r
+ if( uxNextOperation & ( unsigned portBASE_TYPE ) 0x01 )\r
+ {\r
+ timerNORMALLY_EMPTY_TX();\r
+ timerNORMALLY_EMPTY_TX();\r
+\r
+ timerNORMALLY_EMPTY_RX();\r
+ timerNORMALLY_EMPTY_RX();\r
+ }\r
+ else\r
+ { \r
+ timerNORMALLY_FULL_RX();\r
+ timerNORMALLY_FULL_TX();\r
+ timerNORMALLY_FULL_TX();\r
+ timerNORMALLY_FULL_TX();\r
+ timerNORMALLY_FULL_TX();\r
+ }\r
+ \r
+ return xHigherPriorityTaskWoken;\r
+}\r
+\r
+\r