#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "AltBlock.h"
Go to the source code of this file.
Defines | |
#define | bktALLOWABLE_MARGIN ( 12 ) |
#define | bktDONT_BLOCK ( ( portTickType ) 0 ) |
#define | bktPRIMARY_BLOCK_TIME ( 10 ) |
#define | bktPRIMARY_PRIORITY ( 3 ) |
#define | bktQUEUE_LENGTH ( 5 ) |
#define | bktRUN_INDICATOR ( ( unsigned portBASE_TYPE ) 0x55 ) |
#define | bktSECONDARY_PRIORITY ( 2 ) |
#define | bktSHORT_WAIT ( ( ( portTickType ) 20 ) / portTICK_RATE_MS ) |
#define | bktTIME_TO_BLOCK ( 175 ) |
Functions | |
void | vCreateAltBlockTimeTasks (void) |
static void | vPrimaryBlockTimeTestTask (void *pvParameters) |
static void | vSecondaryBlockTimeTestTask (void *pvParameters) |
portBASE_TYPE | xAreAltBlockTimeTestTasksStillRunning (void) |
Variables | |
static portBASE_TYPE | xErrorOccurred = pdFALSE |
static portBASE_TYPE | xPrimaryCycles = 0 |
static volatile unsigned portBASE_TYPE | xRunIndicator |
static xTaskHandle | xSecondary |
static portBASE_TYPE | xSecondaryCycles = 0 |
static xQueueHandle | xTestQueue |
#define bktALLOWABLE_MARGIN ( 12 ) |
Definition at line 78 of file AltBlock.c.
Referenced by vPrimaryBlockTimeTestTask(), and vSecondaryBlockTimeTestTask().
#define bktDONT_BLOCK ( ( portTickType ) 0 ) |
#define bktPRIMARY_BLOCK_TIME ( 10 ) |
#define bktPRIMARY_PRIORITY ( 3 ) |
Definition at line 71 of file AltBlock.c.
Referenced by vCreateAltBlockTimeTasks(), vCreateBlockTimeTasks(), and vPrimaryBlockTimeTestTask().
#define bktQUEUE_LENGTH ( 5 ) |
Definition at line 75 of file AltBlock.c.
Referenced by vCreateAltBlockTimeTasks(), vCreateBlockTimeTasks(), and vPrimaryBlockTimeTestTask().
#define bktRUN_INDICATOR ( ( unsigned portBASE_TYPE ) 0x55 ) |
Definition at line 81 of file AltBlock.c.
Referenced by vPrimaryBlockTimeTestTask(), and vSecondaryBlockTimeTestTask().
#define bktSECONDARY_PRIORITY ( 2 ) |
Definition at line 72 of file AltBlock.c.
Referenced by vCreateAltBlockTimeTasks(), vCreateBlockTimeTasks(), and vPrimaryBlockTimeTestTask().
#define bktSHORT_WAIT ( ( ( portTickType ) 20 ) / portTICK_RATE_MS ) |
#define bktTIME_TO_BLOCK ( 175 ) |
void vCreateAltBlockTimeTasks | ( | void | ) |
Definition at line 104 of file AltBlock.c.
References bktPRIMARY_PRIORITY, bktQUEUE_LENGTH, bktSECONDARY_PRIORITY, configMINIMAL_STACK_SIZE, portBASE_TYPE, portCHAR, vPrimaryBlockTimeTestTask(), vQueueAddToRegistry, vSecondaryBlockTimeTestTask(), xQueueCreate(), xSecondary, xTaskCreate, and xTestQueue.
00105 { 00106 /* Create the queue on which the two tasks block. */ 00107 xTestQueue = xQueueCreate( bktQUEUE_LENGTH, sizeof( portBASE_TYPE ) ); 00108 00109 /* vQueueAddToRegistry() adds the queue to the queue registry, if one is 00110 in use. The queue registry is provided as a means for kernel aware 00111 debuggers to locate queues and has no purpose if a kernel aware debugger 00112 is not being used. The call to vQueueAddToRegistry() will be removed 00113 by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is 00114 defined to be less than 1. */ 00115 vQueueAddToRegistry( xTestQueue, ( signed portCHAR * ) "AltBlockQueue" ); 00116 00117 00118 /* Create the two test tasks. */ 00119 xTaskCreate( vPrimaryBlockTimeTestTask, ( signed portCHAR * )"FBTest1", configMINIMAL_STACK_SIZE, NULL, bktPRIMARY_PRIORITY, NULL ); 00120 xTaskCreate( vSecondaryBlockTimeTestTask, ( signed portCHAR * )"FBTest2", configMINIMAL_STACK_SIZE, NULL, bktSECONDARY_PRIORITY, &xSecondary ); 00121 }
static void vPrimaryBlockTimeTestTask | ( | void * | pvParameters | ) | [static] |
Definition at line 124 of file AltBlock.c.
References bktALLOWABLE_MARGIN, bktDONT_BLOCK, bktPRIMARY_BLOCK_TIME, bktPRIMARY_PRIORITY, bktQUEUE_LENGTH, bktRUN_INDICATOR, bktSECONDARY_PRIORITY, bktSHORT_WAIT, errQUEUE_EMPTY, errQUEUE_FULL, pdPASS, pdTRUE, portBASE_TYPE, portCHAR, portENTER_CRITICAL, portEXIT_CRITICAL, taskYIELD, vPrintDisplayMessage(), vTaskDelay(), vTaskPrioritySet(), vTaskResume(), xErrorOccurred, xPrimaryCycles, xQueueAltReceive, xQueueAltSendToBack, xRunIndicator, xSecondary, xTaskGetTickCount(), and xTestQueue.
Referenced by vCreateAltBlockTimeTasks(), and vCreateBlockTimeTasks().
00125 { 00126 portBASE_TYPE xItem, xData; 00127 portTickType xTimeWhenBlocking; 00128 portTickType xTimeToBlock, xBlockedTime; 00129 00130 #ifdef USE_STDIO 00131 void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); 00132 00133 const portCHAR * const pcTaskStartMsg = "Alt primary block time test started.\r\n"; 00134 00135 /* Queue a message for printing to say the task has started. */ 00136 vPrintDisplayMessage( &pcTaskStartMsg ); 00137 #endif 00138 00139 ( void ) pvParameters; 00140 00141 for( ;; ) 00142 { 00143 /********************************************************************* 00144 Test 1 00145 00146 Simple block time wakeup test on queue receives. */ 00147 for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) 00148 { 00149 /* The queue is empty. Attempt to read from the queue using a block 00150 time. When we wake, ensure the delta in time is as expected. */ 00151 xTimeToBlock = bktPRIMARY_BLOCK_TIME << xItem; 00152 00153 /* A critical section is used to minimise the jitter in the time 00154 measurements. */ 00155 portENTER_CRITICAL(); 00156 { 00157 xTimeWhenBlocking = xTaskGetTickCount(); 00158 00159 /* We should unblock after xTimeToBlock having not received 00160 anything on the queue. */ 00161 if( xQueueAltReceive( xTestQueue, &xData, xTimeToBlock ) != errQUEUE_EMPTY ) 00162 { 00163 xErrorOccurred = pdTRUE; 00164 } 00165 00166 /* How long were we blocked for? */ 00167 xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; 00168 } 00169 portEXIT_CRITICAL(); 00170 00171 if( xBlockedTime < xTimeToBlock ) 00172 { 00173 /* Should not have blocked for less than we requested. */ 00174 xErrorOccurred = pdTRUE; 00175 } 00176 00177 if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) ) 00178 { 00179 /* Should not have blocked for longer than we requested, 00180 although we would not necessarily run as soon as we were 00181 unblocked so a margin is allowed. */ 00182 xErrorOccurred = pdTRUE; 00183 } 00184 } 00185 00186 00187 #if configUSE_PREEMPTION == 0 00188 taskYIELD(); 00189 #endif 00190 00191 00192 /********************************************************************* 00193 Test 2 00194 00195 Simple block time wakeup test on queue sends. 00196 00197 First fill the queue. It should be empty so all sends should pass. */ 00198 for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) 00199 { 00200 if( xQueueAltSendToBack( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) 00201 { 00202 xErrorOccurred = pdTRUE; 00203 } 00204 } 00205 00206 for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) 00207 { 00208 /* The queue is full. Attempt to write to the queue using a block 00209 time. When we wake, ensure the delta in time is as expected. */ 00210 xTimeToBlock = bktPRIMARY_BLOCK_TIME << xItem; 00211 00212 portENTER_CRITICAL(); 00213 { 00214 xTimeWhenBlocking = xTaskGetTickCount(); 00215 00216 /* We should unblock after xTimeToBlock having not received 00217 anything on the queue. */ 00218 if( xQueueAltSendToBack( xTestQueue, &xItem, xTimeToBlock ) != errQUEUE_FULL ) 00219 { 00220 xErrorOccurred = pdTRUE; 00221 } 00222 00223 /* How long were we blocked for? */ 00224 xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; 00225 } 00226 portEXIT_CRITICAL(); 00227 00228 if( xBlockedTime < xTimeToBlock ) 00229 { 00230 /* Should not have blocked for less than we requested. */ 00231 xErrorOccurred = pdTRUE; 00232 } 00233 00234 if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) ) 00235 { 00236 /* Should not have blocked for longer than we requested, 00237 although we would not necessarily run as soon as we were 00238 unblocked so a margin is allowed. */ 00239 xErrorOccurred = pdTRUE; 00240 } 00241 } 00242 00243 #if configUSE_PREEMPTION == 0 00244 taskYIELD(); 00245 #endif 00246 00247 00248 /********************************************************************* 00249 Test 3 00250 00251 Wake the other task, it will block attempting to post to the queue. 00252 When we read from the queue the other task will wake, but before it 00253 can run we will post to the queue again. When the other task runs it 00254 will find the queue still full, even though it was woken. It should 00255 recognise that its block time has not expired and return to block for 00256 the remains of its block time. 00257 00258 Wake the other task so it blocks attempting to post to the already 00259 full queue. */ 00260 xRunIndicator = 0; 00261 vTaskResume( xSecondary ); 00262 00263 /* We need to wait a little to ensure the other task executes. */ 00264 while( xRunIndicator != bktRUN_INDICATOR ) 00265 { 00266 /* The other task has not yet executed. */ 00267 vTaskDelay( bktSHORT_WAIT ); 00268 } 00269 /* Make sure the other task is blocked on the queue. */ 00270 vTaskDelay( bktSHORT_WAIT ); 00271 xRunIndicator = 0; 00272 00273 for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) 00274 { 00275 /* Now when we make space on the queue the other task should wake 00276 but not execute as this task has higher priority. */ 00277 if( xQueueAltReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) 00278 { 00279 xErrorOccurred = pdTRUE; 00280 } 00281 00282 /* Now fill the queue again before the other task gets a chance to 00283 execute. If the other task had executed we would find the queue 00284 full ourselves, and the other task have set xRunIndicator. */ 00285 if( xQueueAltSendToBack( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) 00286 { 00287 xErrorOccurred = pdTRUE; 00288 } 00289 00290 if( xRunIndicator == bktRUN_INDICATOR ) 00291 { 00292 /* The other task should not have executed. */ 00293 xErrorOccurred = pdTRUE; 00294 } 00295 00296 /* Raise the priority of the other task so it executes and blocks 00297 on the queue again. */ 00298 vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 ); 00299 00300 /* The other task should now have re-blocked without exiting the 00301 queue function. */ 00302 if( xRunIndicator == bktRUN_INDICATOR ) 00303 { 00304 /* The other task should not have executed outside of the 00305 queue function. */ 00306 xErrorOccurred = pdTRUE; 00307 } 00308 00309 /* Set the priority back down. */ 00310 vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY ); 00311 } 00312 00313 /* Let the other task timeout. When it unblockes it will check that it 00314 unblocked at the correct time, then suspend itself. */ 00315 while( xRunIndicator != bktRUN_INDICATOR ) 00316 { 00317 vTaskDelay( bktSHORT_WAIT ); 00318 } 00319 vTaskDelay( bktSHORT_WAIT ); 00320 xRunIndicator = 0; 00321 00322 #if configUSE_PREEMPTION == 0 00323 taskYIELD(); 00324 #endif 00325 00326 /********************************************************************* 00327 Test 4 00328 00329 As per test 3 - but with the send and receive the other way around. 00330 The other task blocks attempting to read from the queue. 00331 00332 Empty the queue. We should find that it is full. */ 00333 for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) 00334 { 00335 if( xQueueAltReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) 00336 { 00337 xErrorOccurred = pdTRUE; 00338 } 00339 } 00340 00341 /* Wake the other task so it blocks attempting to read from the 00342 already empty queue. */ 00343 vTaskResume( xSecondary ); 00344 00345 /* We need to wait a little to ensure the other task executes. */ 00346 while( xRunIndicator != bktRUN_INDICATOR ) 00347 { 00348 vTaskDelay( bktSHORT_WAIT ); 00349 } 00350 vTaskDelay( bktSHORT_WAIT ); 00351 xRunIndicator = 0; 00352 00353 for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) 00354 { 00355 /* Now when we place an item on the queue the other task should 00356 wake but not execute as this task has higher priority. */ 00357 if( xQueueAltSendToBack( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) 00358 { 00359 xErrorOccurred = pdTRUE; 00360 } 00361 00362 /* Now empty the queue again before the other task gets a chance to 00363 execute. If the other task had executed we would find the queue 00364 empty ourselves, and the other task would be suspended. */ 00365 if( xQueueAltReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) 00366 { 00367 xErrorOccurred = pdTRUE; 00368 } 00369 00370 if( xRunIndicator == bktRUN_INDICATOR ) 00371 { 00372 /* The other task should not have executed. */ 00373 xErrorOccurred = pdTRUE; 00374 } 00375 00376 /* Raise the priority of the other task so it executes and blocks 00377 on the queue again. */ 00378 vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 ); 00379 00380 /* The other task should now have re-blocked without exiting the 00381 queue function. */ 00382 if( xRunIndicator == bktRUN_INDICATOR ) 00383 { 00384 /* The other task should not have executed outside of the 00385 queue function. */ 00386 xErrorOccurred = pdTRUE; 00387 } 00388 vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY ); 00389 } 00390 00391 /* Let the other task timeout. When it unblockes it will check that it 00392 unblocked at the correct time, then suspend itself. */ 00393 while( xRunIndicator != bktRUN_INDICATOR ) 00394 { 00395 vTaskDelay( bktSHORT_WAIT ); 00396 } 00397 vTaskDelay( bktSHORT_WAIT ); 00398 00399 xPrimaryCycles++; 00400 } 00401 }
static void vSecondaryBlockTimeTestTask | ( | void * | pvParameters | ) | [static] |
Definition at line 404 of file AltBlock.c.
References bktALLOWABLE_MARGIN, bktRUN_INDICATOR, bktTIME_TO_BLOCK, errQUEUE_EMPTY, errQUEUE_FULL, pdTRUE, portBASE_TYPE, portCHAR, portENTER_CRITICAL, portEXIT_CRITICAL, vPrintDisplayMessage(), vTaskSuspend(), xErrorOccurred, xQueueAltReceive, xQueueAltSendToBack, xRunIndicator, xSecondaryCycles, xTaskGetTickCount(), and xTestQueue.
Referenced by vCreateAltBlockTimeTasks(), and vCreateBlockTimeTasks().
00405 { 00406 portTickType xTimeWhenBlocking, xBlockedTime; 00407 portBASE_TYPE xData; 00408 00409 #ifdef USE_STDIO 00410 void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); 00411 00412 const portCHAR * const pcTaskStartMsg = "Alt secondary block time test started.\r\n"; 00413 00414 /* Queue a message for printing to say the task has started. */ 00415 vPrintDisplayMessage( &pcTaskStartMsg ); 00416 #endif 00417 00418 ( void ) pvParameters; 00419 00420 for( ;; ) 00421 { 00422 /********************************************************************* 00423 Test 1 and 2 00424 00425 This task does does not participate in these tests. */ 00426 vTaskSuspend( NULL ); 00427 00428 /********************************************************************* 00429 Test 3 00430 00431 The first thing we do is attempt to read from the queue. It should be 00432 full so we block. Note the time before we block so we can check the 00433 wake time is as per that expected. */ 00434 portENTER_CRITICAL(); 00435 { 00436 xTimeWhenBlocking = xTaskGetTickCount(); 00437 00438 /* We should unblock after bktTIME_TO_BLOCK having not received 00439 anything on the queue. */ 00440 xData = 0; 00441 xRunIndicator = bktRUN_INDICATOR; 00442 if( xQueueAltSendToBack( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_FULL ) 00443 { 00444 xErrorOccurred = pdTRUE; 00445 } 00446 00447 /* How long were we inside the send function? */ 00448 xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; 00449 } 00450 portEXIT_CRITICAL(); 00451 00452 /* We should not have blocked for less time than bktTIME_TO_BLOCK. */ 00453 if( xBlockedTime < bktTIME_TO_BLOCK ) 00454 { 00455 xErrorOccurred = pdTRUE; 00456 } 00457 00458 /* We should of not blocked for much longer than bktALLOWABLE_MARGIN 00459 either. A margin is permitted as we would not necessarily run as 00460 soon as we unblocked. */ 00461 if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) ) 00462 { 00463 xErrorOccurred = pdTRUE; 00464 } 00465 00466 /* Suspend ready for test 3. */ 00467 xRunIndicator = bktRUN_INDICATOR; 00468 vTaskSuspend( NULL ); 00469 00470 /********************************************************************* 00471 Test 4 00472 00473 As per test three, but with the send and receive reversed. */ 00474 portENTER_CRITICAL(); 00475 { 00476 xTimeWhenBlocking = xTaskGetTickCount(); 00477 00478 /* We should unblock after bktTIME_TO_BLOCK having not received 00479 anything on the queue. */ 00480 xRunIndicator = bktRUN_INDICATOR; 00481 if( xQueueAltReceive( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_EMPTY ) 00482 { 00483 xErrorOccurred = pdTRUE; 00484 } 00485 00486 xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; 00487 } 00488 portEXIT_CRITICAL(); 00489 00490 /* We should not have blocked for less time than bktTIME_TO_BLOCK. */ 00491 if( xBlockedTime < bktTIME_TO_BLOCK ) 00492 { 00493 xErrorOccurred = pdTRUE; 00494 } 00495 00496 /* We should of not blocked for much longer than bktALLOWABLE_MARGIN 00497 either. A margin is permitted as we would not necessarily run as soon 00498 as we unblocked. */ 00499 if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) ) 00500 { 00501 xErrorOccurred = pdTRUE; 00502 } 00503 00504 xRunIndicator = bktRUN_INDICATOR; 00505 00506 xSecondaryCycles++; 00507 } 00508 }
portBASE_TYPE xAreAltBlockTimeTestTasksStillRunning | ( | void | ) |
Definition at line 511 of file AltBlock.c.
References pdFAIL, pdPASS, pdTRUE, portBASE_TYPE, xErrorOccurred, xPrimaryCycles, and xSecondaryCycles.
00512 { 00513 static portBASE_TYPE xLastPrimaryCycleCount = 0, xLastSecondaryCycleCount = 0; 00514 portBASE_TYPE xReturn = pdPASS; 00515 00516 /* Have both tasks performed at least one cycle since this function was 00517 last called? */ 00518 if( xPrimaryCycles == xLastPrimaryCycleCount ) 00519 { 00520 xReturn = pdFAIL; 00521 } 00522 00523 if( xSecondaryCycles == xLastSecondaryCycleCount ) 00524 { 00525 xReturn = pdFAIL; 00526 } 00527 00528 if( xErrorOccurred == pdTRUE ) 00529 { 00530 xReturn = pdFAIL; 00531 } 00532 00533 xLastSecondaryCycleCount = xSecondaryCycles; 00534 xLastPrimaryCycleCount = xPrimaryCycles; 00535 00536 return xReturn; 00537 }
portBASE_TYPE xErrorOccurred = pdFALSE [static] |
Definition at line 92 of file AltBlock.c.
Referenced by portTASK_FUNCTION(), prvRecursiveMutexBlockingTask(), prvRecursiveMutexControllingTask(), prvRecursiveMutexPollingTask(), vPrimaryBlockTimeTestTask(), vSecondaryBlockTimeTestTask(), xAreAltBlockTimeTestTasksStillRunning(), xAreBlockTimeTestTasksStillRunning(), and xAreRecursiveMutexTasksStillRunning().
portBASE_TYPE xPrimaryCycles = 0 [static] |
Definition at line 91 of file AltBlock.c.
Referenced by vPrimaryBlockTimeTestTask(), xAreAltBlockTimeTestTasksStillRunning(), and xAreBlockTimeTestTasksStillRunning().
volatile unsigned portBASE_TYPE xRunIndicator [static] |
Definition at line 96 of file AltBlock.c.
Referenced by vPrimaryBlockTimeTestTask(), and vSecondaryBlockTimeTestTask().
xTaskHandle xSecondary [static] |
Definition at line 88 of file AltBlock.c.
Referenced by vCreateAltBlockTimeTasks(), vCreateBlockTimeTasks(), and vPrimaryBlockTimeTestTask().
portBASE_TYPE xSecondaryCycles = 0 [static] |
Definition at line 91 of file AltBlock.c.
Referenced by vSecondaryBlockTimeTestTask(), xAreAltBlockTimeTestTasksStillRunning(), and xAreBlockTimeTestTasksStillRunning().
xQueueHandle xTestQueue [static] |
Definition at line 84 of file AltBlock.c.
Referenced by vCreateAltBlockTimeTasks(), vCreateBlockTimeTasks(), vPrimaryBlockTimeTestTask(), and vSecondaryBlockTimeTestTask().