]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/Common/Minimal/blocktim.c
f06fe24544f96365b961900bec6a0d089c4911bd
[freertos] / FreeRTOS / Demo / Common / Minimal / blocktim.c
1 /*\r
2     FreeRTOS V9.0.0rc2 - Copyright (C) 2016 Real Time Engineers Ltd.\r
3     All rights reserved\r
4 \r
5     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
6 \r
7     This file is part of the FreeRTOS distribution.\r
8 \r
9     FreeRTOS is free software; you can redistribute it and/or modify it under\r
10     the terms of the GNU General Public License (version 2) as published by the\r
11     Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.\r
12 \r
13     ***************************************************************************\r
14     >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
15     >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
16     >>!   obliged to provide the source code for proprietary components     !<<\r
17     >>!   outside of the FreeRTOS kernel.                                   !<<\r
18     ***************************************************************************\r
19 \r
20     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
21     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
22     FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
23     link: http://www.freertos.org/a00114.html\r
24 \r
25     ***************************************************************************\r
26      *                                                                       *\r
27      *    FreeRTOS provides completely free yet professionally developed,    *\r
28      *    robust, strictly quality controlled, supported, and cross          *\r
29      *    platform software that is more than just the market leader, it     *\r
30      *    is the industry's de facto standard.                               *\r
31      *                                                                       *\r
32      *    Help yourself get started quickly while simultaneously helping     *\r
33      *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
34      *    tutorial book, reference manual, or both:                          *\r
35      *    http://www.FreeRTOS.org/Documentation                              *\r
36      *                                                                       *\r
37     ***************************************************************************\r
38 \r
39     http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading\r
40     the FAQ page "My application does not run, what could be wrong?".  Have you\r
41     defined configASSERT()?\r
42 \r
43     http://www.FreeRTOS.org/support - In return for receiving this top quality\r
44     embedded software for free we request you assist our global community by\r
45     participating in the support forum.\r
46 \r
47     http://www.FreeRTOS.org/training - Investing in training allows your team to\r
48     be as productive as possible as early as possible.  Now you can receive\r
49     FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
50     Ltd, and the world's leading authority on the world's leading RTOS.\r
51 \r
52     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
53     including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
54     compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
55 \r
56     http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
57     Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
58 \r
59     http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
60     Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
61     licenses offer ticketed support, indemnification and commercial middleware.\r
62 \r
63     http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
64     engineered and independently SIL3 certified version for use in safety and\r
65     mission critical applications that require provable dependability.\r
66 \r
67     1 tab == 4 spaces!\r
68 */\r
69 \r
70 /*\r
71  * This file contains some test scenarios that ensure tasks do not exit queue\r
72  * send or receive functions prematurely.  A description of the tests is\r
73  * included within the code.\r
74  */\r
75 \r
76 /* Kernel includes. */\r
77 #include "FreeRTOS.h"\r
78 #include "task.h"\r
79 #include "queue.h"\r
80 \r
81 /* Demo includes. */\r
82 #include "blocktim.h"\r
83 \r
84 /* Task priorities.  Allow these to be overridden. */\r
85 #ifndef bktPRIMARY_PRIORITY\r
86         #define bktPRIMARY_PRIORITY             ( configMAX_PRIORITIES - 3 )\r
87 #endif\r
88 \r
89 #ifndef bktSECONDARY_PRIORITY\r
90         #define bktSECONDARY_PRIORITY   ( configMAX_PRIORITIES - 4 )\r
91 #endif\r
92 \r
93 /* Task behaviour. */\r
94 #define bktQUEUE_LENGTH                         ( 5 )\r
95 #define bktSHORT_WAIT                           pdMS_TO_TICKS( ( TickType_t ) 20 )\r
96 #define bktPRIMARY_BLOCK_TIME           ( 10 )\r
97 #define bktALLOWABLE_MARGIN                     ( 15 )\r
98 #define bktTIME_TO_BLOCK                        ( 175 )\r
99 #define bktDONT_BLOCK                           ( ( TickType_t ) 0 )\r
100 #define bktRUN_INDICATOR                        ( ( UBaseType_t ) 0x55 )\r
101 \r
102 /*-----------------------------------------------------------*/\r
103 \r
104 /*\r
105  * The two test tasks.  Their behaviour is commented within the functions.\r
106  */\r
107 static void vPrimaryBlockTimeTestTask( void *pvParameters );\r
108 static void vSecondaryBlockTimeTestTask( void *pvParameters );\r
109 \r
110 /*\r
111  * Very basic tests to verify the block times are as expected.\r
112  */\r
113 static void prvBasicDelayTests( void );\r
114 \r
115 /*-----------------------------------------------------------*/\r
116 \r
117 /* The queue on which the tasks block. */\r
118 static QueueHandle_t xTestQueue;\r
119 \r
120 /* Handle to the secondary task is required by the primary task for calls\r
121 to vTaskSuspend/Resume(). */\r
122 static TaskHandle_t xSecondary;\r
123 \r
124 /* Used to ensure that tasks are still executing without error. */\r
125 static volatile BaseType_t xPrimaryCycles = 0, xSecondaryCycles = 0;\r
126 static volatile BaseType_t xErrorOccurred = pdFALSE;\r
127 \r
128 /* Provides a simple mechanism for the primary task to know when the\r
129 secondary task has executed. */\r
130 static volatile UBaseType_t xRunIndicator;\r
131 \r
132 /*-----------------------------------------------------------*/\r
133 \r
134 void vCreateBlockTimeTasks( void )\r
135 {\r
136         /* Create the queue on which the two tasks block. */\r
137         xTestQueue = xQueueCreate( bktQUEUE_LENGTH, sizeof( BaseType_t ) );\r
138 \r
139         if( xTestQueue != NULL )\r
140         {\r
141                 /* vQueueAddToRegistry() adds the queue to the queue registry, if one\r
142                 is in use.  The queue registry is provided as a means for kernel aware\r
143                 debuggers to locate queues and has no purpose if a kernel aware\r
144                 debugger is not being used.  The call to vQueueAddToRegistry() will be\r
145                 removed by the pre-processor if configQUEUE_REGISTRY_SIZE is not\r
146                 defined or is defined to be less than 1. */\r
147                 vQueueAddToRegistry( xTestQueue, "Block_Time_Queue" );\r
148 \r
149                 /* Create the two test tasks. */\r
150                 xTaskCreate( vPrimaryBlockTimeTestTask, "BTest1", configMINIMAL_STACK_SIZE, NULL, bktPRIMARY_PRIORITY, NULL );\r
151                 xTaskCreate( vSecondaryBlockTimeTestTask, "BTest2", configMINIMAL_STACK_SIZE, NULL, bktSECONDARY_PRIORITY, &xSecondary );\r
152         }\r
153 }\r
154 /*-----------------------------------------------------------*/\r
155 \r
156 static void vPrimaryBlockTimeTestTask( void *pvParameters )\r
157 {\r
158 BaseType_t xItem, xData;\r
159 TickType_t xTimeWhenBlocking;\r
160 TickType_t xTimeToBlock, xBlockedTime;\r
161 \r
162         ( void ) pvParameters;\r
163 \r
164         for( ;; )\r
165         {\r
166                 /*********************************************************************\r
167                 Test 0\r
168 \r
169                 Basic vTaskDelay() and vTaskDelayUntil() tests. */\r
170                 prvBasicDelayTests();\r
171 \r
172 \r
173                 /*********************************************************************\r
174                 Test 1\r
175 \r
176                 Simple block time wakeup test on queue receives. */\r
177                 for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
178                 {\r
179                         /* The queue is empty. Attempt to read from the queue using a block\r
180                         time.  When we wake, ensure the delta in time is as expected. */\r
181                         xTimeToBlock = ( TickType_t ) ( bktPRIMARY_BLOCK_TIME << xItem );\r
182 \r
183                         xTimeWhenBlocking = xTaskGetTickCount();\r
184 \r
185                         /* We should unblock after xTimeToBlock having not received\r
186                         anything on the queue. */\r
187                         if( xQueueReceive( xTestQueue, &xData, xTimeToBlock ) != errQUEUE_EMPTY )\r
188                         {\r
189                                 xErrorOccurred = pdTRUE;\r
190                         }\r
191 \r
192                         /* How long were we blocked for? */\r
193                         xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;\r
194 \r
195                         if( xBlockedTime < xTimeToBlock )\r
196                         {\r
197                                 /* Should not have blocked for less than we requested. */\r
198                                 xErrorOccurred = pdTRUE;\r
199                         }\r
200 \r
201                         if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) )\r
202                         {\r
203                                 /* Should not have blocked for longer than we requested,\r
204                                 although we would not necessarily run as soon as we were\r
205                                 unblocked so a margin is allowed. */\r
206                                 xErrorOccurred = pdTRUE;\r
207                         }\r
208                 }\r
209 \r
210                 /*********************************************************************\r
211                 Test 2\r
212 \r
213                 Simple block time wakeup test on queue sends.\r
214 \r
215                 First fill the queue.  It should be empty so all sends should pass. */\r
216                 for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
217                 {\r
218                         if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )\r
219                         {\r
220                                 xErrorOccurred = pdTRUE;\r
221                         }\r
222 \r
223                         #if configUSE_PREEMPTION == 0\r
224                                 taskYIELD();\r
225                         #endif\r
226                 }\r
227 \r
228                 for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
229                 {\r
230                         /* The queue is full. Attempt to write to the queue using a block\r
231                         time.  When we wake, ensure the delta in time is as expected. */\r
232                         xTimeToBlock = ( TickType_t ) ( bktPRIMARY_BLOCK_TIME << xItem );\r
233 \r
234                         xTimeWhenBlocking = xTaskGetTickCount();\r
235 \r
236                         /* We should unblock after xTimeToBlock having not received\r
237                         anything on the queue. */\r
238                         if( xQueueSend( xTestQueue, &xItem, xTimeToBlock ) != errQUEUE_FULL )\r
239                         {\r
240                                 xErrorOccurred = pdTRUE;\r
241                         }\r
242 \r
243                         /* How long were we blocked for? */\r
244                         xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;\r
245 \r
246                         if( xBlockedTime < xTimeToBlock )\r
247                         {\r
248                                 /* Should not have blocked for less than we requested. */\r
249                                 xErrorOccurred = pdTRUE;\r
250                         }\r
251 \r
252                         if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) )\r
253                         {\r
254                                 /* Should not have blocked for longer than we requested,\r
255                                 although we would not necessarily run as soon as we were\r
256                                 unblocked so a margin is allowed. */\r
257                                 xErrorOccurred = pdTRUE;\r
258                         }\r
259                 }\r
260 \r
261                 /*********************************************************************\r
262                 Test 3\r
263 \r
264                 Wake the other task, it will block attempting to post to the queue.\r
265                 When we read from the queue the other task will wake, but before it\r
266                 can run we will post to the queue again.  When the other task runs it\r
267                 will find the queue still full, even though it was woken.  It should\r
268                 recognise that its block time has not expired and return to block for\r
269                 the remains of its block time.\r
270 \r
271                 Wake the other task so it blocks attempting to post to the already\r
272                 full queue. */\r
273                 xRunIndicator = 0;\r
274                 vTaskResume( xSecondary );\r
275 \r
276                 /* We need to wait a little to ensure the other task executes. */\r
277                 while( xRunIndicator != bktRUN_INDICATOR )\r
278                 {\r
279                         /* The other task has not yet executed. */\r
280                         vTaskDelay( bktSHORT_WAIT );\r
281                 }\r
282                 /* Make sure the other task is blocked on the queue. */\r
283                 vTaskDelay( bktSHORT_WAIT );\r
284                 xRunIndicator = 0;\r
285 \r
286                 for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
287                 {\r
288                         /* Now when we make space on the queue the other task should wake\r
289                         but not execute as this task has higher priority. */\r
290                         if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )\r
291                         {\r
292                                 xErrorOccurred = pdTRUE;\r
293                         }\r
294 \r
295                         /* Now fill the queue again before the other task gets a chance to\r
296                         execute.  If the other task had executed we would find the queue\r
297                         full ourselves, and the other task have set xRunIndicator. */\r
298                         if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )\r
299                         {\r
300                                 xErrorOccurred = pdTRUE;\r
301                         }\r
302 \r
303                         if( xRunIndicator == bktRUN_INDICATOR )\r
304                         {\r
305                                 /* The other task should not have executed. */\r
306                                 xErrorOccurred = pdTRUE;\r
307                         }\r
308 \r
309                         /* Raise the priority of the other task so it executes and blocks\r
310                         on the queue again. */\r
311                         vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 );\r
312 \r
313                         /* The other task should now have re-blocked without exiting the\r
314                         queue function. */\r
315                         if( xRunIndicator == bktRUN_INDICATOR )\r
316                         {\r
317                                 /* The other task should not have executed outside of the\r
318                                 queue function. */\r
319                                 xErrorOccurred = pdTRUE;\r
320                         }\r
321 \r
322                         /* Set the priority back down. */\r
323                         vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY );\r
324                 }\r
325 \r
326                 /* Let the other task timeout.  When it unblockes it will check that it\r
327                 unblocked at the correct time, then suspend itself. */\r
328                 while( xRunIndicator != bktRUN_INDICATOR )\r
329                 {\r
330                         vTaskDelay( bktSHORT_WAIT );\r
331                 }\r
332                 vTaskDelay( bktSHORT_WAIT );\r
333                 xRunIndicator = 0;\r
334 \r
335 \r
336                 /*********************************************************************\r
337                 Test 4\r
338 \r
339                 As per test 3 - but with the send and receive the other way around.\r
340                 The other task blocks attempting to read from the queue.\r
341 \r
342                 Empty the queue.  We should find that it is full. */\r
343                 for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
344                 {\r
345                         if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )\r
346                         {\r
347                                 xErrorOccurred = pdTRUE;\r
348                         }\r
349                 }\r
350 \r
351                 /* Wake the other task so it blocks attempting to read from  the\r
352                 already empty queue. */\r
353                 vTaskResume( xSecondary );\r
354 \r
355                 /* We need to wait a little to ensure the other task executes. */\r
356                 while( xRunIndicator != bktRUN_INDICATOR )\r
357                 {\r
358                         vTaskDelay( bktSHORT_WAIT );\r
359                 }\r
360                 vTaskDelay( bktSHORT_WAIT );\r
361                 xRunIndicator = 0;\r
362 \r
363                 for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
364                 {\r
365                         /* Now when we place an item on the queue the other task should\r
366                         wake but not execute as this task has higher priority. */\r
367                         if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )\r
368                         {\r
369                                 xErrorOccurred = pdTRUE;\r
370                         }\r
371 \r
372                         /* Now empty the queue again before the other task gets a chance to\r
373                         execute.  If the other task had executed we would find the queue\r
374                         empty ourselves, and the other task would be suspended. */\r
375                         if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )\r
376                         {\r
377                                 xErrorOccurred = pdTRUE;\r
378                         }\r
379 \r
380                         if( xRunIndicator == bktRUN_INDICATOR )\r
381                         {\r
382                                 /* The other task should not have executed. */\r
383                                 xErrorOccurred = pdTRUE;\r
384                         }\r
385 \r
386                         /* Raise the priority of the other task so it executes and blocks\r
387                         on the queue again. */\r
388                         vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 );\r
389 \r
390                         /* The other task should now have re-blocked without exiting the\r
391                         queue function. */\r
392                         if( xRunIndicator == bktRUN_INDICATOR )\r
393                         {\r
394                                 /* The other task should not have executed outside of the\r
395                                 queue function. */\r
396                                 xErrorOccurred = pdTRUE;\r
397                         }\r
398                         vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY );\r
399                 }\r
400 \r
401                 /* Let the other task timeout.  When it unblockes it will check that it\r
402                 unblocked at the correct time, then suspend itself. */\r
403                 while( xRunIndicator != bktRUN_INDICATOR )\r
404                 {\r
405                         vTaskDelay( bktSHORT_WAIT );\r
406                 }\r
407                 vTaskDelay( bktSHORT_WAIT );\r
408 \r
409                 xPrimaryCycles++;\r
410         }\r
411 }\r
412 /*-----------------------------------------------------------*/\r
413 \r
414 static void vSecondaryBlockTimeTestTask( void *pvParameters )\r
415 {\r
416 TickType_t xTimeWhenBlocking, xBlockedTime;\r
417 BaseType_t xData;\r
418 \r
419         ( void ) pvParameters;\r
420 \r
421         for( ;; )\r
422         {\r
423                 /*********************************************************************\r
424                 Test 0, 1 and 2\r
425 \r
426                 This task does not participate in these tests. */\r
427                 vTaskSuspend( NULL );\r
428 \r
429                 /*********************************************************************\r
430                 Test 3\r
431 \r
432                 The first thing we do is attempt to read from the queue.  It should be\r
433                 full so we block.  Note the time before we block so we can check the\r
434                 wake time is as per that expected. */\r
435                 xTimeWhenBlocking = xTaskGetTickCount();\r
436 \r
437                 /* We should unblock after bktTIME_TO_BLOCK having not sent anything to\r
438                 the queue. */\r
439                 xData = 0;\r
440                 xRunIndicator = bktRUN_INDICATOR;\r
441                 if( xQueueSend( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_FULL )\r
442                 {\r
443                         xErrorOccurred = pdTRUE;\r
444                 }\r
445 \r
446                 /* How long were we inside the send function? */\r
447                 xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;\r
448 \r
449                 /* We should not have blocked for less time than bktTIME_TO_BLOCK. */\r
450                 if( xBlockedTime < bktTIME_TO_BLOCK )\r
451                 {\r
452                         xErrorOccurred = pdTRUE;\r
453                 }\r
454 \r
455                 /* We should of not blocked for much longer than bktALLOWABLE_MARGIN\r
456                 either.  A margin is permitted as we would not necessarily run as\r
457                 soon as we unblocked. */\r
458                 if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) )\r
459                 {\r
460                         xErrorOccurred = pdTRUE;\r
461                 }\r
462 \r
463                 /* Suspend ready for test 3. */\r
464                 xRunIndicator = bktRUN_INDICATOR;\r
465                 vTaskSuspend( NULL );\r
466 \r
467                 /*********************************************************************\r
468         Test 4\r
469 \r
470                 As per test three, but with the send and receive reversed. */\r
471                 xTimeWhenBlocking = xTaskGetTickCount();\r
472 \r
473                 /* We should unblock after bktTIME_TO_BLOCK having not received\r
474                 anything on the queue. */\r
475                 xRunIndicator = bktRUN_INDICATOR;\r
476                 if( xQueueReceive( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_EMPTY )\r
477                 {\r
478                         xErrorOccurred = pdTRUE;\r
479                 }\r
480 \r
481                 xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;\r
482 \r
483                 /* We should not have blocked for less time than bktTIME_TO_BLOCK. */\r
484                 if( xBlockedTime < bktTIME_TO_BLOCK )\r
485                 {\r
486                         xErrorOccurred = pdTRUE;\r
487                 }\r
488 \r
489                 /* We should of not blocked for much longer than bktALLOWABLE_MARGIN\r
490                 either.  A margin is permitted as we would not necessarily run as soon\r
491                 as we unblocked. */\r
492                 if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) )\r
493                 {\r
494                         xErrorOccurred = pdTRUE;\r
495                 }\r
496 \r
497                 xRunIndicator = bktRUN_INDICATOR;\r
498 \r
499                 xSecondaryCycles++;\r
500         }\r
501 }\r
502 /*-----------------------------------------------------------*/\r
503 \r
504 static void prvBasicDelayTests( void )\r
505 {\r
506 TickType_t xPreTime, xPostTime, x, xLastUnblockTime, xExpectedUnblockTime;\r
507 const TickType_t xPeriod = 75, xCycles = 5, xAllowableMargin = ( bktALLOWABLE_MARGIN >> 1 );\r
508 \r
509         /* Temporarily increase priority so the timing is more accurate, but not so\r
510         high as to disrupt the timer tests. */\r
511         vTaskPrioritySet( NULL, configTIMER_TASK_PRIORITY - 1 );\r
512 \r
513         /* Crude check to too that vTaskDelay() blocks for the expected period. */\r
514         xPreTime = xTaskGetTickCount();\r
515         vTaskDelay( bktTIME_TO_BLOCK );\r
516         xPostTime = xTaskGetTickCount();\r
517 \r
518         /* The priority is higher, so the allowable margin is halved when compared\r
519         to the other tests in this file. */\r
520         if( ( xPostTime - xPreTime ) > ( bktTIME_TO_BLOCK + xAllowableMargin ) )\r
521         {\r
522                 xErrorOccurred = pdTRUE;\r
523         }\r
524 \r
525         /* Now crude tests to check the vTaskDelayUntil() functionality. */\r
526         xPostTime = xTaskGetTickCount();\r
527         xLastUnblockTime = xPostTime;\r
528 \r
529         for( x = 0; x < xCycles; x++ )\r
530         {\r
531                 /* Calculate the next expected unblock time from the time taken before\r
532                 this loop was entered. */\r
533                 xExpectedUnblockTime = xPostTime + ( x * xPeriod );\r
534 \r
535                 vTaskDelayUntil( &xLastUnblockTime, xPeriod );\r
536 \r
537                 if( ( xTaskGetTickCount() - xExpectedUnblockTime ) > ( bktTIME_TO_BLOCK + xAllowableMargin ) )\r
538                 {\r
539                         xErrorOccurred = pdTRUE;\r
540                 }\r
541 \r
542                 xPrimaryCycles++;\r
543         }\r
544 \r
545         /* Reset to the original task priority ready for the other tests. */\r
546         vTaskPrioritySet( NULL, bktPRIMARY_PRIORITY );\r
547 }\r
548 /*-----------------------------------------------------------*/\r
549 \r
550 BaseType_t xAreBlockTimeTestTasksStillRunning( void )\r
551 {\r
552 static BaseType_t xLastPrimaryCycleCount = 0, xLastSecondaryCycleCount = 0;\r
553 BaseType_t xReturn = pdPASS;\r
554 \r
555         /* Have both tasks performed at least one cycle since this function was\r
556         last called? */\r
557         if( xPrimaryCycles == xLastPrimaryCycleCount )\r
558         {\r
559                 xReturn = pdFAIL;\r
560         }\r
561 \r
562         if( xSecondaryCycles == xLastSecondaryCycleCount )\r
563         {\r
564                 xReturn = pdFAIL;\r
565         }\r
566 \r
567         if( xErrorOccurred == pdTRUE )\r
568         {\r
569                 xReturn = pdFAIL;\r
570         }\r
571 \r
572         xLastSecondaryCycleCount = xSecondaryCycles;\r
573         xLastPrimaryCycleCount = xPrimaryCycles;\r
574 \r
575         return xReturn;\r
576 }\r