void vApplicationTickHook( void ) { static xOLEDMessage xMessage = { "PASS" }; static unsigned long ulTicksSinceLastDisplay = 0; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; /* Called from every tick interrupt. Have enough ticks passed to make it time to perform our health status check again? */ ulTicksSinceLastDisplay++; if( ulTicksSinceLastDisplay >= mainCHECK_DELAY ) { ulTicksSinceLastDisplay = 0; /* Has an error been found in any task? */ if( xAreGenericQueueTasksStillRunning() != pdTRUE ) { xMessage.pcMessage = "ERROR IN GEN Q"; } else if( xIsCreateTaskStillRunning() != pdTRUE ) { xMessage.pcMessage = "ERROR IN CREATE"; } else if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) { xMessage.pcMessage = "ERROR IN MATH"; } else if( xAreIntQueueTasksStillRunning() != pdTRUE ) { xMessage.pcMessage = "ERROR IN INT QUEUE"; } else if( xAreBlockingQueuesStillRunning() != pdTRUE ) { xMessage.pcMessage = "ERROR IN BLOCK Q"; } else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) { xMessage.pcMessage = "ERROR IN BLOCK TIME"; } else if( xAreSemaphoreTasksStillRunning() != pdTRUE ) { xMessage.pcMessage = "ERROR IN SEMAPHORE"; } else if( xArePollingQueuesStillRunning() != pdTRUE ) { xMessage.pcMessage = "ERROR IN POLL Q"; } else if( xAreQueuePeekTasksStillRunning() != pdTRUE ) { xMessage.pcMessage = "ERROR IN PEEK Q"; } else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) { xMessage.pcMessage = "ERROR IN REC MUTEX"; } else if( xAreQueueSetTasksStillRunning() != pdPASS ) { xMessage.pcMessage = "ERROR IN Q SET"; } else if( xAreEventGroupTasksStillRunning() != pdTRUE ) { xMessage.pcMessage = "ERROR IN EVNT GRP"; } configASSERT( strcmp( ( const char * ) xMessage.pcMessage, "PASS" ) == 0 ); /* Send the message to the OLED gatekeeper for display. */ xHigherPriorityTaskWoken = pdFALSE; xQueueSendFromISR( xOLEDQueue, &xMessage, &xHigherPriorityTaskWoken ); } /* Write to a queue that is in use as part of the queue set demo to demonstrate using queue sets from an ISR. */ vQueueSetAccessQueueSetFromISR(); /* Call the event group ISR tests. */ vPeriodicEventGroupsProcessing(); }
static void prvCheckTask( void *pvParameters ) { TickType_t xNextWakeTime; const TickType_t xCycleFrequency = 2500 / portTICK_PERIOD_MS; /* Just to remove compiler warning. */ ( void ) pvParameters; /* Initialise xNextWakeTime - this only needs to be done once. */ xNextWakeTime = xTaskGetTickCount(); for( ;; ) { /* Place this task in the blocked state until it is time to run again. */ vTaskDelayUntil( &xNextWakeTime, xCycleFrequency ); /* Check the standard demo tasks are running without error. */ #if( configUSE_PREEMPTION != 0 ) { /* These tasks are only created when preemption is used. */ if( xAreTimerDemoTasksStillRunning( xCycleFrequency ) != pdTRUE ) { pcStatusMessage = "Error: TimerDemo"; } } #endif if( xAreEventGroupTasksStillRunning() != pdTRUE ) { pcStatusMessage = "Error: EventGroup"; } else if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) { pcStatusMessage = "Error: IntMath"; } else if( xAreGenericQueueTasksStillRunning() != pdTRUE ) { pcStatusMessage = "Error: GenQueue"; } else if( xAreQueuePeekTasksStillRunning() != pdTRUE ) { pcStatusMessage = "Error: QueuePeek"; } else if( xAreBlockingQueuesStillRunning() != pdTRUE ) { pcStatusMessage = "Error: BlockQueue"; } else if( xAreSemaphoreTasksStillRunning() != pdTRUE ) { pcStatusMessage = "Error: SemTest"; } else if( xArePollingQueuesStillRunning() != pdTRUE ) { pcStatusMessage = "Error: PollQueue"; } else if( xAreMathsTaskStillRunning() != pdPASS ) { pcStatusMessage = "Error: Flop"; } else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) { pcStatusMessage = "Error: RecMutex"; } else if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE ) { pcStatusMessage = "Error: CountSem"; } else if( xIsCreateTaskStillRunning() != pdTRUE ) { pcStatusMessage = "Error: Death"; } else if( xAreDynamicPriorityTasksStillRunning() != pdPASS ) { pcStatusMessage = "Error: Dynamic"; } else if( xAreQueueSetTasksStillRunning() != pdPASS ) { pcStatusMessage = "Error: Queue set"; } else if( xIsQueueOverwriteTaskStillRunning() != pdPASS ) { pcStatusMessage = "Error: Queue overwrite"; } /* This is the only task that uses stdout so its ok to call printf() directly. */ printf( "%s - %d\r\n", pcStatusMessage, xTaskGetTickCount() ); } }
static void prvCheckTask( void *pvParameters ) { TickType_t xDelayPeriod = mainNO_ERROR_CHECK_TASK_PERIOD; TickType_t xLastExecutionTime; static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; unsigned long ulErrorFound = pdFALSE; /* Just to stop compiler warnings. */ ( void ) pvParameters; /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() works correctly. */ xLastExecutionTime = xTaskGetTickCount(); /* Cycle for ever, delaying then checking all the other tasks are still operating without error. The onboard LED is toggled on each iteration. If an error is detected then the delay period is decreased from mainNO_ERROR_CHECK_TASK_PERIOD to mainERROR_CHECK_TASK_PERIOD. This has the effect of increasing the rate at which the onboard LED toggles, and in so doing gives visual feedback of the system status. */ for( ;; ) { /* Delay until it is time to execute again. */ vTaskDelayUntil( &xLastExecutionTime, xDelayPeriod ); /* Check all the demo tasks (other than the flash tasks) to ensure that they are all still running, and that none have detected an error. */ if( xAreIntQueueTasksStillRunning() != pdTRUE ) { ulErrorFound = 1UL << 0UL; } if( xAreMathsTaskStillRunning() != pdTRUE ) { ulErrorFound = 1UL << 1UL; } if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) { ulErrorFound = 1UL << 2UL; } if( xAreBlockingQueuesStillRunning() != pdTRUE ) { ulErrorFound = 1UL << 3UL; } if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) { ulErrorFound = 1UL << 4UL; } if ( xAreGenericQueueTasksStillRunning() != pdTRUE ) { ulErrorFound = 1UL << 5UL; } if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) { ulErrorFound = 1UL << 6UL; } if( xIsCreateTaskStillRunning() != pdTRUE ) { ulErrorFound = 1UL << 7UL; } if( xAreSemaphoreTasksStillRunning() != pdTRUE ) { ulErrorFound = 1UL << 8UL; } if( xAreTimerDemoTasksStillRunning( ( TickType_t ) xDelayPeriod ) != pdPASS ) { ulErrorFound = 1UL << 9UL; } if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE ) { ulErrorFound = 1UL << 10UL; } if( xIsQueueOverwriteTaskStillRunning() != pdPASS ) { ulErrorFound = 1UL << 11UL; } if( xAreEventGroupTasksStillRunning() != pdPASS ) { ulErrorFound = 1UL << 12UL; } if( xAreInterruptSemaphoreTasksStillRunning() != pdPASS ) { ulErrorFound = 1UL << 13UL; } if( xAreQueueSetTasksStillRunning() != pdPASS ) { ulErrorFound = 1UL << 14UL; } if( xAreTaskNotificationTasksStillRunning() != pdPASS ) { ulErrorFound = 1UL << 15UL; } /* Check that the register test 1 task is still running. */ if( ulLastRegTest1Value == ulRegTest1LoopCounter ) { ulErrorFound = 1UL << 16UL; } ulLastRegTest1Value = ulRegTest1LoopCounter; /* Check that the register test 2 task is still running. */ if( ulLastRegTest2Value == ulRegTest2LoopCounter ) { ulErrorFound = 1UL << 17UL; } ulLastRegTest2Value = ulRegTest2LoopCounter; /* Toggle the check LED to give an indication of the system status. If the LED toggles every mainNO_ERROR_CHECK_TASK_PERIOD milliseconds then everything is ok. A faster toggle indicates an error. */ mainTOGGLE_LED(); if( ulErrorFound != pdFALSE ) { /* An error has been detected in one of the tasks - flash the LED at a higher frequency to give visible feedback that something has gone wrong. */ xDelayPeriod = mainERROR_CHECK_TASK_PERIOD; } } }
static void prvCheckTimerCallback( TimerHandle_t xTimer ) { static long lChangedTimerPeriodAlready = pdFALSE; static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; unsigned long ulErrorOccurred = pdFALSE; /* Avoid compiler warnings. */ ( void ) xTimer; /* Have any of the standard demo tasks detected an error in their operation? */ if( xAreGenericQueueTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 3UL ); } else if( xAreQueuePeekTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 4UL ); } else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 5UL ); } else if( xAreSemaphoreTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 6UL ); } else if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 8UL ); } else if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 9UL ); } else if( xIsQueueOverwriteTaskStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 10UL ); } else if( xAreQueueSetTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 11UL ); } else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 12UL ); } else if( xAreEventGroupTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 13UL ); } else if( xAreTaskNotificationTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 14UL ); } else if( xAreInterruptSemaphoreTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 15UL ); } else if( xAreTimerDemoTasksStillRunning( mainCHECK_TIMER_PERIOD_MS ) != pdTRUE ) { ulErrorOccurred |= 1UL << 16UL; } else if( xAreIntQueueTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= 1UL << 17UL; } /* Check that the register test 1 task is still running. */ if( ulLastRegTest1Value == ulRegTest1LoopCounter ) { ulErrorOccurred |= 1UL << 18UL; } ulLastRegTest1Value = ulRegTest1LoopCounter; /* Check that the register test 2 task is still running. */ if( ulLastRegTest2Value == ulRegTest2LoopCounter ) { ulErrorOccurred |= 1UL << 19UL; } ulLastRegTest2Value = ulRegTest2LoopCounter; if( ulErrorOccurred != pdFALSE ) { /* An error occurred. Increase the frequency at which the check timer toggles its LED to give visual feedback of the potential error condition. */ if( lChangedTimerPeriodAlready == pdFALSE ) { lChangedTimerPeriodAlready = pdTRUE; /* This call to xTimerChangePeriod() uses a zero block time. Functions called from inside of a timer callback function must *never* attempt to block as to do so could impact other software timers. */ xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); } } /* Toggle the LED to give visual feedback of the system status. The rate at which the LED toggles will increase to mainERROR_CHECK_TIMER_PERIOD_MS if a suspected error has been found in any of the standard demo tasks. */ vParTestToggleLED( mainCHECK_LED ); }
static void prvCheckTask( void *pvParameters ) { TickType_t xNextWakeTime; const TickType_t xCycleFrequency = pdMS_TO_TICKS( 2500UL ); /* Just to remove compiler warning. */ ( void ) pvParameters; /* Initialise xNextWakeTime - this only needs to be done once. */ xNextWakeTime = xTaskGetTickCount(); for( ;; ) { /* Place this task in the blocked state until it is time to run again. */ vTaskDelayUntil( &xNextWakeTime, xCycleFrequency ); /* Check the standard demo tasks are running without error. */ #if( configUSE_PREEMPTION != 0 ) { /* These tasks are only created when preemption is used. */ if( xAreTimerDemoTasksStillRunning( xCycleFrequency ) != pdTRUE ) { pcStatusMessage = "Error: TimerDemo"; } } #endif if( xAreTaskNotificationTasksStillRunning() != pdTRUE ) { pcStatusMessage = "Error: Notification"; } if( xAreInterruptSemaphoreTasksStillRunning() != pdTRUE ) { pcStatusMessage = "Error: IntSem"; } else if( xAreEventGroupTasksStillRunning() != pdTRUE ) { pcStatusMessage = "Error: EventGroup"; } else if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) { pcStatusMessage = "Error: IntMath"; } else if( xAreGenericQueueTasksStillRunning() != pdTRUE ) { pcStatusMessage = "Error: GenQueue"; } else if( xAreQueuePeekTasksStillRunning() != pdTRUE ) { pcStatusMessage = "Error: QueuePeek"; } else if( xAreBlockingQueuesStillRunning() != pdTRUE ) { pcStatusMessage = "Error: BlockQueue"; } else if( xAreSemaphoreTasksStillRunning() != pdTRUE ) { pcStatusMessage = "Error: SemTest"; } else if( xArePollingQueuesStillRunning() != pdTRUE ) { pcStatusMessage = "Error: PollQueue"; } else if( xAreMathsTaskStillRunning() != pdPASS ) { pcStatusMessage = "Error: Flop"; } else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) { pcStatusMessage = "Error: RecMutex"; } else if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE ) { pcStatusMessage = "Error: CountSem"; } else if( xIsCreateTaskStillRunning() != pdTRUE ) { pcStatusMessage = "Error: Death"; } else if( xAreDynamicPriorityTasksStillRunning() != pdPASS ) { pcStatusMessage = "Error: Dynamic"; } else if( xAreQueueSetTasksStillRunning() != pdPASS ) { pcStatusMessage = "Error: Queue set"; } else if( xIsQueueOverwriteTaskStillRunning() != pdPASS ) { pcStatusMessage = "Error: Queue overwrite"; } else if( xAreQueueSetPollTasksStillRunning() != pdPASS ) { pcStatusMessage = "Error: Queue set polling"; } else if( xAreBlockTimeTestTasksStillRunning() != pdPASS ) { pcStatusMessage = "Error: Block time"; } else if( xAreAbortDelayTestTasksStillRunning() != pdPASS ) { pcStatusMessage = "Error: Abort delay"; } #if( configSUPPORT_STATIC_ALLOCATION == 1 ) else if( xAreStaticAllocationTasksStillRunning() != pdPASS ) { pcStatusMessage = "Error: Static allocation"; } #endif /* configSUPPORT_STATIC_ALLOCATION */ /* This is the only task that uses stdout so its ok to call printf() directly. */ printf( "%s - tick count %d - free heap %d - min free heap %d\r\n", pcStatusMessage, xTaskGetTickCount(), xPortGetFreeHeapSize(), xPortGetMinimumEverFreeHeapSize() ); } }
static void prvCheckTimerCallback( TimerHandle_t xTimer ) { static long lChangedTimerPeriodAlready = pdFALSE; static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0, ulLastHighFrequencyTimerInterrupts = 0; static const unsigned long ulExpectedHighFrequencyInterrupts = ( ( mainTEST_INTERRUPT_FREQUENCY / 1000UL ) * mainCHECK_TIMER_PERIOD_MS ) - 10; /* 10 allows for a margin of error. */ unsigned long ulErrorOccurred = pdFALSE; /* The count of the high frequency timer interrupts. */ extern unsigned long ulHighFrequencyTimerInterrupts; /* Avoid compiler warnings. */ ( void ) xTimer; /* Check that the register test 1 task is still running. */ if( ulLastRegTest1Value == ulRegTest1Cycles ) { ulErrorOccurred |= ( 0x01UL << 1UL ); } ulLastRegTest1Value = ulRegTest1Cycles; /* Check that the register test 2 task is still running. */ if( ulLastRegTest2Value == ulRegTest2Cycles ) { ulErrorOccurred |= ( 0x01UL << 2UL ); } ulLastRegTest2Value = ulRegTest2Cycles; /* Have any of the standard demo tasks detected an error in their operation? */ if( xAreGenericQueueTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 3UL ); } else if( xAreQueuePeekTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 4UL ); } else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 5UL ); } else if( xAreSemaphoreTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 6UL ); } else if( xAreIntQueueTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 7UL ); } else if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 8UL ); } else if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 9UL ); } else if( xIsQueueOverwriteTaskStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 10UL ); } else if( xAreQueueSetTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 11UL ); } else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 12UL ); } else if( xAreEventGroupTasksStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 13UL ); } else if( xAreMathsTaskStillRunning() != pdTRUE ) { ulErrorOccurred |= ( 0x01UL << 15UL ); } /* Ensure the expected number of high frequency interrupts have occurred. */ if( ulLastHighFrequencyTimerInterrupts != 0 ) { if( ( ulHighFrequencyTimerInterrupts - ulLastHighFrequencyTimerInterrupts ) < ulExpectedHighFrequencyInterrupts ) { ulErrorOccurred |= ( 0x01UL << 14UL ); } } ulLastHighFrequencyTimerInterrupts = ulHighFrequencyTimerInterrupts; if( ulErrorOccurred != pdFALSE ) { /* An error occurred. Increase the frequency at which the check timer toggles its LED to give visual feedback of the potential error condition. */ if( lChangedTimerPeriodAlready == pdFALSE ) { lChangedTimerPeriodAlready = pdTRUE; /* This call to xTimerChangePeriod() uses a zero block time. Functions called from inside of a timer callback function must *never* attempt to block as to do so could impact other software timers. */ xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); } } vParTestToggleLED( mainCHECK_LED ); }
static void prvCheckTimerCallback( TimerHandle_t xTimer ) { static long lChangedTimerPeriodAlready = pdFALSE; unsigned long ulErrorFound = pdFALSE; /* Check all the demo tasks (other than the flash tasks) to ensure they are all still running, and that none have detected an error. */ if( xAreIntQueueTasksStillRunning() != pdTRUE ) { ulErrorFound |= 1UL << 0UL; } if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) { ulErrorFound |= 1UL << 1UL; } if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) { ulErrorFound |= 1UL << 2UL; } if( xAreBlockingQueuesStillRunning() != pdTRUE ) { ulErrorFound |= 1UL << 3UL; } if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) { ulErrorFound |= 1UL << 4UL; } if ( xAreGenericQueueTasksStillRunning() != pdTRUE ) { ulErrorFound |= 1UL << 5UL; } if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) { ulErrorFound |= 1UL << 6UL; } if( xIsCreateTaskStillRunning() != pdTRUE ) { ulErrorFound |= 1UL << 7UL; } if( xArePollingQueuesStillRunning() != pdTRUE ) { ulErrorFound |= 1UL << 8UL; } if( xAreSemaphoreTasksStillRunning() != pdTRUE ) { ulErrorFound |= 1UL << 9UL; } if( xAreComTestTasksStillRunning() != pdTRUE ) { ulErrorFound |= 1UL << 10UL; } if( xAreQueueSetTasksStillRunning() != pdTRUE ) { ulErrorFound |= 1UL << 11UL; } if( xAreTaskNotificationTasksStillRunning() != pdTRUE ) { ulErrorFound |= 1UL << 12UL; } if( xAreTimerDemoTasksStillRunning( mainCHECK_TIMER_PERIOD_MS ) != pdTRUE ) { ulErrorFound |= 1UL << 13UL; } if( xAreEventGroupTasksStillRunning() != pdTRUE ) { ulErrorFound |= 1UL << 14UL; } if( xAreInterruptSemaphoreTasksStillRunning() != pdTRUE ) { ulErrorFound |= 1UL << 15UL; } /* Toggle the check LED to give an indication of the system status. If the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then everything is ok. A faster toggle indicates an error. */ vParTestToggleLED( mainCHECK_LED ); /* Have any errors been latch in ulErrorFound? If so, shorten the period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds. This will result in an increase in the rate at which mainCHECK_LED toggles. */ if( ulErrorFound != pdFALSE ) { if( lChangedTimerPeriodAlready == pdFALSE ) { lChangedTimerPeriodAlready = pdTRUE; /* This call to xTimerChangePeriod() uses a zero block time. Functions called from inside of a timer callback function must *never* attempt to block. */ xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); } } }