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