2 * FreeRTOS Kernel V10.0.1
\r
3 * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
\r
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
\r
6 * this software and associated documentation files (the "Software"), to deal in
\r
7 * the Software without restriction, including without limitation the rights to
\r
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
\r
9 * the Software, and to permit persons to whom the Software is furnished to do so,
\r
10 * subject to the following conditions:
\r
12 * The above copyright notice and this permission notice shall be included in all
\r
13 * copies or substantial portions of the Software.
\r
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
\r
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
\r
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
\r
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
22 * http://www.FreeRTOS.org
\r
23 * http://aws.amazon.com/freertos
\r
25 * 1 tab == 4 spaces!
\r
29 * This file contains some test scenarios that ensure tasks respond correctly
\r
30 * to xTaskAbortDelay() calls.
\r
33 /* Standard includes. */
\r
36 /* Kernel includes. */
\r
37 #include "FreeRTOS.h"
\r
41 #include "event_groups.h"
\r
43 /* Demo includes. */
\r
44 #include "AbortDelay.h"
\r
46 /* This file can only be used if the functionality it tests is included in the
\r
47 build. Remove the whole file if this is not the case. */
\r
48 #if( INCLUDE_xTaskAbortDelay == 1 )
\r
50 #if( INCLUDE_xTaskGetHandle != 1 )
\r
51 #error This test file uses the xTaskGetHandle() API function so INCLUDE_xTaskGetHandle must be set to 1 in FreeRTOSConfig.h.
\r
54 /* Task priorities. Allow these to be overridden. */
\r
55 #ifndef abtCONTROLLING_PRIORITY
\r
56 #define abtCONTROLLING_PRIORITY ( configMAX_PRIORITIES - 3 )
\r
59 #ifndef abtBLOCKING_PRIORITY
\r
60 #define abtBLOCKING_PRIORITY ( configMAX_PRIORITIES - 2 )
\r
63 /* The tests that are performed. */
\r
64 #define abtNOTIFY_WAIT_ABORTS 0
\r
65 #define abtNOTIFY_TAKE_ABORTS 1
\r
66 #define abtDELAY_ABORTS 2
\r
67 #define abtDELAY_UNTIL_ABORTS 3
\r
68 #define abtSEMAPHORE_TAKE_ABORTS 4
\r
69 #define abtEVENT_GROUP_ABORTS 5
\r
70 #define abtQUEUE_SEND_ABORTS 6
\r
71 #define abtMAX_TESTS 7
\r
73 /*-----------------------------------------------------------*/
\r
76 * The two test tasks. The controlling task specifies which test to executed.
\r
77 * More information is provided in the comments within the tasks.
\r
79 static void prvControllingTask( void *pvParameters );
\r
80 static void prvBlockingTask( void *pvParameters );
\r
83 * Test functions called by the blocking task. Each function follows the same
\r
84 * pattern, but the way the task blocks is different in each case.
\r
86 * In each function three blocking calls are made. The first and third
\r
87 * blocking call is expected to time out, while the middle blocking call is
\r
88 * expected to be aborted by the controlling task half way through the block
\r
91 static void prvTestAbortingTaskNotifyWait( void );
\r
92 static void prvTestAbortingTaskNotifyTake( void );
\r
93 static void prvTestAbortingTaskDelay( void );
\r
94 static void prvTestAbortingTaskDelayUntil( void );
\r
95 static void prvTestAbortingSemaphoreTake( void );
\r
96 static void prvTestAbortingEventGroupWait( void );
\r
97 static void prvTestAbortingQueueSend( void );
\r
100 * Checks the amount of time a task spent in the Blocked state is within the
\r
103 static void prvCheckExpectedTimeIsWithinAnAcceptableMargin( TickType_t xStartTime, TickType_t xExpectedBlockTime );
\r
105 /*-----------------------------------------------------------*/
\r
107 /* Used to ensure that tasks are still executing without error. */
\r
108 static volatile BaseType_t xControllingCycles = 0, xBlockingCycles = 0;
\r
109 static volatile BaseType_t xErrorOccurred = pdFALSE;
\r
111 /* Each task needs to know the other tasks handle so they can send signals to
\r
112 each other. The handle is obtained from the task's name. */
\r
113 static const char *pcControllingTaskName = "AbtCtrl", *pcBlockingTaskName = "AbtBlk";
\r
115 /* The maximum amount of time a task will block for. */
\r
116 const TickType_t xMaxBlockTime = pdMS_TO_TICKS( 100 );
\r
117 const TickType_t xHalfMaxBlockTime = pdMS_TO_TICKS( 50 );
\r
119 /* The actual block time is dependent on the priority of other tasks in the
\r
120 system so the actual block time might be greater than that expected, but it
\r
121 should be within an acceptable upper bound. */
\r
122 const TickType_t xAllowableMargin = pdMS_TO_TICKS( 7 );
\r
124 /*-----------------------------------------------------------*/
\r
126 void vCreateAbortDelayTasks( void )
\r
128 /* Create the two test tasks described above. */
\r
129 xTaskCreate( prvControllingTask, pcControllingTaskName, configMINIMAL_STACK_SIZE, NULL, abtCONTROLLING_PRIORITY, NULL );
\r
130 xTaskCreate( prvBlockingTask, pcBlockingTaskName, configMINIMAL_STACK_SIZE, NULL, abtBLOCKING_PRIORITY, NULL );
\r
132 /*-----------------------------------------------------------*/
\r
134 static void prvControllingTask( void *pvParameters )
\r
136 TaskHandle_t xBlockingTask;
\r
137 uint32_t ulTestToPerform = abtNOTIFY_WAIT_ABORTS;
\r
138 TickType_t xTimeAtStart;
\r
139 const TickType_t xStartMargin = 2UL;
\r
141 /* Just to remove compiler warnings. */
\r
142 ( void ) pvParameters;
\r
144 xBlockingTask = xTaskGetHandle( pcBlockingTaskName );
\r
145 configASSERT( xBlockingTask );
\r
149 /* Tell the secondary task to perform the next test. */
\r
150 xTimeAtStart = xTaskGetTickCount();
\r
151 xTaskNotify( xBlockingTask, ulTestToPerform, eSetValueWithOverwrite );
\r
153 /* The secondary task has a higher priority, so will now be in the
\r
154 Blocked state to wait for a maximum of xMaxBlockTime. It expects that
\r
155 period to complete with a timeout. It will then block for
\r
156 xMaxBlockTimeAgain, but this time it expects to the block time to abort
\r
157 half way through. Block until it is time to send the abort to the
\r
158 secondary task. xStartMargin is used because this task takes timing
\r
159 from the beginning of the test, whereas the blocking task takes timing
\r
160 from the entry into the Blocked state - and as the tasks run at
\r
161 different priorities, there may be some discrepancy. Also, temporarily
\r
162 raise the priority of the controlling task to that of the blocking
\r
163 task to minimise discrepancies. */
\r
164 vTaskPrioritySet( NULL, abtBLOCKING_PRIORITY );
\r
165 vTaskDelay( xMaxBlockTime + xHalfMaxBlockTime + xStartMargin );
\r
166 if( xTaskAbortDelay( xBlockingTask ) != pdPASS )
\r
168 xErrorOccurred = pdTRUE;
\r
171 /* Reset the priority to the normal controlling priority. */
\r
172 vTaskPrioritySet( NULL, abtCONTROLLING_PRIORITY );
\r
174 /* Now wait to be notified that the secondary task has completed its
\r
176 ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
\r
178 /* Did the entire test run for the expected time, which is two full
\r
179 block times plus the half block time caused by calling
\r
180 xTaskAbortDelay()? */
\r
181 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, ( xMaxBlockTime + xMaxBlockTime + xHalfMaxBlockTime ) );
\r
183 /* Move onto the next test. */
\r
186 if( ulTestToPerform >= abtMAX_TESTS )
\r
188 ulTestToPerform = 0;
\r
191 /* To indicate this task is still executing. */
\r
192 xControllingCycles++;
\r
195 /*-----------------------------------------------------------*/
\r
197 static void prvBlockingTask( void *pvParameters )
\r
199 TaskHandle_t xControllingTask;
\r
200 uint32_t ulNotificationValue;
\r
201 const uint32_t ulMax = 0xffffffffUL;
\r
203 /* Just to remove compiler warnings. */
\r
204 ( void ) pvParameters;
\r
206 xControllingTask = xTaskGetHandle( pcControllingTaskName );
\r
207 configASSERT( xControllingTask );
\r
211 /* Wait to be notified of the test that is to be performed next. */
\r
212 xTaskNotifyWait( 0, ulMax, &ulNotificationValue, portMAX_DELAY );
\r
214 switch( ulNotificationValue )
\r
216 case abtNOTIFY_WAIT_ABORTS:
\r
217 prvTestAbortingTaskNotifyWait();
\r
220 case abtNOTIFY_TAKE_ABORTS:
\r
221 prvTestAbortingTaskNotifyTake();
\r
224 case abtDELAY_ABORTS:
\r
225 prvTestAbortingTaskDelay();
\r
228 case abtDELAY_UNTIL_ABORTS:
\r
229 prvTestAbortingTaskDelayUntil();
\r
232 case abtSEMAPHORE_TAKE_ABORTS:
\r
233 prvTestAbortingSemaphoreTake();
\r
236 case abtEVENT_GROUP_ABORTS:
\r
237 prvTestAbortingEventGroupWait();
\r
240 case abtQUEUE_SEND_ABORTS:
\r
241 prvTestAbortingQueueSend();
\r
245 /* Should not get here. */
\r
249 /* Let the primary task know the test is complete. */
\r
250 xTaskNotifyGive( xControllingTask );
\r
252 /* To indicate this task is still executing. */
\r
256 /*-----------------------------------------------------------*/
\r
258 static void prvTestAbortingTaskDelayUntil( void )
\r
260 TickType_t xTimeAtStart, xLastBlockTime;
\r
262 /* Note the time before the delay so the length of the delay is known. */
\r
263 xTimeAtStart = xTaskGetTickCount();
\r
265 /* Take a copy of the time as it is updated in the call to
\r
266 vTaskDelayUntil() but its original value is needed to determine the actual
\r
267 time spend in the Blocked state. */
\r
268 xLastBlockTime = xTimeAtStart;
\r
270 /* This first delay should just time out. */
\r
271 vTaskDelayUntil( &xLastBlockTime, xMaxBlockTime );
\r
272 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
\r
274 /* This second delay should be aborted by the primary task half way
\r
275 through. Again take a copy of the time as it is updated in the call to
\r
276 vTaskDelayUntil() buts its original value is needed to determine the amount
\r
277 of time actually spent in the Blocked state. */
\r
278 xTimeAtStart = xTaskGetTickCount();
\r
279 xLastBlockTime = xTimeAtStart;
\r
280 vTaskDelayUntil( &xLastBlockTime, xMaxBlockTime );
\r
281 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
\r
283 /* As with the other tests, the third block period should not time out. */
\r
284 xTimeAtStart = xTaskGetTickCount();
\r
285 xLastBlockTime = xTimeAtStart;
\r
286 vTaskDelayUntil( &xLastBlockTime, xMaxBlockTime );
\r
287 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
\r
289 /*-----------------------------------------------------------*/
\r
291 static void prvTestAbortingTaskDelay( void )
\r
293 TickType_t xTimeAtStart;
\r
295 /* Note the time before the delay so the length of the delay is known. */
\r
296 xTimeAtStart = xTaskGetTickCount();
\r
298 /* This first delay should just time out. */
\r
299 vTaskDelay( xMaxBlockTime );
\r
300 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
\r
302 /* Note the time before the delay so the length of the delay is known. */
\r
303 xTimeAtStart = xTaskGetTickCount();
\r
305 /* This second delay should be aborted by the primary task half way
\r
307 vTaskDelay( xMaxBlockTime );
\r
308 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
\r
310 /* Note the time before the delay so the length of the delay is known. */
\r
311 xTimeAtStart = xTaskGetTickCount();
\r
313 /* This third delay should just time out again. */
\r
314 vTaskDelay( xMaxBlockTime );
\r
315 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
\r
317 /*-----------------------------------------------------------*/
\r
319 static void prvTestAbortingTaskNotifyTake( void )
\r
321 TickType_t xTimeAtStart;
\r
324 /* Note the time before the delay so the length of the delay is known. */
\r
325 xTimeAtStart = xTaskGetTickCount();
\r
327 /* This first delay should just time out. */
\r
328 ulReturn = ulTaskNotifyTake( pdFALSE, xMaxBlockTime );
\r
329 if( ulReturn != 0 )
\r
331 xErrorOccurred = pdTRUE;
\r
333 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
\r
335 /* Note the time before the delay so the length of the delay is known. */
\r
336 xTimeAtStart = xTaskGetTickCount();
\r
338 /* This second delay should be aborted by the primary task half way
\r
340 ulReturn = ulTaskNotifyTake( pdFALSE, xMaxBlockTime );
\r
341 if( ulReturn != 0 )
\r
343 xErrorOccurred = pdTRUE;
\r
345 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
\r
347 /* Note the time before the delay so the length of the delay is known. */
\r
348 xTimeAtStart = xTaskGetTickCount();
\r
350 /* This third delay should just time out again. */
\r
351 ulReturn = ulTaskNotifyTake( pdFALSE, xMaxBlockTime );
\r
352 if( ulReturn != 0 )
\r
354 xErrorOccurred = pdTRUE;
\r
356 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
\r
358 /*-----------------------------------------------------------*/
\r
360 static void prvTestAbortingEventGroupWait( void )
\r
362 TickType_t xTimeAtStart;
\r
363 EventGroupHandle_t xEventGroup;
\r
364 EventBits_t xBitsToWaitFor = ( EventBits_t ) 0x01, xReturn;
\r
366 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
\r
368 static StaticEventGroup_t xEventGroupBuffer;
\r
370 /* Create the event group. Statically allocated memory is used so the
\r
371 creation cannot fail. */
\r
372 xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
\r
376 xEventGroup = xEventGroupCreate();
\r
377 configASSERT( xEventGroup );
\r
381 /* Note the time before the delay so the length of the delay is known. */
\r
382 xTimeAtStart = xTaskGetTickCount();
\r
384 /* This first delay should just time out. */
\r
385 xReturn = xEventGroupWaitBits( xEventGroup, xBitsToWaitFor, pdTRUE, pdTRUE, xMaxBlockTime );
\r
386 if( xReturn != 0x00 )
\r
388 xErrorOccurred = pdTRUE;
\r
390 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
\r
392 /* Note the time before the delay so the length of the delay is known. */
\r
393 xTimeAtStart = xTaskGetTickCount();
\r
395 /* This second delay should be aborted by the primary task half way
\r
397 xReturn = xEventGroupWaitBits( xEventGroup, xBitsToWaitFor, pdTRUE, pdTRUE, xMaxBlockTime );
\r
398 if( xReturn != 0x00 )
\r
400 xErrorOccurred = pdTRUE;
\r
402 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
\r
404 /* Note the time before the delay so the length of the delay is known. */
\r
405 xTimeAtStart = xTaskGetTickCount();
\r
407 /* This third delay should just time out again. */
\r
408 xReturn = xEventGroupWaitBits( xEventGroup, xBitsToWaitFor, pdTRUE, pdTRUE, xMaxBlockTime );
\r
409 if( xReturn != 0x00 )
\r
411 xErrorOccurred = pdTRUE;
\r
413 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
\r
415 /* Not really necessary in this case, but for completeness. */
\r
416 vEventGroupDelete( xEventGroup );
\r
418 /*-----------------------------------------------------------*/
\r
420 static void prvTestAbortingQueueSend( void )
\r
422 TickType_t xTimeAtStart;
\r
423 BaseType_t xReturn;
\r
424 const UBaseType_t xQueueLength = ( UBaseType_t ) 1;
\r
425 QueueHandle_t xQueue;
\r
426 uint8_t ucItemToQueue;
\r
428 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
\r
430 static StaticQueue_t xQueueBuffer;
\r
431 static uint8_t ucQueueStorage[ sizeof( uint8_t ) ];
\r
433 /* Create the queue. Statically allocated memory is used so the
\r
434 creation cannot fail. */
\r
435 xQueue = xQueueCreateStatic( xQueueLength, sizeof( uint8_t ), ucQueueStorage, &xQueueBuffer );
\r
439 xQueue = xQueueCreate( xQueueLength, sizeof( uint8_t ) );
\r
440 configASSERT( xQueue );
\r
444 /* This function tests aborting when in the blocked state waiting to send,
\r
445 so the queue must be full. There is only one space in the queue. */
\r
446 xReturn = xQueueSend( xQueue, &ucItemToQueue, xMaxBlockTime );
\r
447 if( xReturn != pdPASS )
\r
449 xErrorOccurred = pdTRUE;
\r
452 /* Note the time before the delay so the length of the delay is known. */
\r
453 xTimeAtStart = xTaskGetTickCount();
\r
455 /* This first delay should just time out. */
\r
456 xReturn = xQueueSend( xQueue, &ucItemToQueue, xMaxBlockTime );
\r
457 if( xReturn != pdFALSE )
\r
459 xErrorOccurred = pdTRUE;
\r
461 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
\r
463 /* Note the time before the delay so the length of the delay is known. */
\r
464 xTimeAtStart = xTaskGetTickCount();
\r
466 /* This second delay should be aborted by the primary task half way
\r
468 xReturn = xQueueSend( xQueue, &ucItemToQueue, xMaxBlockTime );
\r
469 if( xReturn != pdFALSE )
\r
471 xErrorOccurred = pdTRUE;
\r
473 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
\r
475 /* Note the time before the delay so the length of the delay is known. */
\r
476 xTimeAtStart = xTaskGetTickCount();
\r
478 /* This third delay should just time out again. */
\r
479 xReturn = xQueueSend( xQueue, &ucItemToQueue, xMaxBlockTime );
\r
480 if( xReturn != pdFALSE )
\r
482 xErrorOccurred = pdTRUE;
\r
484 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
\r
486 /* Not really necessary in this case, but for completeness. */
\r
487 vQueueDelete( xQueue );
\r
489 /*-----------------------------------------------------------*/
\r
491 static void prvTestAbortingSemaphoreTake( void )
\r
493 TickType_t xTimeAtStart;
\r
494 BaseType_t xReturn;
\r
495 SemaphoreHandle_t xSemaphore;
\r
497 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
\r
499 static StaticSemaphore_t xSemaphoreBuffer;
\r
501 /* Create the semaphore. Statically allocated memory is used so the
\r
502 creation cannot fail. */
\r
503 xSemaphore = xSemaphoreCreateBinaryStatic( &xSemaphoreBuffer );
\r
507 xSemaphore = xSemaphoreCreateBinary();
\r
511 /* Note the time before the delay so the length of the delay is known. */
\r
512 xTimeAtStart = xTaskGetTickCount();
\r
514 /* This first delay should just time out. */
\r
515 xReturn = xSemaphoreTake( xSemaphore, xMaxBlockTime );
\r
516 if( xReturn != pdFALSE )
\r
518 xErrorOccurred = pdTRUE;
\r
520 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
\r
522 /* Note the time before the delay so the length of the delay is known. */
\r
523 xTimeAtStart = xTaskGetTickCount();
\r
525 /* This second delay should be aborted by the primary task half way
\r
527 xReturn = xSemaphoreTake( xSemaphore, xMaxBlockTime );
\r
528 if( xReturn != pdFALSE )
\r
530 xErrorOccurred = pdTRUE;
\r
532 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
\r
534 /* Note the time before the delay so the length of the delay is known. */
\r
535 xTimeAtStart = xTaskGetTickCount();
\r
537 /* This third delay should just time out again. */
\r
538 xReturn = xSemaphoreTake( xSemaphore, xMaxBlockTime );
\r
539 if( xReturn != pdFALSE )
\r
541 xErrorOccurred = pdTRUE;
\r
543 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
\r
545 /* Not really necessary in this case, but for completeness. */
\r
546 vSemaphoreDelete( xSemaphore );
\r
548 /*-----------------------------------------------------------*/
\r
550 static void prvTestAbortingTaskNotifyWait( void )
\r
552 TickType_t xTimeAtStart;
\r
553 BaseType_t xReturn;
\r
555 /* Note the time before the delay so the length of the delay is known. */
\r
556 xTimeAtStart = xTaskGetTickCount();
\r
558 /* This first delay should just time out. */
\r
559 xReturn = xTaskNotifyWait( 0, 0, NULL, xMaxBlockTime );
\r
560 if( xReturn != pdFALSE )
\r
562 xErrorOccurred = pdTRUE;
\r
564 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
\r
566 /* Note the time before the delay so the length of the delay is known. */
\r
567 xTimeAtStart = xTaskGetTickCount();
\r
569 /* This second delay should be aborted by the primary task half way
\r
571 xReturn = xTaskNotifyWait( 0, 0, NULL, xMaxBlockTime );
\r
572 if( xReturn != pdFALSE )
\r
574 xErrorOccurred = pdTRUE;
\r
576 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
\r
578 /* Note the time before the delay so the length of the delay is known. */
\r
579 xTimeAtStart = xTaskGetTickCount();
\r
581 /* This third delay should just time out again. */
\r
582 xReturn = xTaskNotifyWait( 0, 0, NULL, xMaxBlockTime );
\r
583 if( xReturn != pdFALSE )
\r
585 xErrorOccurred = pdTRUE;
\r
587 prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
\r
589 /*-----------------------------------------------------------*/
\r
591 static void prvCheckExpectedTimeIsWithinAnAcceptableMargin( TickType_t xStartTime, TickType_t xExpectedBlockTime )
\r
593 TickType_t xTimeNow, xActualBlockTime;
\r
595 xTimeNow = xTaskGetTickCount();
\r
596 xActualBlockTime = xTimeNow - xStartTime;
\r
598 /* The actual block time should not be less than the expected block time. */
\r
599 if( xActualBlockTime < xExpectedBlockTime )
\r
601 xErrorOccurred = pdTRUE;
\r
604 /* The actual block time can be greater than the expected block time, as it
\r
605 depends on the priority of the other tasks, but it should be within an
\r
606 acceptable margin. */
\r
607 if( xActualBlockTime > ( xExpectedBlockTime + xAllowableMargin ) )
\r
609 xErrorOccurred = pdTRUE;
\r
612 /*-----------------------------------------------------------*/
\r
614 BaseType_t xAreAbortDelayTestTasksStillRunning( void )
\r
616 static BaseType_t xLastControllingCycleCount = 0, xLastBlockingCycleCount = 0;
\r
617 BaseType_t xReturn = pdPASS;
\r
619 /* Have both tasks performed at least one cycle since this function was
\r
621 if( xControllingCycles == xLastControllingCycleCount )
\r
626 if( xBlockingCycles == xLastBlockingCycleCount )
\r
631 if( xErrorOccurred == pdTRUE )
\r
636 xLastBlockingCycleCount = xBlockingCycles;
\r
637 xLastControllingCycleCount = xControllingCycles;
\r
642 #endif /* INCLUDE_xTaskAbortDelay == 1 */
\r