|
|
@ -56,7 +56,7 @@
|
|
|
|
* If you would prefer a much simpler project to get started with then select
|
|
|
|
* If you would prefer a much simpler project to get started with then select
|
|
|
|
* the 'Blinky' build configuration within the HEW IDE.
|
|
|
|
* the 'Blinky' build configuration within the HEW IDE.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Creates all the demo application tasks, then starts the scheduler. The WEB
|
|
|
|
* Creates all the demo application tasks, then starts the scheduler. The web
|
|
|
|
* documentation provides more details of the standard demo application tasks,
|
|
|
|
* documentation provides more details of the standard demo application tasks,
|
|
|
|
* which provide no particular functionality but do provide a good example of
|
|
|
|
* which provide no particular functionality but do provide a good example of
|
|
|
|
* how to use the FreeRTOS API. The tasks defined in flop.c are included in the
|
|
|
|
* how to use the FreeRTOS API. The tasks defined in flop.c are included in the
|
|
|
@ -68,15 +68,14 @@
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* "Reg test" tasks - These fill the registers with known values, then check
|
|
|
|
* "Reg test" tasks - These fill the registers with known values, then check
|
|
|
|
* that each register still contains its expected value. Each task uses
|
|
|
|
* that each register still contains its expected value. Each task uses
|
|
|
|
* different values. The tasks run with very low priority so get preempted very
|
|
|
|
* different values. The tasks run with very low priority so get preempted
|
|
|
|
* frequently. A register containing an unexpected value is indicative of an
|
|
|
|
* very frequently. A check variable is incremented on each iteration of the
|
|
|
|
* error in the context switching mechanism and will result in interrupts being
|
|
|
|
* test loop. A register containing an unexpected value is indicative of an
|
|
|
|
* disabled and a branch to a null loop. This has the effect of stopping
|
|
|
|
* error in the context switching mechanism and will result in a branch to a
|
|
|
|
* execution of all the tests and tasks, which in turn results in all LED
|
|
|
|
* null loop - which in turn will prevent the check variable from incrementing
|
|
|
|
* activity stopping too. The nature of the reg test tasks necessitates that
|
|
|
|
* any further and allow the check task (described below) to determine that an
|
|
|
|
* they are written in assembly code. The check task (described below) checks
|
|
|
|
* error has occurred. The nature of the reg test tasks necessitates that they
|
|
|
|
* that the reg test tasks are still executing and will indicate an error if
|
|
|
|
* are written in assembly code.
|
|
|
|
* either reg test task is found to have stalled.
|
|
|
|
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* "Check" task - This only executes every five seconds but has a high priority
|
|
|
|
* "Check" task - This only executes every five seconds but has a high priority
|
|
|
|
* to ensure it gets processor time. Its main function is to check that all the
|
|
|
|
* to ensure it gets processor time. Its main function is to check that all the
|
|
|
@ -277,6 +276,7 @@ portTickType xNextWakeTime, xCycleFrequency = mainNO_ERROR_CYCLE_TIME;
|
|
|
|
extern void vSetupHighFrequencyTimer( void );
|
|
|
|
extern void vSetupHighFrequencyTimer( void );
|
|
|
|
extern volatile unsigned short usMaxJitter;
|
|
|
|
extern volatile unsigned short usMaxJitter;
|
|
|
|
volatile unsigned long ulActualJitter = 0;
|
|
|
|
volatile unsigned long ulActualJitter = 0;
|
|
|
|
|
|
|
|
static char cErrorText[ 100 ];
|
|
|
|
|
|
|
|
|
|
|
|
/* If this is being executed then the kernel has been started. Start the high
|
|
|
|
/* If this is being executed then the kernel has been started. Start the high
|
|
|
|
frequency timer test as described at the top of this file. This is only
|
|
|
|
frequency timer test as described at the top of this file. This is only
|
|
|
@ -301,46 +301,57 @@ volatile unsigned long ulActualJitter = 0;
|
|
|
|
rate at which mainCHECK_LED flashes to give visual feedback that an error
|
|
|
|
rate at which mainCHECK_LED flashes to give visual feedback that an error
|
|
|
|
has occurred. */
|
|
|
|
has occurred. */
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
|
|
|
|
strcpy( cErrorText, "Error: GenQueue" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
|
|
|
|
else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
|
|
|
|
strcpy( cErrorText, "Error: QueuePeek" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( xAreBlockingQueuesStillRunning() != pdTRUE )
|
|
|
|
else if( xAreBlockingQueuesStillRunning() != pdTRUE )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
|
|
|
|
strcpy( cErrorText, "Error: BlockQueue" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
|
|
|
|
else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
|
|
|
|
strcpy( cErrorText, "Error: BlockTime" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( xAreSemaphoreTasksStillRunning() != pdTRUE )
|
|
|
|
else if( xAreSemaphoreTasksStillRunning() != pdTRUE )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
|
|
|
|
strcpy( cErrorText, "Error: SemTest" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( xArePollingQueuesStillRunning() != pdTRUE )
|
|
|
|
else if( xArePollingQueuesStillRunning() != pdTRUE )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
|
|
|
|
strcpy( cErrorText, "Error: PollQueue" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( xIsCreateTaskStillRunning() != pdTRUE )
|
|
|
|
else if( xIsCreateTaskStillRunning() != pdTRUE )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
|
|
|
|
strcpy( cErrorText, "Error: Death" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
|
|
|
|
else if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
|
|
|
|
strcpy( cErrorText, "Error: IntMath" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
|
|
|
|
else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
|
|
|
|
strcpy( cErrorText, "Error: RecMutex" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( xAreIntQueueTasksStillRunning() != pdPASS )
|
|
|
|
else if( xAreIntQueueTasksStillRunning() != pdPASS )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
|
|
|
|
strcpy( cErrorText, "Error: IntQueue" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( xAreMathsTaskStillRunning() != pdPASS )
|
|
|
|
else if( xAreMathsTaskStillRunning() != pdPASS )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
|
|
|
|
strcpy( cErrorText, "Error: Flop" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Check the reg test tasks are still cycling. They will stop incrementing
|
|
|
|
/* Check the reg test tasks are still cycling. They will stop incrementing
|
|
|
@ -348,11 +359,13 @@ volatile unsigned long ulActualJitter = 0;
|
|
|
|
if( ulRegTest1CycleCount == ulLastRegTest1CycleCount )
|
|
|
|
if( ulRegTest1CycleCount == ulLastRegTest1CycleCount )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
|
|
|
|
strcpy( cErrorText, "Error: RegTest1" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if( ulRegTest2CycleCount == ulLastRegTest2CycleCount )
|
|
|
|
if( ulRegTest2CycleCount == ulLastRegTest2CycleCount )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
xCycleFrequency = mainERROR_CYCLE_TIME;
|
|
|
|
|
|
|
|
strcpy( cErrorText, "Error: RegTest2" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ulLastRegTest1CycleCount = ulRegTest1CycleCount;
|
|
|
|
ulLastRegTest1CycleCount = ulRegTest1CycleCount;
|
|
|
@ -505,43 +518,42 @@ TestLoop1:
|
|
|
|
; Now compare each register to ensure it still contains the value that was
|
|
|
|
; Now compare each register to ensure it still contains the value that was
|
|
|
|
; set before this loop was entered.
|
|
|
|
; set before this loop was entered.
|
|
|
|
CMP #1, R1
|
|
|
|
CMP #1, R1
|
|
|
|
BNE RegTest2Error
|
|
|
|
BNE RegTest1Error
|
|
|
|
CMP #2, R2
|
|
|
|
CMP #2, R2
|
|
|
|
BNE RegTest2Error
|
|
|
|
BNE RegTest1Error
|
|
|
|
CMP #3, R3
|
|
|
|
CMP #3, R3
|
|
|
|
BNE RegTest2Error
|
|
|
|
BNE RegTest1Error
|
|
|
|
CMP #4, R4
|
|
|
|
CMP #4, R4
|
|
|
|
BNE RegTest2Error
|
|
|
|
BNE RegTest1Error
|
|
|
|
CMP #5, R5
|
|
|
|
CMP #5, R5
|
|
|
|
BNE RegTest2Error
|
|
|
|
BNE RegTest1Error
|
|
|
|
CMP #6, R6
|
|
|
|
CMP #6, R6
|
|
|
|
BNE RegTest2Error
|
|
|
|
BNE RegTest1Error
|
|
|
|
CMP #7, R7
|
|
|
|
CMP #7, R7
|
|
|
|
BNE RegTest2Error
|
|
|
|
BNE RegTest1Error
|
|
|
|
CMP #8, R8
|
|
|
|
CMP #8, R8
|
|
|
|
BNE RegTest2Error
|
|
|
|
BNE RegTest1Error
|
|
|
|
CMP #9, R9
|
|
|
|
CMP #9, R9
|
|
|
|
BNE RegTest2Error
|
|
|
|
BNE RegTest1Error
|
|
|
|
CMP #10, R10
|
|
|
|
CMP #10, R10
|
|
|
|
BNE RegTest2Error
|
|
|
|
BNE RegTest1Error
|
|
|
|
CMP #11, R11
|
|
|
|
CMP #11, R11
|
|
|
|
BNE RegTest2Error
|
|
|
|
BNE RegTest1Error
|
|
|
|
CMP #12, R12
|
|
|
|
CMP #12, R12
|
|
|
|
BNE RegTest2Error
|
|
|
|
BNE RegTest1Error
|
|
|
|
CMP #13, R13
|
|
|
|
CMP #13, R13
|
|
|
|
BNE RegTest2Error
|
|
|
|
BNE RegTest1Error
|
|
|
|
CMP #14, R14
|
|
|
|
CMP #14, R14
|
|
|
|
BNE RegTest2Error
|
|
|
|
BNE RegTest1Error
|
|
|
|
CMP #15, R15
|
|
|
|
CMP #15, R15
|
|
|
|
BNE RegTest2Error
|
|
|
|
BNE RegTest1Error
|
|
|
|
|
|
|
|
|
|
|
|
; All comparisons passed, start a new itteratio of this loop.
|
|
|
|
; All comparisons passed, start a new itteratio of this loop.
|
|
|
|
BRA TestLoop1
|
|
|
|
BRA TestLoop1
|
|
|
|
|
|
|
|
|
|
|
|
RegTest1Error:
|
|
|
|
RegTest1Error:
|
|
|
|
; A compare failed, something has gone wrong. Stop the tick and any other
|
|
|
|
; A compare failed, just loop here so the loop counter stops incrementing
|
|
|
|
; interrupts to make it obvious that things have halted.
|
|
|
|
; causing the check task to indicate the error.
|
|
|
|
CLRPSW I
|
|
|
|
|
|
|
|
BRA RegTest1Error
|
|
|
|
BRA RegTest1Error
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
@ -618,9 +630,8 @@ TestLoop2:
|
|
|
|
BRA TestLoop2
|
|
|
|
BRA TestLoop2
|
|
|
|
|
|
|
|
|
|
|
|
RegTest2Error:
|
|
|
|
RegTest2Error:
|
|
|
|
; A compare failed, something went wrong. Stop the tick and any other
|
|
|
|
; A compare failed, just loop here so the loop counter stops incrementing
|
|
|
|
; interrupts to make it obvious that things have halted.
|
|
|
|
; - causing the check task to indicate the error.
|
|
|
|
CLRPSW I
|
|
|
|
|
|
|
|
BRA RegTest2Error
|
|
|
|
BRA RegTest2Error
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|