From 7bb27701b9c63929549dfeb9095dea440b4e9d31 Mon Sep 17 00:00:00 2001 From: RichardBarry Date: Sun, 18 May 2008 19:57:01 +0000 Subject: [PATCH] Tidy up. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@357 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- Demo/Common/Minimal/IntQueue.c | 152 ++++++++++++++++++++++----------- 1 file changed, 100 insertions(+), 52 deletions(-) diff --git a/Demo/Common/Minimal/IntQueue.c b/Demo/Common/Minimal/IntQueue.c index 02753ef50..e71df3b32 100644 --- a/Demo/Common/Minimal/IntQueue.c +++ b/Demo/Common/Minimal/IntQueue.c @@ -47,6 +47,21 @@ licensing and training services. */ +/* + * This file defines one of the more complex set of demo/test tasks. They are + * designed to stress test the queue implementation though pseudo simultaneous + * multiple reads and multiple writes from both tasks of varying priority and + * interrupts. The interrupts are prioritised such to ensure that nesting + * occurs (for those ports that support it). + * + * The test ensures that, while being accessed from three tasks and two + * interrupts, all the data sent to the queues is also received from + * the same queue, and that no duplicate items are either sent or received. + * The tests also ensure that a low priority task is never able to successfully + * read from or write to a queue when a task of higher priority is attempting + * the same operation. + */ + /* Standard includes. */ #include @@ -68,10 +83,20 @@ processed as expected. */ #define intqNUM_VALUES_TO_LOG ( 200 ) #define intqSHORT_DELAY ( 75 ) +/* The value by which the value being sent to or received from a queue should +increment past intqNUM_VALUES_TO_LOG before we check that all values have been +sent/received correctly. This is done to ensure that all tasks and interrupts +accessing the queue have completed their accesses with the +intqNUM_VALUES_TO_LOG range. */ +#define intqVALUE_OVERRUN ( 50 ) + /* The delay used by the polling task. A short delay is used for code coverage. */ #define intqONE_TICK_DELAY ( 1 ) +/* Each task and interrupt is given a unique identifier. This value is used to +identify which task sent or received each value. The identifier is also used +to distinguish between two tasks that are running the same task function. */ #define intqHIGH_PRIROITY_TASK1 ( ( unsigned portBASE_TYPE ) 1 ) #define intqHIGH_PRIROITY_TASK2 ( ( unsigned portBASE_TYPE ) 2 ) #define intqLOW_PRIROITY_TASK ( ( unsigned portBASE_TYPE ) 3 ) @@ -79,10 +104,12 @@ coverage. */ #define intqSECOND_INTERRUPT ( ( unsigned portBASE_TYPE ) 5 ) #define intqQUEUE_LENGTH ( ( unsigned portBASE_TYPE ) 10 ) - +/* At least intqMIN_ACCEPTABLE_TASK_COUNT values should be sent to/received +from each queue by each task, otherwise an error is detected. */ #define intqMIN_ACCEPTABLE_TASK_COUNT ( 5 ) - +/* Send the next value to the queue that is normally empty. This is called +from within the interrupts. */ #define timerNORMALLY_EMPTY_TX() \ if( xQueueIsQueueFullFromISR( xNormallyEmptyQueue ) != pdTRUE ) \ { \ @@ -95,6 +122,8 @@ coverage. */ portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ } \ +/* Send the next value to the queue that is normally full. This is called +from within the interrupts. */ #define timerNORMALLY_FULL_TX() \ if( xQueueIsQueueFullFromISR( xNormallyFullQueue ) != pdTRUE ) \ { \ @@ -107,6 +136,8 @@ coverage. */ portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ } \ +/* Receive a value from the normally empty queue. This is called from within +an interrupt. */ #define timerNORMALLY_EMPTY_RX() \ if( xQueueReceiveFromISR( xNormallyEmptyQueue, &uxRxedValue, &xHigherPriorityTaskWoken ) != pdPASS ) \ { \ @@ -117,6 +148,8 @@ coverage. */ prvRecordValue_NormallyEmpty( uxRxedValue, intqSECOND_INTERRUPT ); \ } +/* Receive a value from the normally full queue. This is called from within +an interrupt. */ #define timerNORMALLY_FULL_RX() \ if( xQueueReceiveFromISR( xNormallyFullQueue, &uxRxedValue, &xHigherPriorityTaskWoken ) == pdPASS ) \ { \ @@ -124,14 +157,12 @@ coverage. */ } \ - - /*-----------------------------------------------------------*/ /* The two queues used by the test. */ static xQueueHandle xNormallyEmptyQueue, xNormallyFullQueue; -/* Variables used to detect a stall in one of the tasts. */ +/* Variables used to detect a stall in one of the tasks. */ static unsigned portBASE_TYPE uxHighPriorityLoops1 = 0, uxHighPriorityLoops2 = 0, uxLowPriorityLoops1 = 0, uxLowPriorityLoops2 = 0; /* Any unexpected behaviour sets xErrorStatus to fail and log the line that @@ -139,6 +170,7 @@ caused the error in xErrorLine. */ static portBASE_TYPE xErrorStatus = pdPASS; static unsigned portBASE_TYPE xErrorLine = ( unsigned portBASE_TYPE ) 0; +/* Used for sequencing between tasks. */ static portBASE_TYPE xWasSuspended = pdFALSE; /* The values that are sent to the queues. An incremented value is sent each @@ -149,8 +181,9 @@ volatile unsigned portBASE_TYPE uxValueForNormallyEmptyQueue = 0, uxValueForNorm xTaskHandle xHighPriorityNormallyEmptyTask1, xHighPriorityNormallyEmptyTask2, xHighPriorityNormallyFullTask1, xHighPriorityNormallyFullTask2; /* When a value is received in a queue the value is ticked off in the array -the array position of the vlaue is set to a 1. This way missing or duplicate -values can be detected. */ +the array position of the value is set to a the identifier of the task or +interrupt that accessed the queue. This way missing or duplicate values can be +detected. */ static unsigned portCHAR ucNormallyEmptyReceivedValues[ intqNUM_VALUES_TO_LOG ] = { 0 }; static unsigned portCHAR ucNormallyFullReceivedValues[ intqNUM_VALUES_TO_LOG ] = { 0 }; @@ -161,6 +194,8 @@ static void prvHigherPriorityNormallyEmptyTask( void *pvParameters ); static void prv1stHigherPriorityNormallyFullTask( void *pvParameters ); static void prv2ndHigherPriorityNormallyFullTask( void *pvParameters ); +/* Used to mark the positions within the ucNormallyEmptyReceivedValues and +ucNormallyFullReceivedValues arrays, while checking for duplicates. */ static void prvRecordValue_NormallyEmpty( unsigned portBASE_TYPE uxValue, unsigned portBASE_TYPE uxSource ); static void prvRecordValue_NormallyFull( unsigned portBASE_TYPE uxValue, unsigned portBASE_TYPE uxSource ); @@ -191,7 +226,7 @@ static void prvRecordValue_NormallyFull( unsigned portBASE_TYPE uxValue, unsigne if( uxValue < intqNUM_VALUES_TO_LOG ) { /* We don't expect to receive the same value twice, so if the value - has already been marked as recieved an error has occurred. */ + has already been marked as received an error has occurred. */ if( ucNormallyFullReceivedValues[ uxValue ] != 0x00 ) { prvQueueAccessLogError( __LINE__ ); @@ -208,7 +243,7 @@ static void prvRecordValue_NormallyEmpty( unsigned portBASE_TYPE uxValue, unsign if( uxValue < intqNUM_VALUES_TO_LOG ) { /* We don't expect to receive the same value twice, so if the value - has already been marked as recieved an error has occurred. */ + has already been marked as received an error has occurred. */ if( ucNormallyEmptyReceivedValues[ uxValue ] != 0x00 ) { prvQueueAccessLogError( __LINE__ ); @@ -261,7 +296,7 @@ unsigned portBASE_TYPE uxRxed, ux, uxTask1, uxTask2; if( ( unsigned portBASE_TYPE ) pvParameters == intqHIGH_PRIROITY_TASK1 ) { /* Have we received all the expected values? */ - if( uxValueForNormallyEmptyQueue > ( intqNUM_VALUES_TO_LOG + 50 ) ) + if( uxValueForNormallyEmptyQueue > ( intqNUM_VALUES_TO_LOG + intqVALUE_OVERRUN ) ) { vTaskSuspend( xHighPriorityNormallyEmptyTask2 ); @@ -329,7 +364,7 @@ static void prvLowerPriorityNormallyEmptyTask( void *pvParameters ) unsigned portBASE_TYPE uxValue, uxRxed; portBASE_TYPE xQueueStatus; - /* The paramters are not being used so avoid compiler warnings. */ + /* The parameters are not being used so avoid compiler warnings. */ ( void ) pvParameters; for( ;; ) @@ -373,48 +408,12 @@ portBASE_TYPE xQueueStatus; } /*-----------------------------------------------------------*/ -portBASE_TYPE xAreIntQueueTasksStillRunning( void ) -{ -static unsigned portBASE_TYPE uxLastHighPriorityLoops1 = 0, uxLastHighPriorityLoops2 = 0, uxLastLowPriorityLoops1 = 0, uxLastLowPriorityLoops2 = 0; - - if( uxHighPriorityLoops1 == uxLastHighPriorityLoops1 ) - { - prvQueueAccessLogError( __LINE__ ); - } - - uxLastHighPriorityLoops1 = uxHighPriorityLoops1; - - if( uxHighPriorityLoops2 == uxLastHighPriorityLoops2 ) - { - prvQueueAccessLogError( __LINE__ ); - } - - uxLastHighPriorityLoops2 = uxHighPriorityLoops2; - - if( uxLowPriorityLoops1 == uxLastLowPriorityLoops1 ) - { - prvQueueAccessLogError( __LINE__ ); - } - - uxLastLowPriorityLoops1 = uxLowPriorityLoops1; - - if( uxLowPriorityLoops2 == uxLastLowPriorityLoops2 ) - { - prvQueueAccessLogError( __LINE__ ); - } - - uxLastLowPriorityLoops2 = uxLowPriorityLoops2; - - return xErrorStatus; -} -/*-----------------------------------------------------------*/ - static void prv1stHigherPriorityNormallyFullTask( void *pvParameters ) { unsigned portBASE_TYPE uxValueToTx, ux; portBASE_TYPE xQueueStatus; - /* The paramters are not being used so avoid compiler warnings. */ + /* The parameters are not being used so avoid compiler warnings. */ ( void ) pvParameters; /* Make sure the queue starts full or near full. >> 1 as there are two @@ -451,7 +450,7 @@ portBASE_TYPE xQueueStatus; taskYIELD(); /* Have all the expected values been sent to the queue? */ - if( uxValueToTx > ( intqNUM_VALUES_TO_LOG + 50 ) ) + if( uxValueToTx > ( intqNUM_VALUES_TO_LOG + intqVALUE_OVERRUN ) ) { /* Make sure the other high priority task completes its send of any values below intqNUM_VALUE_TO_LOG. */ @@ -461,7 +460,7 @@ portBASE_TYPE xQueueStatus; if( xWasSuspended == pdTRUE ) { - /* We would have expected the other high pririty task to have + /* We would have expected the other high priority task to have set this back to false by now. */ prvQueueAccessLogError( __LINE__ ); } @@ -503,7 +502,7 @@ static void prv2ndHigherPriorityNormallyFullTask( void *pvParameters ) unsigned portBASE_TYPE uxValueToTx, ux; portBASE_TYPE xQueueStatus; - /* The paramters are not being used so avoid compiler warnings. */ + /* The parameters are not being used so avoid compiler warnings. */ ( void ) pvParameters; /* Make sure the queue starts full or near full. >> 1 as there are two @@ -550,7 +549,7 @@ static void prvLowerPriorityNormallyFullTask( void *pvParameters ) unsigned portBASE_TYPE uxValue, uxTxed = 9999; portBASE_TYPE xQueueStatus; - /* The paramters are not being used so avoid compiler warnings. */ + /* The parameters are not being used so avoid compiler warnings. */ ( void ) pvParameters; for( ;; ) @@ -593,6 +592,9 @@ portBASE_TYPE xFirstTimerHandler( void ) portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE, uxRxedValue; static unsigned portBASE_TYPE uxNextOperation = 0; + /* Called from a timer interrupt. Perform various read and write + accesses on the queues. */ + uxNextOperation++; if( uxNextOperation & ( unsigned portBASE_TYPE ) 0x01 ) @@ -618,6 +620,9 @@ unsigned portBASE_TYPE uxRxedValue; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; static unsigned portBASE_TYPE uxNextOperation = 0; + /* Called from a timer interrupt. Perform various read and write + accesses on the queues. */ + uxNextOperation++; if( uxNextOperation & ( unsigned portBASE_TYPE ) 0x01 ) @@ -639,5 +644,48 @@ static unsigned portBASE_TYPE uxNextOperation = 0; return xHigherPriorityTaskWoken; } +/*-----------------------------------------------------------*/ + + +portBASE_TYPE xAreIntQueueTasksStillRunning( void ) +{ +static unsigned portBASE_TYPE uxLastHighPriorityLoops1 = 0, uxLastHighPriorityLoops2 = 0, uxLastLowPriorityLoops1 = 0, uxLastLowPriorityLoops2 = 0; + + /* xErrorStatus can be set outside of this function. This function just + checks that all the tasks are still cycling. */ + if( uxHighPriorityLoops1 == uxLastHighPriorityLoops1 ) + { + /* The high priority 1 task has stalled. */ + prvQueueAccessLogError( __LINE__ ); + } + + uxLastHighPriorityLoops1 = uxHighPriorityLoops1; + + if( uxHighPriorityLoops2 == uxLastHighPriorityLoops2 ) + { + /* The high priority 2 task has stalled. */ + prvQueueAccessLogError( __LINE__ ); + } + + uxLastHighPriorityLoops2 = uxHighPriorityLoops2; + + if( uxLowPriorityLoops1 == uxLastLowPriorityLoops1 ) + { + /* The low priority 1 task has stalled. */ + prvQueueAccessLogError( __LINE__ ); + } + + uxLastLowPriorityLoops1 = uxLowPriorityLoops1; + + if( uxLowPriorityLoops2 == uxLastLowPriorityLoops2 ) + { + /* The low priority 2 task has stalled. */ + prvQueueAccessLogError( __LINE__ ); + } + + uxLastLowPriorityLoops2 = uxLowPriorityLoops2; + + return xErrorStatus; +} -- 2.39.5