]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/Common/Minimal/blocktim.c
Prepare for a FreeRTOS V9 release candidate:
[freertos] / FreeRTOS / Demo / Common / Minimal / blocktim.c
1 /*\r
2     FreeRTOS V8.2.3 - Copyright (C) 2015 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         /* vQueueAddToRegistry() adds the queue to the queue registry, if one is\r
140         in use.  The queue registry is provided as a means for kernel aware\r
141         debuggers to locate queues and has no purpose if a kernel aware debugger\r
142         is not being used.  The call to vQueueAddToRegistry() will be removed\r
143         by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is\r
144         defined to be less than 1. */\r
145         vQueueAddToRegistry( xTestQueue, "Block_Time_Queue" );\r
146 \r
147         /* Create the two test tasks. */\r
148         xTaskCreate( vPrimaryBlockTimeTestTask, "BTest1", configMINIMAL_STACK_SIZE, NULL, bktPRIMARY_PRIORITY, NULL );\r
149         xTaskCreate( vSecondaryBlockTimeTestTask, "BTest2", configMINIMAL_STACK_SIZE, NULL, bktSECONDARY_PRIORITY, &xSecondary );\r
150 }\r
151 /*-----------------------------------------------------------*/\r
152 \r
153 static void vPrimaryBlockTimeTestTask( void *pvParameters )\r
154 {\r
155 BaseType_t xItem, xData;\r
156 TickType_t xTimeWhenBlocking;\r
157 TickType_t xTimeToBlock, xBlockedTime;\r
158 \r
159         ( void ) pvParameters;\r
160 \r
161         for( ;; )\r
162         {\r
163                 /*********************************************************************\r
164                 Test 0\r
165 \r
166                 Basic vTaskDelay() and vTaskDelayUntil() tests. */\r
167                 prvBasicDelayTests();\r
168 \r
169 \r
170                 /*********************************************************************\r
171                 Test 1\r
172 \r
173                 Simple block time wakeup test on queue receives. */\r
174                 for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
175                 {\r
176                         /* The queue is empty. Attempt to read from the queue using a block\r
177                         time.  When we wake, ensure the delta in time is as expected. */\r
178                         xTimeToBlock = ( TickType_t ) ( bktPRIMARY_BLOCK_TIME << xItem );\r
179 \r
180                         xTimeWhenBlocking = xTaskGetTickCount();\r
181 \r
182                         /* We should unblock after xTimeToBlock having not received\r
183                         anything on the queue. */\r
184                         if( xQueueReceive( xTestQueue, &xData, xTimeToBlock ) != errQUEUE_EMPTY )\r
185                         {\r
186                                 xErrorOccurred = pdTRUE;\r
187                         }\r
188 \r
189                         /* How long were we blocked for? */\r
190                         xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;\r
191 \r
192                         if( xBlockedTime < xTimeToBlock )\r
193                         {\r
194                                 /* Should not have blocked for less than we requested. */\r
195                                 xErrorOccurred = pdTRUE;\r
196                         }\r
197 \r
198                         if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) )\r
199                         {\r
200                                 /* Should not have blocked for longer than we requested,\r
201                                 although we would not necessarily run as soon as we were\r
202                                 unblocked so a margin is allowed. */\r
203                                 xErrorOccurred = pdTRUE;\r
204                         }\r
205                 }\r
206 \r
207                 /*********************************************************************\r
208                 Test 2\r
209 \r
210                 Simple block time wakeup test on queue sends.\r
211 \r
212                 First fill the queue.  It should be empty so all sends should pass. */\r
213                 for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
214                 {\r
215                         if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )\r
216                         {\r
217                                 xErrorOccurred = pdTRUE;\r
218                         }\r
219 \r
220                         #if configUSE_PREEMPTION == 0\r
221                                 taskYIELD();\r
222                         #endif\r
223                 }\r
224 \r
225                 for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
226                 {\r
227                         /* The queue is full. Attempt to write to the queue using a block\r
228                         time.  When we wake, ensure the delta in time is as expected. */\r
229                         xTimeToBlock = ( TickType_t ) ( bktPRIMARY_BLOCK_TIME << xItem );\r
230 \r
231                         xTimeWhenBlocking = xTaskGetTickCount();\r
232 \r
233                         /* We should unblock after xTimeToBlock having not received\r
234                         anything on the queue. */\r
235                         if( xQueueSend( xTestQueue, &xItem, xTimeToBlock ) != errQUEUE_FULL )\r
236                         {\r
237                                 xErrorOccurred = pdTRUE;\r
238                         }\r
239 \r
240                         /* How long were we blocked for? */\r
241                         xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;\r
242 \r
243                         if( xBlockedTime < xTimeToBlock )\r
244                         {\r
245                                 /* Should not have blocked for less than we requested. */\r
246                                 xErrorOccurred = pdTRUE;\r
247                         }\r
248 \r
249                         if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) )\r
250                         {\r
251                                 /* Should not have blocked for longer than we requested,\r
252                                 although we would not necessarily run as soon as we were\r
253                                 unblocked so a margin is allowed. */\r
254                                 xErrorOccurred = pdTRUE;\r
255                         }\r
256                 }\r
257 \r
258                 /*********************************************************************\r
259                 Test 3\r
260 \r
261                 Wake the other task, it will block attempting to post to the queue.\r
262                 When we read from the queue the other task will wake, but before it\r
263                 can run we will post to the queue again.  When the other task runs it\r
264                 will find the queue still full, even though it was woken.  It should\r
265                 recognise that its block time has not expired and return to block for\r
266                 the remains of its block time.\r
267 \r
268                 Wake the other task so it blocks attempting to post to the already\r
269                 full queue. */\r
270                 xRunIndicator = 0;\r
271                 vTaskResume( xSecondary );\r
272 \r
273                 /* We need to wait a little to ensure the other task executes. */\r
274                 while( xRunIndicator != bktRUN_INDICATOR )\r
275                 {\r
276                         /* The other task has not yet executed. */\r
277                         vTaskDelay( bktSHORT_WAIT );\r
278                 }\r
279                 /* Make sure the other task is blocked on the queue. */\r
280                 vTaskDelay( bktSHORT_WAIT );\r
281                 xRunIndicator = 0;\r
282 \r
283                 for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
284                 {\r
285                         /* Now when we make space on the queue the other task should wake\r
286                         but not execute as this task has higher priority. */\r
287                         if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )\r
288                         {\r
289                                 xErrorOccurred = pdTRUE;\r
290                         }\r
291 \r
292                         /* Now fill the queue again before the other task gets a chance to\r
293                         execute.  If the other task had executed we would find the queue\r
294                         full ourselves, and the other task have set xRunIndicator. */\r
295                         if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )\r
296                         {\r
297                                 xErrorOccurred = pdTRUE;\r
298                         }\r
299 \r
300                         if( xRunIndicator == bktRUN_INDICATOR )\r
301                         {\r
302                                 /* The other task should not have executed. */\r
303                                 xErrorOccurred = pdTRUE;\r
304                         }\r
305 \r
306                         /* Raise the priority of the other task so it executes and blocks\r
307                         on the queue again. */\r
308                         vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 );\r
309 \r
310                         /* The other task should now have re-blocked without exiting the\r
311                         queue function. */\r
312                         if( xRunIndicator == bktRUN_INDICATOR )\r
313                         {\r
314                                 /* The other task should not have executed outside of the\r
315                                 queue function. */\r
316                                 xErrorOccurred = pdTRUE;\r
317                         }\r
318 \r
319                         /* Set the priority back down. */\r
320                         vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY );\r
321                 }\r
322 \r
323                 /* Let the other task timeout.  When it unblockes it will check that it\r
324                 unblocked at the correct time, then suspend itself. */\r
325                 while( xRunIndicator != bktRUN_INDICATOR )\r
326                 {\r
327                         vTaskDelay( bktSHORT_WAIT );\r
328                 }\r
329                 vTaskDelay( bktSHORT_WAIT );\r
330                 xRunIndicator = 0;\r
331 \r
332 \r
333                 /*********************************************************************\r
334                 Test 4\r
335 \r
336                 As per test 3 - but with the send and receive the other way around.\r
337                 The other task blocks attempting to read from the queue.\r
338 \r
339                 Empty the queue.  We should find that it is full. */\r
340                 for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
341                 {\r
342                         if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )\r
343                         {\r
344                                 xErrorOccurred = pdTRUE;\r
345                         }\r
346                 }\r
347 \r
348                 /* Wake the other task so it blocks attempting to read from  the\r
349                 already empty queue. */\r
350                 vTaskResume( xSecondary );\r
351 \r
352                 /* We need to wait a little to ensure the other task executes. */\r
353                 while( xRunIndicator != bktRUN_INDICATOR )\r
354                 {\r
355                         vTaskDelay( bktSHORT_WAIT );\r
356                 }\r
357                 vTaskDelay( bktSHORT_WAIT );\r
358                 xRunIndicator = 0;\r
359 \r
360                 for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
361                 {\r
362                         /* Now when we place an item on the queue the other task should\r
363                         wake but not execute as this task has higher priority. */\r
364                         if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )\r
365                         {\r
366                                 xErrorOccurred = pdTRUE;\r
367                         }\r
368 \r
369                         /* Now empty the queue again before the other task gets a chance to\r
370                         execute.  If the other task had executed we would find the queue\r
371                         empty ourselves, and the other task would be suspended. */\r
372                         if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )\r
373                         {\r
374                                 xErrorOccurred = pdTRUE;\r
375                         }\r
376 \r
377                         if( xRunIndicator == bktRUN_INDICATOR )\r
378                         {\r
379                                 /* The other task should not have executed. */\r
380                                 xErrorOccurred = pdTRUE;\r
381                         }\r
382 \r
383                         /* Raise the priority of the other task so it executes and blocks\r
384                         on the queue again. */\r
385                         vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 );\r
386 \r
387                         /* The other task should now have re-blocked without exiting the\r
388                         queue function. */\r
389                         if( xRunIndicator == bktRUN_INDICATOR )\r
390                         {\r
391                                 /* The other task should not have executed outside of the\r
392                                 queue function. */\r
393                                 xErrorOccurred = pdTRUE;\r
394                         }\r
395                         vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY );\r
396                 }\r
397 \r
398                 /* Let the other task timeout.  When it unblockes it will check that it\r
399                 unblocked at the correct time, then suspend itself. */\r
400                 while( xRunIndicator != bktRUN_INDICATOR )\r
401                 {\r
402                         vTaskDelay( bktSHORT_WAIT );\r
403                 }\r
404                 vTaskDelay( bktSHORT_WAIT );\r
405 \r
406                 xPrimaryCycles++;\r
407         }\r
408 }\r
409 /*-----------------------------------------------------------*/\r
410 \r
411 static void vSecondaryBlockTimeTestTask( void *pvParameters )\r
412 {\r
413 TickType_t xTimeWhenBlocking, xBlockedTime;\r
414 BaseType_t xData;\r
415 \r
416         ( void ) pvParameters;\r
417 \r
418         for( ;; )\r
419         {\r
420                 /*********************************************************************\r
421                 Test 0, 1 and 2\r
422 \r
423                 This task does not participate in these tests. */\r
424                 vTaskSuspend( NULL );\r
425 \r
426                 /*********************************************************************\r
427                 Test 3\r
428 \r
429                 The first thing we do is attempt to read from the queue.  It should be\r
430                 full so we block.  Note the time before we block so we can check the\r
431                 wake time is as per that expected. */\r
432                 xTimeWhenBlocking = xTaskGetTickCount();\r
433 \r
434                 /* We should unblock after bktTIME_TO_BLOCK having not sent anything to\r
435                 the queue. */\r
436                 xData = 0;\r
437                 xRunIndicator = bktRUN_INDICATOR;\r
438                 if( xQueueSend( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_FULL )\r
439                 {\r
440                         xErrorOccurred = pdTRUE;\r
441                 }\r
442 \r
443                 /* How long were we inside the send function? */\r
444                 xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;\r
445 \r
446                 /* We should not have blocked for less time than bktTIME_TO_BLOCK. */\r
447                 if( xBlockedTime < bktTIME_TO_BLOCK )\r
448                 {\r
449                         xErrorOccurred = pdTRUE;\r
450                 }\r
451 \r
452                 /* We should of not blocked for much longer than bktALLOWABLE_MARGIN\r
453                 either.  A margin is permitted as we would not necessarily run as\r
454                 soon as we unblocked. */\r
455                 if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) )\r
456                 {\r
457                         xErrorOccurred = pdTRUE;\r
458                 }\r
459 \r
460                 /* Suspend ready for test 3. */\r
461                 xRunIndicator = bktRUN_INDICATOR;\r
462                 vTaskSuspend( NULL );\r
463 \r
464                 /*********************************************************************\r
465         Test 4\r
466 \r
467                 As per test three, but with the send and receive reversed. */\r
468                 xTimeWhenBlocking = xTaskGetTickCount();\r
469 \r
470                 /* We should unblock after bktTIME_TO_BLOCK having not received\r
471                 anything on the queue. */\r
472                 xRunIndicator = bktRUN_INDICATOR;\r
473                 if( xQueueReceive( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_EMPTY )\r
474                 {\r
475                         xErrorOccurred = pdTRUE;\r
476                 }\r
477 \r
478                 xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;\r
479 \r
480                 /* We should not have blocked for less time than bktTIME_TO_BLOCK. */\r
481                 if( xBlockedTime < bktTIME_TO_BLOCK )\r
482                 {\r
483                         xErrorOccurred = pdTRUE;\r
484                 }\r
485 \r
486                 /* We should of not blocked for much longer than bktALLOWABLE_MARGIN\r
487                 either.  A margin is permitted as we would not necessarily run as soon\r
488                 as we unblocked. */\r
489                 if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) )\r
490                 {\r
491                         xErrorOccurred = pdTRUE;\r
492                 }\r
493 \r
494                 xRunIndicator = bktRUN_INDICATOR;\r
495 \r
496                 xSecondaryCycles++;\r
497         }\r
498 }\r
499 /*-----------------------------------------------------------*/\r
500 \r
501 static void prvBasicDelayTests( void )\r
502 {\r
503 TickType_t xPreTime, xPostTime, x, xLastUnblockTime, xExpectedUnblockTime;\r
504 const TickType_t xPeriod = 75, xCycles = 5, xAllowableMargin = ( bktALLOWABLE_MARGIN >> 1 );\r
505 \r
506         /* Temporarily increase priority so the timing is more accurate, but not so\r
507         high as to disrupt the timer tests. */\r
508         vTaskPrioritySet( NULL, configTIMER_TASK_PRIORITY - 1 );\r
509 \r
510         /* Crude check to too that vTaskDelay() blocks for the expected period. */\r
511         xPreTime = xTaskGetTickCount();\r
512         vTaskDelay( bktTIME_TO_BLOCK );\r
513         xPostTime = xTaskGetTickCount();\r
514 \r
515         /* The priority is higher, so the allowable margin is halved when compared\r
516         to the other tests in this file. */\r
517         if( ( xPostTime - xPreTime ) > ( bktTIME_TO_BLOCK + xAllowableMargin ) )\r
518         {\r
519                 xErrorOccurred = pdTRUE;\r
520         }\r
521 \r
522         /* Now crude tests to check the vTaskDelayUntil() functionality. */\r
523         xPostTime = xTaskGetTickCount();\r
524         xLastUnblockTime = xPostTime;\r
525 \r
526         for( x = 0; x < xCycles; x++ )\r
527         {\r
528                 /* Calculate the next expected unblock time from the time taken before\r
529                 this loop was entered. */\r
530                 xExpectedUnblockTime = xPostTime + ( x * xPeriod );\r
531 \r
532                 vTaskDelayUntil( &xLastUnblockTime, xPeriod );\r
533 \r
534                 if( ( xTaskGetTickCount() - xExpectedUnblockTime ) > ( bktTIME_TO_BLOCK + xAllowableMargin ) )\r
535                 {\r
536                         xErrorOccurred = pdTRUE;\r
537                 }\r
538 \r
539                 xPrimaryCycles++;\r
540         }\r
541 \r
542         /* Reset to the original task priority ready for the other tests. */\r
543         vTaskPrioritySet( NULL, bktPRIMARY_PRIORITY );\r
544 }\r
545 /*-----------------------------------------------------------*/\r
546 \r
547 BaseType_t xAreBlockTimeTestTasksStillRunning( void )\r
548 {\r
549 static BaseType_t xLastPrimaryCycleCount = 0, xLastSecondaryCycleCount = 0;\r
550 BaseType_t xReturn = pdPASS;\r
551 \r
552         /* Have both tasks performed at least one cycle since this function was\r
553         last called? */\r
554         if( xPrimaryCycles == xLastPrimaryCycleCount )\r
555         {\r
556                 xReturn = pdFAIL;\r
557         }\r
558 \r
559         if( xSecondaryCycles == xLastSecondaryCycleCount )\r
560         {\r
561                 xReturn = pdFAIL;\r
562         }\r
563 \r
564         if( xErrorOccurred == pdTRUE )\r
565         {\r
566                 xReturn = pdFAIL;\r
567         }\r
568 \r
569         xLastSecondaryCycleCount = xSecondaryCycles;\r
570         xLastPrimaryCycleCount = xPrimaryCycles;\r
571 \r
572         return xReturn;\r
573 }\r