]> begriffs open source - freertos/blob - Demo/Common/Minimal/IntQueue.c
Add new test file.
[freertos] / Demo / Common / Minimal / IntQueue.c
1 /*\r
2         FreeRTOS.org V5.0.0 - Copyright (C) 2003-2008 Richard Barry.\r
3 \r
4         This file is part of the FreeRTOS.org distribution.\r
5 \r
6         FreeRTOS.org is free software; you can redistribute it and/or modify\r
7         it under the terms of the GNU General Public License as published by\r
8         the Free Software Foundation; either version 2 of the License, or\r
9         (at your option) any later version.\r
10 \r
11         FreeRTOS.org is distributed in the hope that it will be useful,\r
12         but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14         GNU General Public License for more details.\r
15 \r
16         You should have received a copy of the GNU General Public License\r
17         along with FreeRTOS.org; if not, write to the Free Software\r
18         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19 \r
20         A special exception to the GPL can be applied should you wish to distribute\r
21         a combined work that includes FreeRTOS.org, without being obliged to provide\r
22         the source code for any proprietary components.  See the licensing section\r
23         of http://www.FreeRTOS.org for full details of how and when the exception\r
24         can be applied.\r
25 \r
26     ***************************************************************************\r
27     ***************************************************************************\r
28     *                                                                         *\r
29     * SAVE TIME AND MONEY!  We can port FreeRTOS.org to your own hardware,    *\r
30     * and even write all or part of your application on your behalf.          *\r
31     * See http://www.OpenRTOS.com for details of the services we provide to   *\r
32     * expedite your project.                                                  *\r
33     *                                                                         *\r
34     ***************************************************************************\r
35     ***************************************************************************\r
36 \r
37         Please ensure to read the configuration and relevant port sections of the\r
38         online documentation.\r
39 \r
40         http://www.FreeRTOS.org - Documentation, latest information, license and \r
41         contact details.\r
42 \r
43         http://www.SafeRTOS.com - A version that is certified for use in safety \r
44         critical systems.\r
45 \r
46         http://www.OpenRTOS.com - Commercial support, development, porting, \r
47         licensing and training services.\r
48 */\r
49 \r
50 /* Standard includes. */\r
51 #include <string.h>\r
52 \r
53 /* SafeRTOS includes. */\r
54 #include "FreeRTOS.h"\r
55 #include "queue.h"\r
56 #include "task.h"\r
57 \r
58 /* Demo app includes. */\r
59 #include "IntQueue.h"\r
60 #include "IntQueueTimer.h"\r
61 \r
62 /* Priorities used by test tasks. */\r
63 #define intqHIGHER_PRIORITY             1\r
64 #define intqLOWER_PRIORITY              0\r
65 \r
66 /* The number of values to send/receive before checking that all values were\r
67 processed as expected. */\r
68 #define intqNUM_VALUES_TO_LOG   ( 200 )\r
69 #define intqSHORT_DELAY                 ( 75 )\r
70 \r
71 /* The delay used by the polling task.  A short delay is used for code \r
72 coverage. */\r
73 #define intqONE_TICK_DELAY              ( 1 )\r
74 \r
75 #define intqHIGH_PRIROITY_TASK1 ( ( unsigned portBASE_TYPE ) 1 )\r
76 #define intqHIGH_PRIROITY_TASK2 ( ( unsigned portBASE_TYPE ) 2 )\r
77 #define intqLOW_PRIROITY_TASK   ( ( unsigned portBASE_TYPE ) 3 )\r
78 #define intqFIRST_INTERRUPT             ( ( unsigned portBASE_TYPE ) 4 )\r
79 #define intqSECOND_INTERRUPT    ( ( unsigned portBASE_TYPE ) 5 )\r
80 #define intqQUEUE_LENGTH                ( ( unsigned portBASE_TYPE ) 10 )\r
81 \r
82 \r
83 #define intqMIN_ACCEPTABLE_TASK_COUNT           ( 5 )\r
84 \r
85 \r
86 #define timerNORMALLY_EMPTY_TX()                                                                                                                                                                                        \\r
87         if( xQueueIsQueueFullFromISR( xNormallyEmptyQueue ) != pdTRUE )                                                                                                                 \\r
88         {                                                                                                                                                                                                                                               \\r
89         unsigned portBASE_TYPE uxSavedInterruptStatus;                                                                                                                                                  \\r
90                 uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();                                                                                                                     \\r
91                 {                                                                                                                                                                                                                                       \\r
92                         xQueueSendFromISR( xNormallyEmptyQueue, ( void * ) &uxValueForNormallyEmptyQueue, &xHigherPriorityTaskWoken );  \\r
93                         uxValueForNormallyEmptyQueue++;                                                                                                                                                                 \\r
94                 }                                                                                                                                                                                                                                       \\r
95                 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );                                                                                                            \\r
96         }                                                                                                                                                                                                                                               \\r
97 \r
98 #define timerNORMALLY_FULL_TX()                                                                                                                                                                                         \\r
99         if( xQueueIsQueueFullFromISR( xNormallyFullQueue ) != pdTRUE )                                                                                                                  \\r
100         {                                                                                                                                                                                                                                               \\r
101         unsigned portBASE_TYPE uxSavedInterruptStatus;                                                                                                                                                  \\r
102                 uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();                                                                                                                     \\r
103                 {                                                                                                                                                                                                                                       \\r
104                         xQueueSendFromISR( xNormallyFullQueue, ( void * ) &uxValueForNormallyFullQueue, &xHigherPriorityTaskWoken );    \\r
105                         uxValueForNormallyFullQueue++;                                                                                                                                                                  \\r
106                 }                                                                                                                                                                                                                                       \\r
107                 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );                                                                                                            \\r
108         }                                                                                                                                                                                                                                               \\r
109 \r
110 #define timerNORMALLY_EMPTY_RX()                                                                                                                                                        \\r
111         if( xQueueReceiveFromISR( xNormallyEmptyQueue, &uxRxedValue, &xHigherPriorityTaskWoken ) != pdPASS )    \\r
112         {                                                                                                                                                                                                               \\r
113                 prvQueueAccessLogError( __LINE__ );                                                                                                                                     \\r
114         }                                                                                                                                                                                                               \\r
115         else                                                                                                                                                                                                    \\r
116         {                                                                                                                                                                                                               \\r
117                 prvRecordValue_NormallyEmpty( uxRxedValue, intqSECOND_INTERRUPT );                                                                      \\r
118         }\r
119 \r
120 #define timerNORMALLY_FULL_RX()                                                                                                                                                         \\r
121         if( xQueueReceiveFromISR( xNormallyFullQueue, &uxRxedValue, &xHigherPriorityTaskWoken ) == pdPASS )             \\r
122         {                                                                                                                                                                                                               \\r
123                 prvRecordValue_NormallyFull( uxRxedValue, intqSECOND_INTERRUPT );                                                                       \\r
124         }                                                                                                                                                                                                               \\r
125 \r
126 \r
127 \r
128 \r
129 /*-----------------------------------------------------------*/\r
130 \r
131 /* The two queues used by the test. */\r
132 static xQueueHandle xNormallyEmptyQueue, xNormallyFullQueue;\r
133 \r
134 /* Variables used to detect a stall in one of the tasts. */\r
135 static unsigned portBASE_TYPE uxHighPriorityLoops1 = 0, uxHighPriorityLoops2 = 0, uxLowPriorityLoops1 = 0, uxLowPriorityLoops2 = 0;\r
136 \r
137 /* Any unexpected behaviour sets xErrorStatus to fail and log the line that\r
138 caused the error in xErrorLine. */\r
139 static portBASE_TYPE xErrorStatus = pdPASS;\r
140 static unsigned portBASE_TYPE xErrorLine = ( unsigned portBASE_TYPE ) 0;\r
141 \r
142 static portBASE_TYPE xWasSuspended = pdFALSE;\r
143 \r
144 /* The values that are sent to the queues.  An incremented value is sent each\r
145 time to each queue. */\r
146 volatile unsigned portBASE_TYPE uxValueForNormallyEmptyQueue = 0, uxValueForNormallyFullQueue = 0;\r
147 \r
148 /* A handle to some of the tasks is required so they can be suspended/resumed. */\r
149 xTaskHandle xHighPriorityNormallyEmptyTask1, xHighPriorityNormallyEmptyTask2, xHighPriorityNormallyFullTask1, xHighPriorityNormallyFullTask2;\r
150 \r
151 /* When a value is received in a queue the value is ticked off in the array\r
152 the array position of the vlaue is set to a 1.  This way missing or duplicate\r
153 values can be detected. */\r
154 static unsigned portCHAR ucNormallyEmptyReceivedValues[ intqNUM_VALUES_TO_LOG ] = { 0 };\r
155 static unsigned portCHAR ucNormallyFullReceivedValues[ intqNUM_VALUES_TO_LOG ] = { 0 };\r
156 \r
157 /* The test tasks themselves. */\r
158 static void prvLowerPriorityNormallyEmptyTask( void *pvParameters );\r
159 static void prvLowerPriorityNormallyFullTask( void *pvParameters );\r
160 static void prvHigherPriorityNormallyEmptyTask( void *pvParameters );\r
161 static void prv1stHigherPriorityNormallyFullTask( void *pvParameters );\r
162 static void prv2ndHigherPriorityNormallyFullTask( void *pvParameters );\r
163 \r
164 static void prvRecordValue_NormallyEmpty( unsigned portBASE_TYPE uxValue, unsigned portBASE_TYPE uxSource );\r
165 static void prvRecordValue_NormallyFull( unsigned portBASE_TYPE uxValue, unsigned portBASE_TYPE uxSource );\r
166 \r
167 /* Logs the line on which an error occurred. */\r
168 static void prvQueueAccessLogError( unsigned portBASE_TYPE uxLine );\r
169 \r
170 /*-----------------------------------------------------------*/\r
171 \r
172 void vStartInterruptQueueTasks( void )\r
173 {\r
174         /* Start the test tasks. */\r
175         xTaskCreate( prvHigherPriorityNormallyEmptyTask, ( signed portCHAR * ) "H1QRx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIROITY_TASK1, intqHIGHER_PRIORITY, &xHighPriorityNormallyEmptyTask1 );\r
176         xTaskCreate( prvHigherPriorityNormallyEmptyTask, ( signed portCHAR * ) "H2QRx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIROITY_TASK2, intqHIGHER_PRIORITY, &xHighPriorityNormallyEmptyTask2 );\r
177         xTaskCreate( prvLowerPriorityNormallyEmptyTask, ( signed portCHAR * ) "LQRx", configMINIMAL_STACK_SIZE, NULL, intqLOWER_PRIORITY, NULL );\r
178         xTaskCreate( prv1stHigherPriorityNormallyFullTask, ( signed portCHAR * ) "H1QTx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIROITY_TASK1, intqHIGHER_PRIORITY, &xHighPriorityNormallyFullTask1 );\r
179         xTaskCreate( prv2ndHigherPriorityNormallyFullTask, ( signed portCHAR * ) "H1QTx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIROITY_TASK2, intqHIGHER_PRIORITY, &xHighPriorityNormallyFullTask2 );\r
180         xTaskCreate( prvLowerPriorityNormallyFullTask, ( signed portCHAR * ) "LQRx", configMINIMAL_STACK_SIZE, NULL, intqLOWER_PRIORITY, NULL );\r
181 \r
182         /* Create the queues that are accessed by multiple tasks and multiple \r
183         interrupts. */\r
184         xNormallyFullQueue = xQueueCreate( intqQUEUE_LENGTH, ( unsigned portBASE_TYPE ) sizeof( unsigned portBASE_TYPE ) );\r
185         xNormallyEmptyQueue = xQueueCreate( intqQUEUE_LENGTH, ( unsigned portBASE_TYPE ) sizeof( unsigned portBASE_TYPE ) );\r
186 }\r
187 /*-----------------------------------------------------------*/\r
188 \r
189 static void prvRecordValue_NormallyFull( unsigned portBASE_TYPE uxValue, unsigned portBASE_TYPE uxSource )\r
190 {\r
191         if( uxValue < intqNUM_VALUES_TO_LOG )\r
192         {\r
193                 /* We don't expect to receive the same value twice, so if the value\r
194                 has already been marked as recieved an error has occurred. */\r
195                 if( ucNormallyFullReceivedValues[ uxValue ] != 0x00 )\r
196                 {\r
197                         prvQueueAccessLogError( __LINE__ );\r
198                 }\r
199                 \r
200                 /* Log that this value has been received. */\r
201                 ucNormallyFullReceivedValues[ uxValue ] = uxSource;\r
202         }\r
203 }\r
204 /*-----------------------------------------------------------*/\r
205 \r
206 static void prvRecordValue_NormallyEmpty( unsigned portBASE_TYPE uxValue, unsigned portBASE_TYPE uxSource )\r
207 {\r
208         if( uxValue < intqNUM_VALUES_TO_LOG )\r
209         {\r
210                 /* We don't expect to receive the same value twice, so if the value\r
211                 has already been marked as recieved an error has occurred. */\r
212                 if( ucNormallyEmptyReceivedValues[ uxValue ] != 0x00 )\r
213                 {\r
214                         prvQueueAccessLogError( __LINE__ );\r
215                 }\r
216                 \r
217                 /* Log that this value has been received. */\r
218                 ucNormallyEmptyReceivedValues[ uxValue ] = uxSource;\r
219         }\r
220 }\r
221 /*-----------------------------------------------------------*/\r
222 \r
223 static void prvQueueAccessLogError( unsigned portBASE_TYPE uxLine )\r
224 {\r
225         /* Latch the line number that caused the error. */\r
226         xErrorLine = uxLine;\r
227         xErrorStatus = pdFAIL;\r
228 }\r
229 /*-----------------------------------------------------------*/\r
230 \r
231 static void prvHigherPriorityNormallyEmptyTask( void *pvParameters )\r
232 {\r
233 unsigned portBASE_TYPE uxRxed, ux, uxTask1, uxTask2;\r
234 \r
235         /* The timer should not be started until after the scheduler has started. \r
236         More than one task is running this code so we check the parameter value\r
237         to determine which task should start the timer. */\r
238         if( ( unsigned portBASE_TYPE ) pvParameters == intqHIGH_PRIROITY_TASK1 )\r
239         {\r
240                 vInitialiseTimerForIntQueueTest();\r
241         }\r
242 \r
243         for( ;; )\r
244         {\r
245                 /* Block waiting to receive a value from the normally empty queue.\r
246                 Interrupts will write to the queue so we should receive a value. */\r
247                 if( xQueueReceive( xNormallyEmptyQueue, &uxRxed, intqSHORT_DELAY ) != pdPASS )\r
248                 {\r
249                         prvQueueAccessLogError( __LINE__ );\r
250                 }\r
251                 else\r
252                 {\r
253                         /* Note which value was received so we can check all expected\r
254                         values are received and no values are duplicated. */\r
255                         prvRecordValue_NormallyEmpty( uxRxed, ( unsigned portBASE_TYPE ) pvParameters );\r
256                 }\r
257                 \r
258                 /* Ensure the other task running this code gets a chance to execute. */\r
259                 taskYIELD();\r
260                 \r
261                 if( ( unsigned portBASE_TYPE ) pvParameters == intqHIGH_PRIROITY_TASK1 )\r
262                 {\r
263                         /* Have we received all the expected values? */\r
264                         if( uxValueForNormallyEmptyQueue > ( intqNUM_VALUES_TO_LOG + 50 ) )\r
265                         {\r
266                                 vTaskSuspend( xHighPriorityNormallyEmptyTask2 );\r
267                                 \r
268                                 uxTask1 = 0;\r
269                                 uxTask2 = 0;\r
270                 \r
271                                 /* Loop through the array, checking that both tasks have\r
272                                 placed values into the array, and that no values are missing. */\r
273                                 for( ux = 0; ux < intqNUM_VALUES_TO_LOG; ux++ )\r
274                                 {\r
275                                         if( ucNormallyEmptyReceivedValues[ ux ] == 0 )\r
276                                         {\r
277                                                 /* A value is missing. */\r
278                                                 prvQueueAccessLogError( __LINE__ );\r
279                                         }\r
280                                         else\r
281                                         {\r
282                                                 if( ucNormallyEmptyReceivedValues[ ux ] == intqHIGH_PRIROITY_TASK1 )\r
283                                                 {\r
284                                                         /* Value was placed into the array by task 1. */\r
285                                                         uxTask1++;\r
286                                                 }\r
287                                                 else if( ucNormallyEmptyReceivedValues[ ux ] == intqHIGH_PRIROITY_TASK2 )\r
288                                                 {\r
289                                                         /* Value was placed into the array by task 2. */\r
290                                                         uxTask2++;\r
291                                                 }\r
292                                         }\r
293                                 }\r
294                                 \r
295                                 if( uxTask1 < intqMIN_ACCEPTABLE_TASK_COUNT )\r
296                                 {\r
297                                         /* Only task 2 seemed to log any values. */\r
298                                         prvQueueAccessLogError( __LINE__ );\r
299                                 }\r
300                                 \r
301                                 if( uxTask2 < intqMIN_ACCEPTABLE_TASK_COUNT  )\r
302                                 {\r
303                                         /* Only task 1 seemed to log any values. */\r
304                                         prvQueueAccessLogError( __LINE__ );\r
305                                 }\r
306 \r
307                                 /* Clear the array again, ready to start a new cycle. */\r
308                                 memset( ucNormallyEmptyReceivedValues, 0x00, sizeof( ucNormallyEmptyReceivedValues ) );\r
309                                 \r
310                                 uxHighPriorityLoops1++;\r
311                                 uxValueForNormallyEmptyQueue = 0;\r
312 \r
313                                 /* Suspend ourselves, allowing the lower priority task to \r
314                                 actually receive something from the queue.  Until now it\r
315                                 will have been prevented from doing so by the higher\r
316                                 priority tasks.  The lower priority task will resume us\r
317                                 if it receives something.  We will then resume the other\r
318                                 higher priority task. */\r
319                                 vTaskSuspend( NULL );           \r
320                                 vTaskResume( xHighPriorityNormallyEmptyTask2 );\r
321                         }\r
322                 }\r
323         }\r
324 }\r
325 /*-----------------------------------------------------------*/\r
326 \r
327 static void prvLowerPriorityNormallyEmptyTask( void *pvParameters )\r
328 {\r
329 unsigned portBASE_TYPE uxValue, uxRxed;\r
330 portBASE_TYPE xQueueStatus;\r
331 \r
332         /* The paramters are not being used so avoid compiler warnings. */\r
333         ( void ) pvParameters;\r
334         \r
335         for( ;; )\r
336         {       \r
337                 if( ( xQueueStatus = xQueueReceive( xNormallyEmptyQueue, &uxRxed, intqONE_TICK_DELAY ) ) != errQUEUE_EMPTY )\r
338                 {\r
339                         /* We should only obtain a value when the high priority task is\r
340                         suspended. */\r
341                         if( xTaskIsTaskSuspended( xHighPriorityNormallyEmptyTask1 ) == pdFALSE )\r
342                         {\r
343                                 prvQueueAccessLogError( __LINE__ );\r
344                         }\r
345 \r
346                         prvRecordValue_NormallyEmpty( uxRxed, intqLOW_PRIROITY_TASK );\r
347                         \r
348                         /* Wake the higher priority task again. */\r
349                         vTaskResume( xHighPriorityNormallyEmptyTask1 );\r
350                         uxLowPriorityLoops1++;\r
351                 }\r
352                 else\r
353                 {\r
354                         /* Raise our priority while we send so we can preempt the higher\r
355                         priority task, and ensure we get the Tx value into the queue. */\r
356                         vTaskPrioritySet( NULL, intqHIGHER_PRIORITY + 1 );\r
357                         \r
358                         portENTER_CRITICAL();\r
359                         {\r
360                                 uxValue = uxValueForNormallyEmptyQueue;\r
361                                 uxValueForNormallyEmptyQueue++;\r
362                         }\r
363                         portEXIT_CRITICAL();\r
364                         \r
365                         if( xQueueSend( xNormallyEmptyQueue, &uxValue, portMAX_DELAY ) != pdPASS )\r
366                         {\r
367                                 prvQueueAccessLogError( __LINE__ );\r
368                         }\r
369                         \r
370                         vTaskPrioritySet( NULL, intqLOWER_PRIORITY );\r
371                 }\r
372         }\r
373 }\r
374 /*-----------------------------------------------------------*/\r
375 \r
376 portBASE_TYPE xAreIntQueueTasksStillRunning( void )\r
377 {\r
378 static unsigned portBASE_TYPE uxLastHighPriorityLoops1 = 0, uxLastHighPriorityLoops2 = 0, uxLastLowPriorityLoops1 = 0, uxLastLowPriorityLoops2 = 0;\r
379         \r
380         if( uxHighPriorityLoops1 == uxLastHighPriorityLoops1 )\r
381         {\r
382                 prvQueueAccessLogError( __LINE__ );\r
383         }\r
384         \r
385         uxLastHighPriorityLoops1 = uxHighPriorityLoops1;\r
386         \r
387         if( uxHighPriorityLoops2 == uxLastHighPriorityLoops2 )\r
388         {\r
389                 prvQueueAccessLogError( __LINE__ );\r
390         }\r
391         \r
392         uxLastHighPriorityLoops2 = uxHighPriorityLoops2;\r
393         \r
394         if( uxLowPriorityLoops1 == uxLastLowPriorityLoops1 )\r
395         {\r
396                 prvQueueAccessLogError( __LINE__ );\r
397         }\r
398 \r
399         uxLastLowPriorityLoops1 = uxLowPriorityLoops1;\r
400 \r
401         if( uxLowPriorityLoops2 == uxLastLowPriorityLoops2 )\r
402         {\r
403                 prvQueueAccessLogError( __LINE__ );\r
404         }\r
405 \r
406         uxLastLowPriorityLoops2 = uxLowPriorityLoops2;\r
407 \r
408         return xErrorStatus;\r
409 }\r
410 /*-----------------------------------------------------------*/\r
411 \r
412 static void prv1stHigherPriorityNormallyFullTask( void *pvParameters )\r
413 {\r
414 unsigned portBASE_TYPE uxValueToTx, ux;\r
415 portBASE_TYPE xQueueStatus;\r
416 \r
417         /* The paramters are not being used so avoid compiler warnings. */\r
418         ( void ) pvParameters;\r
419         \r
420         /* Make sure the queue starts full or near full.  >> 1 as there are two\r
421         high priority tasks. */\r
422         for( ux = 0; ux < ( intqQUEUE_LENGTH >> 1 ); ux++ )\r
423         {\r
424                 portENTER_CRITICAL();\r
425                 {\r
426                         uxValueToTx = uxValueForNormallyFullQueue;\r
427                         uxValueForNormallyFullQueue++;\r
428                 }\r
429                 portEXIT_CRITICAL();\r
430 \r
431                 xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY );                \r
432         }\r
433 \r
434         for( ;; )\r
435         {\r
436                 portENTER_CRITICAL();\r
437                 {\r
438                         uxValueToTx = uxValueForNormallyFullQueue;\r
439                         uxValueForNormallyFullQueue++;\r
440                 }\r
441                 portEXIT_CRITICAL();\r
442 \r
443                 if( ( xQueueStatus = xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ) ) != pdPASS )\r
444                 {\r
445                         /* intqHIGH_PRIROITY_TASK2 is never suspended so we would not \r
446                         expect it to ever time out. */\r
447                         prvQueueAccessLogError( __LINE__ );\r
448                 }\r
449 \r
450                 /* Allow the other task running this code to run. */\r
451                 taskYIELD();\r
452                 \r
453                 /* Have all the expected values been sent to the queue? */\r
454                 if( uxValueToTx > ( intqNUM_VALUES_TO_LOG + 50 ) )\r
455                 {\r
456                         /* Make sure the other high priority task completes its send of\r
457                         any values below intqNUM_VALUE_TO_LOG. */\r
458                         vTaskDelay( intqSHORT_DELAY );\r
459                         \r
460                         vTaskSuspend( xHighPriorityNormallyFullTask2 );\r
461                         \r
462                         if( xWasSuspended == pdTRUE )\r
463                         {\r
464                                 /* We would have expected the other high pririty task to have\r
465                                 set this back to false by now. */\r
466                                 prvQueueAccessLogError( __LINE__ );\r
467                         }\r
468                         \r
469                         /* Set the suspended flag so an error is not logged if the other\r
470                         task recognises a time out when it is unsuspended. */\r
471                         xWasSuspended = pdTRUE;\r
472         \r
473                         for( ux = 0; ux < intqNUM_VALUES_TO_LOG; ux++ )\r
474                         {\r
475                                 if( ucNormallyFullReceivedValues[ ux ] == 0 )\r
476                                 {\r
477                                         /* A value was missing. */\r
478                                         prvQueueAccessLogError( __LINE__ );\r
479                                 }\r
480                         }                               \r
481 \r
482                         /* Reset the array ready for the next cycle. */\r
483                         memset( ucNormallyFullReceivedValues, 0x00, sizeof( ucNormallyFullReceivedValues ) );                           \r
484                         \r
485                         uxHighPriorityLoops2++;\r
486                         uxValueForNormallyFullQueue = 0;\r
487 \r
488                         /* Suspend ourselves, allowing the lower priority task to \r
489                         actually receive something from the queue.  Until now it\r
490                         will have been prevented from doing so by the higher\r
491                         priority tasks.  The lower priority task will resume us\r
492                         if it receives something.  We will then resume the other\r
493                         higher priority task. */\r
494                         vTaskSuspend( NULL );   \r
495                         vTaskResume( xHighPriorityNormallyFullTask2 );\r
496                 }\r
497         }\r
498 }\r
499 /*-----------------------------------------------------------*/\r
500 \r
501 static void prv2ndHigherPriorityNormallyFullTask( void *pvParameters )\r
502 {\r
503 unsigned portBASE_TYPE uxValueToTx, ux;\r
504 portBASE_TYPE xQueueStatus;\r
505 \r
506         /* The paramters are not being used so avoid compiler warnings. */\r
507         ( void ) pvParameters;\r
508         \r
509         /* Make sure the queue starts full or near full.  >> 1 as there are two\r
510         high priority tasks. */\r
511         for( ux = 0; ux < ( intqQUEUE_LENGTH >> 1 ); ux++ )\r
512         {\r
513                 portENTER_CRITICAL();\r
514                 {\r
515                         uxValueToTx = uxValueForNormallyFullQueue;\r
516                         uxValueForNormallyFullQueue++;\r
517                 }\r
518                 portEXIT_CRITICAL();\r
519 \r
520                 xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY );                \r
521         }\r
522 \r
523         for( ;; )\r
524         {\r
525                 portENTER_CRITICAL();\r
526                 {\r
527                         uxValueToTx = uxValueForNormallyFullQueue;\r
528                         uxValueForNormallyFullQueue++;\r
529                 }\r
530                 portEXIT_CRITICAL();\r
531 \r
532                 if( ( xQueueStatus = xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ) ) != pdPASS )\r
533                 {\r
534                         if( xWasSuspended != pdTRUE )\r
535                         {\r
536                                 /* It is ok to time out if the task has been suspended. */\r
537                                 prvQueueAccessLogError( __LINE__ );\r
538                         }\r
539                 }\r
540 \r
541                 xWasSuspended = pdFALSE;\r
542                 \r
543                 taskYIELD();\r
544         }\r
545 }\r
546 /*-----------------------------------------------------------*/\r
547 \r
548 static void prvLowerPriorityNormallyFullTask( void *pvParameters )\r
549 {\r
550 unsigned portBASE_TYPE uxValue, uxTxed = 9999;\r
551 portBASE_TYPE xQueueStatus;\r
552 \r
553         /* The paramters are not being used so avoid compiler warnings. */\r
554         ( void ) pvParameters;\r
555         \r
556         for( ;; )\r
557         {       \r
558                 if( ( xQueueStatus = xQueueSend( xNormallyFullQueue, &uxTxed, intqONE_TICK_DELAY ) ) != errQUEUE_FULL )\r
559                 {\r
560                         /* We would only expect to succeed when the higher priority task\r
561                         is suspended. */\r
562                         if( xTaskIsTaskSuspended( xHighPriorityNormallyFullTask1 ) == pdFALSE )\r
563                         {\r
564                                 prvQueueAccessLogError( __LINE__ );\r
565                         }\r
566 \r
567                         vTaskResume( xHighPriorityNormallyFullTask1 );\r
568                         uxLowPriorityLoops2++;\r
569                 }\r
570                 else\r
571                 {\r
572                         /* Raise our priority while we receive so we can preempt the higher\r
573                         priority task, and ensure we get the value from the queue. */\r
574                         vTaskPrioritySet( NULL, intqHIGHER_PRIORITY + 1 );\r
575                         \r
576                         if( xQueueReceive( xNormallyFullQueue, &uxValue, portMAX_DELAY ) != pdPASS )\r
577                         {\r
578                                 prvQueueAccessLogError( __LINE__ );\r
579                         }\r
580                         else\r
581                         {\r
582                                 prvRecordValue_NormallyFull( uxValue, intqLOW_PRIROITY_TASK );\r
583                         }\r
584                         \r
585                         vTaskPrioritySet( NULL, intqLOWER_PRIORITY );\r
586                 }\r
587         }\r
588 }\r
589 /*-----------------------------------------------------------*/\r
590 \r
591 portBASE_TYPE xFirstTimerHandler( void )\r
592 {\r
593 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE, uxRxedValue;\r
594 static unsigned portBASE_TYPE uxNextOperation = 0;\r
595 \r
596         uxNextOperation++;\r
597         \r
598         if( uxNextOperation & ( unsigned portBASE_TYPE ) 0x01 )\r
599         {\r
600                 timerNORMALLY_EMPTY_TX();\r
601                 timerNORMALLY_EMPTY_TX();       \r
602                 timerNORMALLY_EMPTY_TX();\r
603         }\r
604         else\r
605         {\r
606                 timerNORMALLY_FULL_RX();\r
607                 timerNORMALLY_FULL_RX();\r
608                 timerNORMALLY_FULL_RX();\r
609         }\r
610         \r
611         return xHigherPriorityTaskWoken;\r
612 }\r
613 /*-----------------------------------------------------------*/\r
614 \r
615 portBASE_TYPE xSecondTimerHandler( void )\r
616 {\r
617 unsigned portBASE_TYPE uxRxedValue;\r
618 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
619 static unsigned portBASE_TYPE uxNextOperation = 0;\r
620 \r
621         uxNextOperation++;\r
622         \r
623         if( uxNextOperation & ( unsigned portBASE_TYPE ) 0x01 )\r
624         {\r
625                 timerNORMALLY_EMPTY_TX();\r
626                 timerNORMALLY_EMPTY_TX();\r
627 \r
628                 timerNORMALLY_EMPTY_RX();\r
629                 timerNORMALLY_EMPTY_RX();\r
630         }\r
631         else\r
632         {       \r
633                 timerNORMALLY_FULL_RX();\r
634                 timerNORMALLY_FULL_TX();\r
635                 timerNORMALLY_FULL_TX();\r
636                 timerNORMALLY_FULL_TX();\r
637                 timerNORMALLY_FULL_TX();\r
638         }\r
639         \r
640         return xHigherPriorityTaskWoken;\r
641 }\r
642 \r
643 \r