static void prvControllingTask( void *pvParameters ) { TaskHandle_t xBlockingTask; uint32_t ulTestToPerform = abtNOTIFY_WAIT_ABORTS; TickType_t xTimeAtStart; const TickType_t xStartMargin = 2UL; /* Just to remove compiler warnings. */ ( void ) pvParameters; xBlockingTask = xTaskGetTaskHandle( pcBlockingTaskName ); configASSERT( xBlockingTask ); for( ;; ) { /* Tell the secondary task to perform the next test. */ xTimeAtStart = xTaskGetTickCount(); xTaskNotify( xBlockingTask, ulTestToPerform, eSetValueWithOverwrite ); /* The secondary task has a higher priority, so will now be in the Blocked state to wait for a maximum of xMaxBlockTime. It expects that period to complete with a timeout. It will then block for xMaxBlockTimeAgain, but this time it expects to the block time to abort half way through. Block until it is time to send the abort to the secondary task. xStartMargin is used because this task takes timing from the beginning of the test, whereas the blocking task takes timing from the entry into the Blocked state - and as the tasks run at different priorities, there may be some discrepancy. Also, temporarily raise the priority of the controlling task to that of the blocking task to minimise discrepancies. */ vTaskPrioritySet( NULL, abtBLOCKING_PRIORITY ); vTaskDelay( xMaxBlockTime + xHalfMaxBlockTime + xStartMargin ); xTaskAbortDelay( xBlockingTask ); /* Reset the priority to the normal controlling priority. */ vTaskPrioritySet( NULL, abtCONTROLLING_PRIORITY ); /* Now wait to be notified that the secondary task has completed its test. */ ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); /* Did the entire test run for the expected time, which is two full block times plus the half block time caused by calling xTaskAbortDelay()? */ prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, ( xMaxBlockTime + xMaxBlockTime + xHalfMaxBlockTime ) ); /* Move onto the next test. */ ulTestToPerform++; if( ulTestToPerform >= abtMAX_TESTS ) { ulTestToPerform = 0; } /* To indicate this task is still executing. */ xControllingCycles++; } }
BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) { BaseType_t xReturn; BaseType_t xRunningPrivileged = xPortRaisePrivilege(); xReturn = xTaskAbortDelay( xTask ); vPortResetPrivilege( xRunningPrivileged ); return xReturn; }