@ -67,6 +67,7 @@
# include "TimerDemo.h"
# include "countsem.h"
# include "death.h"
# include "dynamic.h"
# include "QueueSet.h"
# include "QueueOverwrite.h"
# include "EventGroupsDemo.h"
@ -94,42 +95,16 @@
# define mainTIMER_TEST_PERIOD ( 50 )
/* Parameters that are passed into the register check tasks solely for the
purpose of ensuring parameters are passed into tasks correctly . */
# define mainREG_TEST_TASK_1_PARAMETER ( ( void * ) 0x12345678 )
# define mainREG_TEST_TASK_2_PARAMETER ( ( void * ) 0x87654321 )
/* Whether or not to enable interrupt queue tests. */
# define mainENABLE_INT_QUEUE_TESTS ( 0 )
/* The task that periodically checks that all the standard demo tasks are
* still executing and error free .
*/
static void prvCheckTask ( void * pvParameters ) ;
/* Tasks that implement register tests. */
static void prvRegTest1Task ( void * pvParameters ) ;
static void prvRegTest2Task ( void * pvParameters ) ;
/* Functions implemented in assembly file regtest_xtensa.S. */
extern void vRegTest1 ( void ) ;
extern void vRegTest2 ( void ) ;
/*-----------------------------------------------------------*/
/* The variable into which error messages are latched. */
static char * pcStatusMessage = " No errors " ;
/* The following two variables are used to communicate the status of the
register check tasks to the check task . If the variables keep incrementing ,
then the register check tasks have not discovered any errors . If a variable
stops incrementing , then an error has been found . */
volatile unsigned long ulRegTest1Counter = 0UL , ulRegTest2Counter = 0UL ;
/* The following variable is used to communicate whether the timers for the
IntQueue tests have been Initialized . This is needed to ensure that the queues
are accessed from the tick hook only after they have been created in the
interrupt queue test . */
volatile BaseType_t xTimerForQueueTestInitialized = pdFALSE ;
/*-----------------------------------------------------------*/
int main_full ( void )
@ -137,57 +112,45 @@ int main_full( void )
/* Start the check task as described at the top of this file. */
xTaskCreate ( prvCheckTask , " Check " , configMINIMAL_STACK_SIZE , NULL , mainCHECK_TASK_PRIORITY , NULL ) ;
# if( mainENABLE_INT_QUEUE_TESTS == 0 )
/* Create the standard demo tasks. */
vStartTaskNotifyTask ( ) ;
vStartBlockingQueueTasks ( mainBLOCK_Q_PRIORITY ) ;
vStartSemaphoreTasks ( mainSEM_TEST_PRIORITY ) ;
vStartPolledQueueTasks ( mainQUEUE_POLL_PRIORITY ) ;
vStartIntegerMathTasks ( mainINTEGER_TASK_PRIORITY ) ;
vStartGenericQueueTasks ( mainGEN_QUEUE_TASK_PRIORITY ) ;
vStartQueuePeekTasks ( ) ;
vStartMathTasks ( mainFLOP_TASK_PRIORITY ) ;
vStartRecursiveMutexTasks ( ) ;
vStartCountingSemaphoreTasks ( ) ;
vStartDynamicPriorityTasks ( ) ;
vStartQueueSetTasks ( ) ;
vStartQueueOverwriteTask ( mainQUEUE_OVERWRITE_PRIORITY ) ;
vStartEventGroupTasks ( ) ;
vStartInterruptSemaphoreTasks ( ) ;
vStartQueueSetPollingTask ( ) ;
vCreateBlockTimeTasks ( ) ;
vCreateAbortDelayTasks ( ) ;
vStartMessageBufferTasks ( configMINIMAL_STACK_SIZE ) ;
vStartStreamBufferTasks ( ) ;
vStartStreamBufferInterruptDemo ( ) ;
# if( configUSE_PREEMPTION != 0 )
{
/* Create the standard demo tasks. */
vStartTaskNotifyTask ( ) ;
vStartBlockingQueueTasks ( mainBLOCK_Q_PRIORITY ) ;
vStartSemaphoreTasks ( mainSEM_TEST_PRIORITY ) ;
vStartPolledQueueTasks ( mainQUEUE_POLL_PRIORITY ) ;
vStartIntegerMathTasks ( mainINTEGER_TASK_PRIORITY ) ;
vStartGenericQueueTasks ( mainGEN_QUEUE_TASK_PRIORITY ) ;
vStartQueuePeekTasks ( ) ;
vStartMathTasks ( mainFLOP_TASK_PRIORITY ) ;
vStartRecursiveMutexTasks ( ) ;
vStartCountingSemaphoreTasks ( ) ;
vStartQueueSetTasks ( ) ;
vStartQueueOverwriteTask ( mainQUEUE_OVERWRITE_PRIORITY ) ;
vStartEventGroupTasks ( ) ;
vStartInterruptSemaphoreTasks ( ) ;
vStartQueueSetPollingTask ( ) ;
vCreateBlockTimeTasks ( ) ;
# if( configUSE_PREEMPTION != 0 )
{
/* Don't expect these tasks to pass when preemption is not used. */
vStartTimerDemoTask ( mainTIMER_TEST_PERIOD ) ;
}
# endif
vCreateAbortDelayTasks ( ) ;
vStartMessageBufferTasks ( configMINIMAL_STACK_SIZE ) ;
vStartStreamBufferTasks ( ) ;
vStartStreamBufferInterruptDemo ( ) ;
/* Create the register check tasks, as described at the top of this file */
xTaskCreate ( prvRegTest1Task , " Reg1 " , configMINIMAL_STACK_SIZE , mainREG_TEST_TASK_1_PARAMETER , tskIDLE_PRIORITY , NULL ) ;
xTaskCreate ( prvRegTest2Task , " Reg2 " , configMINIMAL_STACK_SIZE , mainREG_TEST_TASK_2_PARAMETER , tskIDLE_PRIORITY , NULL ) ;
/* The suicide tasks must be created last as they need to know how many
tasks were running prior to their creation . This then allows them to
ascertain whether or not the correct / expected number of tasks are running at
any given time . */
vCreateSuicidalTasks ( mainCREATOR_TASK_PRIORITY ) ;
}
# else /* mainENABLE_INT_QUEUE_TESTS */
{
/* Start interrupt queue test tasks. */
vStartInterruptQueueTasks ( ) ;
/* Don't expect these tasks to pass when preemption is not used. */
vStartTimerDemoTask ( mainTIMER_TEST_PERIOD ) ;
}
# endif /* mainENABLE_INT_QUEUE_TESTS */
# endif
/* The suicide tasks must be created last as they need to know how many
tasks were running prior to their creation . This then allows them to
ascertain whether or not the correct / expected number of tasks are running at
any given time . */
vCreateSuicidalTasks ( mainCREATOR_TASK_PRIORITY ) ;
/* Start the scheduler itself. */
vTaskStartScheduler ( ) ;
@ -202,7 +165,6 @@ static void prvCheckTask( void *pvParameters )
{
TickType_t xNextWakeTime ;
const TickType_t xCycleFrequency = pdMS_TO_TICKS ( 5000UL ) ;
static unsigned long ulLastRegTest1Value = 0 , ulLastRegTest2Value = 0 ;
/* Just to remove compiler warning. */
( void ) pvParameters ;
@ -215,124 +177,105 @@ static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
/* Place this task in the blocked state until it is time to run again. */
vTaskDelayUntil ( & xNextWakeTime , xCycleFrequency ) ;
# if( mainENABLE_INT_QUEUE_TESTS == 0 )
/* Check the standard demo tasks are running without error. */
# if( configUSE_PREEMPTION != 0 )
{
/* 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 " ;
}
else if ( xAreBlockingQueuesStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: BlockQueue " ;
}
else if ( xAreSemaphoreTasksStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: SemTest " ;
}
else if ( xArePollingQueuesStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: PollQueue " ;
}
else if ( xAreIntegerMathsTaskStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: IntMath " ;
}
else if ( xAreGenericQueueTasksStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: GenQueue " ;
}
else if ( xAreQueuePeekTasksStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: QueuePeek " ;
}
else if ( xAreMathsTaskStillRunning ( ) ! = pdPASS )
{
pcStatusMessage = " Error: Flop " ;
}
else if ( xAreRecursiveMutexTasksStillRunning ( ) ! = pdTRUE )
/* These tasks are only created when preemption is used. */
if ( xAreTimerDemoTasksStillRunning ( xCycleFrequency ) ! = pdTRUE )
{
pcStatusMessage = " Error: RecMutex " ;
}
else if ( xAreCountingSemaphoreTasksStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: CountSem " ;
}
else if ( xAreQueueSetTasksStillRunning ( ) ! = pdPASS )
{
pcStatusMessage = " Error: Queue set " ;
}
else if ( xIsQueueOverwriteTaskStillRunning ( ) ! = pdPASS )
{
pcStatusMessage = " Error: Queue overwrite " ;
}
else if ( xAreEventGroupTasksStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: EventGroup " ;
}
else if ( xAreInterruptSemaphoreTasksStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: IntSem " ;
}
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 " ;
}
else if ( xAreMessageBufferTasksStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: MessageBuffer " ;
}
else if ( xAreStreamBufferTasksStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: StreamBuffer " ;
}
else if ( xIsInterruptStreamBufferDemoStillRunning ( ) ! = pdPASS )
{
pcStatusMessage = " Error: Stream buffer interrupt " ;
}
else if ( xIsCreateTaskStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: Death " ;
}
else if ( ulLastRegTest1Value = = ulRegTest1Counter )
{
pcStatusMessage = " Error: Reg Test 1 " ;
}
else if ( ulLastRegTest2Value = = ulRegTest2Counter )
{
pcStatusMessage = " Error: Reg Test 2 " ;
pcStatusMessage = " Error: TimerDemo " ;
}
}
# endif
/* Update register test counters. */
ulLastRegTest1Value = ulRegTest1Counter ;
ulLastRegTest2Value = ulRegTest2Counter ;
if ( xAreTaskNotificationTasksStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: Notification " ;
}
# else /* mainENABLE_INT_QUEUE_TESTS */
else if ( xAreIntegerMathsTaskStillRunning ( ) ! = pdTRUE )
{
if ( xAreIntQueueTasksStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: IntQueue " ;
}
pcStatusMessage = " Error: IntMath " ;
}
else if ( xAreGenericQueueTasksStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: GenQueue " ;
}
else if ( xAreBlockingQueuesStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: BlockQueue " ;
}
else if ( xAreSemaphoreTasksStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: SemTest " ;
}
else if ( xArePollingQueuesStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: PollQueue " ;
}
else if ( xAreQueuePeekTasksStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: QueuePeek " ;
}
else if ( xAreRecursiveMutexTasksStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: RecMutex " ;
}
else if ( xAreCountingSemaphoreTasksStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: CountSem " ;
}
else if ( xAreDynamicPriorityTasksStillRunning ( ) ! = pdPASS )
{
pcStatusMessage = " Error: Dynamic " ;
}
else if ( xAreQueueSetTasksStillRunning ( ) ! = pdPASS )
{
pcStatusMessage = " Error: Queue set " ;
}
else if ( xAreEventGroupTasksStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: EventGroup " ;
}
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 ( xAreMessageBufferTasksStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: MessageBuffer " ;
}
else if ( xAreAbortDelayTestTasksStillRunning ( ) ! = pdPASS )
{
pcStatusMessage = " Error: Abort delay " ;
}
else if ( xAreStreamBufferTasksStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: StreamBuffer " ;
}
else if ( xIsInterruptStreamBufferDemoStillRunning ( ) ! = pdPASS )
{
pcStatusMessage = " Error: Stream buffer interrupt " ;
}
else if ( xAreInterruptSemaphoreTasksStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: IntSem " ;
}
else if ( xIsCreateTaskStillRunning ( ) ! = pdTRUE )
{
pcStatusMessage = " Error: Death " ;
}
else if ( xAreMathsTaskStillRunning ( ) ! = pdPASS )
{
pcStatusMessage = " Error: Flop " ;
}
# endif /* mainENABLE_INT_QUEUE_TESTS */
/* This is the only task that uses stdout so its ok to call printf()
directly . */
@ -349,89 +292,39 @@ void vFullDemoTickHookFunction( void )
{
TaskHandle_t xTimerTask ;
# if( mainENABLE_INT_QUEUE_TESTS == 0 )
/* Call the periodic timer test, which tests the timer API functions that
can be called from an ISR . */
# if( configUSE_PREEMPTION != 0 )
{
/* Exercise using task notifications from an interrupt. */
xNotifyTaskFromISR ( ) ;
/* 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 periodic queue overwrite from ISR demo. */
vQueueOverwritePeriodicISRDemo ( ) ;
/* Exercise event groups from interrupts. */
vPeriodicEventGroupsProcessing ( ) ;
/* Only created when preemption is used. */
vTimerPeriodicISRTests ( ) ;
}
# endif
/* Exercise giving mutexes from an interrupt . */
vInterruptSemaphorePeriodicTest ( ) ;
/* Call the periodic queue overwrite from ISR demo. */
vQueueOverwritePeriodicISRDemo ( ) ;
/* Queue set access from interrupt. */
vQueueSetPollingInterruptAccess ( ) ;
/* Write to a queue that is in use as part of the queue set demo to
demonstrate using queue sets from an ISR . */
vQueueSetAccessQueueSetFromISR ( ) ;
vQueueSetPollingInterruptAccess ( ) ;
/* Call the periodic timer test, which tests the timer API functions that
can be called from an ISR . */
# if( configUSE_PREEMPTION != 0 )
{
/* Only created when preemption is used. */
vTimerPeriodicISRTests ( ) ;
}
# endif
/* Exercise event groups from interrupts. */
vPeriodicEventGroupsProcessing ( ) ;
/* Writes to stream buffer byte by byte to test the stream buffer trigger
level functionality . */
vPeriodicStreamBufferProcessing ( ) ;
/* Exercise giving mutexes from an interrupt. */
vInterruptSemaphorePeriodicTest ( ) ;
/* Writes a string to a string buffer four bytes at a time to demonstrate
a stream being sent from an interrupt to a task . */
vBasicStreamBufferSendFromISR ( ) ;
}
# else /* mainENABLE_INT_QUEUE_TESTS */
{
/* Access queues from interrupt. Make sure to access after the queues have
been created . */
if ( xTimerForQueueTestInitialized = = pdTRUE )
{
portYIELD_FROM_ISR ( xFirstTimerHandler ( ) ) ;
}
}
# endif /* mainENABLE_INT_QUEUE_TESTS */
}
/*-----------------------------------------------------------*/
/* Exercise using task notifications from an interrupt. */
xNotifyTaskFromISR ( ) ;
static void prvRegTest1Task ( void * pvParameters )
{
/* Although the regtest task is written in assembly, its entry point is
written in C for convenience of checking the task parameter is being passed
in correctly . */
if ( pvParameters = = mainREG_TEST_TASK_1_PARAMETER )
{
/* Start the part of the test that is written in assembly. */
vRegTest1 ( ) ;
}
/* Writes to stream buffer byte by byte to test the stream buffer trigger
level functionality . */
vPeriodicStreamBufferProcessing ( ) ;
/* The following line will only execute if the task parameter is found to
be incorrect . The check task will detect that the regtest loop counter is
not being incremented and flag an error . */
vTaskDelete ( NULL ) ;
/* Writes a string to a string buffer four bytes at a time to demonstrate
a stream being sent from an interrupt to a task . */
vBasicStreamBufferSendFromISR ( ) ;
}
/*-----------------------------------------------------------*/
static void prvRegTest2Task ( void * pvParameters )
{
/* Although the regtest task is written in assembly, its entry point is
written in C for convenience of checking the task parameter is being passed
in correctly . */
if ( pvParameters = = mainREG_TEST_TASK_2_PARAMETER )
{
/* Start the part of the test that is written in assembly. */
vRegTest2 ( ) ;
}
/* The following line will only execute if the task parameter is found to
be incorrect . The check task will detect that the regtest loop counter is
not being incremented and flag an error . */
vTaskDelete ( NULL ) ;
}
/*-----------------------------------------------------------*/