licensing and training services.\r
*/\r
\r
+\r
+/* _RB_ Add description here. */\r
+\r
+\r
/* Standard includes. */\r
#include <stdlib.h>\r
#include <string.h>\r
/*-----------------------------------------------------------*/\r
\r
/* Constants for the ComTest tasks. */\r
-#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 115200 )\r
-#define mainCOM_TEST_LED ( 5 )\r
+#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 115200 )\r
+#define mainCOM_TEST_LED ( 5 )\r
\r
/* Priorities for the demo application tasks. */\r
-#define mainLED_TASK_PRIORITY ( ( tskIDLE_PRIORITY + 1 ) | portPRIVILEGE_BIT )\r
-#define mainCOM_TEST_PRIORITY ( ( tskIDLE_PRIORITY + 2 ) | portPRIVILEGE_BIT )\r
+#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
+#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
-#define mainCHECK_TASK_PRIORITY ( ( tskIDLE_PRIORITY + 4 ) | portPRIVILEGE_BIT )\r
+#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 )\r
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
\r
#define mainNO_ERROR_FLASH_PERIOD ( ( portTickType ) 5000 / portTICK_RATE_MS )\r
#define mainERROR_FLASH_PERIOD ( ( portTickType ) 500 / portTICK_RATE_MS )\r
#define mainON_BOARD_LED_BIT ( ( unsigned long ) 7 )\r
-#define mainREG_TEST_TASKS 1\r
+\r
/*-----------------------------------------------------------*/\r
\r
/*\r
* prvCheckOtherTasksAreStillRunning(). See the description at the top\r
* of the file.\r
*/\r
-static void vErrorChecks( void *pvParameters );\r
-/*-----------------------------------------------------------*/\r
+static void prvCheckTask( void *pvParameters );\r
\r
/*\r
- * Configure the processor for use with the Olimex demo board. This includes\r
- * setup for the I/O, system clock, and access timings.\r
+ * Configure the processor ready to run this demo.\r
*/\r
static void prvSetupHardware( void );\r
\r
-/*\r
- * Function to create the heavily restricted RegTest tasks.\r
- */\r
-static void vStartRegTestTasks( unsigned portBASE_TYPE uxPriority );\r
-\r
-#if mainREG_TEST_TASKS == 1\r
-\r
/*\r
* Writes to and checks the value of each register that is used in the context\r
* of a task.\r
*/\r
-static void vRegTask1( void *pvParameters );\r
-static void vRegTask2( void *pvParameters );\r
+static void prvRegTask1( void *pvParameters );\r
+static void prvRegTask2( void *pvParameters );\r
\r
/*\r
- * Specific check to see if the Register test functions are still operating.\r
+ * Specific check to see if the Register test functions are still operating\r
+ * correctly.\r
*/\r
-static portBASE_TYPE xAreRegTestTasksStillRunning( void );\r
+static portBASE_TYPE prvAreRegTestTasksStillRunning( void );\r
\r
-#endif /* mainREG_TEST_TASKS */\r
/*-----------------------------------------------------------*/\r
\r
/* Used by the register test tasks to indicated liveness. */\r
static unsigned long ulRegisterTest1Count = 0;\r
static unsigned long ulRegisterTest2Count = 0;\r
+\r
/*-----------------------------------------------------------*/\r
\r
/*\r
- * Starts all the other tasks, then starts the scheduler.\r
+ * Starts all the tasks, then starts the scheduler.\r
*/\r
int main( void )\r
{\r
/* Setup the hardware for use with the TriCore evaluation board. */\r
prvSetupHardware();\r
\r
- /* Start the demo/test application tasks. */\r
+ /* Start standard demo/test application tasks. */\r
vStartIntegerMathTasks( tskIDLE_PRIORITY );\r
vStartLEDFlashTasks( mainLED_TASK_PRIORITY );\r
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );\r
vStartGenericQueueTasks( tskIDLE_PRIORITY );\r
vStartRecursiveMutexTasks();\r
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );\r
- vStartRegTestTasks( tskIDLE_PRIORITY );\r
+ /* _RB_ Create the timer test task here too. */\r
+\r
+ /* Create the register test tasks, as described at the top of this file. */\r
+ xTaskCreate( prvRegTask1, ( signed char * ) "Reg 1", configMINIMAL_STACK_SIZE, &ulRegisterTest1Count, tskIDLE_PRIORITY, NULL );\r
+ xTaskCreate( prvRegTask2, ( signed char * ) "Reg 2", configMINIMAL_STACK_SIZE, &ulRegisterTest2Count, tskIDLE_PRIORITY, NULL );\r
\r
/* Start the check task - which is defined in this file. */\r
- xTaskCreate( vErrorChecks, ( signed char * ) "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );\r
+ xTaskCreate( prvCheckTask, ( signed char * ) "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );\r
+\r
+ /* _RB_ start the death tasks here too. */\r
\r
/* Now all the tasks have been started - start the scheduler. */\r
vTaskStartScheduler();\r
\r
- /* Should never reach here! */\r
+ /* If all is well then the following line will never be reached. If\r
+ execution does reach here, then it is highly probably that the heap size\r
+ is too small for the idle and/or timer tasks to be created within\r
+ vTaskStartScheduler(). */\r
for( ;; );\r
}\r
/*-----------------------------------------------------------*/\r
\r
-static void vErrorChecks( void *pvParameters )\r
+static void prvCheckTask( void *pvParameters )\r
{\r
portTickType xDelayPeriod = mainNO_ERROR_FLASH_PERIOD;\r
+portTickType xLastExecutionTime;\r
\r
/* Just to stop compiler warnings. */\r
( void ) pvParameters;\r
\r
+ /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()\r
+ works correctly. */\r
+ xLastExecutionTime = xTaskGetTickCount();\r
+\r
/* Cycle for ever, delaying then checking all the other tasks are still\r
operating without error. If an error is detected then the delay period\r
is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so\r
- the on board LED flash rate will increase. */\r
+ the on board LED flash rate will increase. NOTE: This task could easily\r
+ be replaced by a software timer callback to remove the overhead of having\r
+ an extra task. */\r
\r
for( ;; )\r
{\r
/* Delay until it is time to execute again. */\r
- vTaskDelay( xDelayPeriod );\r
+ vTaskDelayUntil( &xLastExecutionTime, xDelayPeriod );\r
\r
/* Check all the standard demo application tasks are executing without\r
error. */\r
if( prvCheckOtherTasksAreStillRunning() != pdPASS )\r
{\r
- /* An error has been detected in one of the tasks - flash faster. */\r
+ /* An error has been detected in one of the tasks - flash the LED\r
+ at a higher frequency to give visible feedback that something has\r
+ gone wrong (it might just be that the loop back connector required\r
+ by the comtest tasks has not been fitted). */\r
xDelayPeriod = mainERROR_FLASH_PERIOD;\r
}\r
\r
long lReturn = pdPASS;\r
\r
/* Check all the demo tasks (other than the flash tasks) to ensure\r
- that they are all still running, and that none of them have detected\r
- an error. */\r
+ that they are all still running, and that none have detected an error. */\r
\r
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )\r
{\r
lReturn = pdFAIL;\r
}\r
\r
- if( xAreRegTestTasksStillRunning() != pdTRUE )\r
+ if( prvAreRegTestTasksStillRunning() != pdTRUE )\r
{\r
lReturn = pdFAIL;\r
}\r
\r
void vApplicationMallocFailedHook( void )\r
{\r
- /* This function will be called if a call to pvPortMalloc() fails to return\r
- the requested memory. pvPortMalloc() is called internally by the scheduler\r
- whenever a task, queue or semaphore is created. */\r
+ /* vApplicationMallocFailedHook() will only be called if\r
+ configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook\r
+ function that will get called if a call to pvPortMalloc() fails.\r
+ pvPortMalloc() is called internally by the kernel whenever a task, queue,\r
+ timer or semaphore is created. It is also called by various parts of the\r
+ demo application. If heap_1.c or heap_2.c are used, then the size of the\r
+ heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in\r
+ FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used\r
+ to query the size of free heap space that remains (although it does not\r
+ provide information on how the remaining heap might be fragmented). */\r
_debug();\r
+ taskDISABLE_INTERRUPTS();\r
for( ;; );\r
}\r
/*-----------------------------------------------------------*/\r
\r
void vApplicationTickHook( void )\r
{\r
- /*\r
- * This function will be called whenever the system tick is incremented.\r
- * Note that it is executed as part of an interrupt and as such should\r
- * not block nor be used for any long running execution.\r
- */\r
- vParTestToggleLED( mainON_BOARD_LED_BIT - 1 );\r
+ /* vApplicationTickHook() will only be called if configUSE_TICK_HOOK is set\r
+ to 1 in FreeRTOSConfig.h. It is a hook function that will get called during\r
+ each FreeRTOS tick interrupt. Note that vApplicationTickHook() is called\r
+ from an interrupt context. */\r
}\r
/*-----------------------------------------------------------*/\r
\r
void vApplicationIdleHook( void )\r
{\r
- /*\r
- * This function will be called during the normal execution of the IDLE task.\r
- */\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-#if mainREG_TEST_TASKS == 1\r
-\r
-static void vStartRegTestTasks( unsigned portBASE_TYPE uxPriority )\r
-{\r
- (void)xTaskCreate( vRegTask1, ( signed char * ) "Reg 1", configMINIMAL_STACK_SIZE, &ulRegisterTest1Count, uxPriority, NULL );\r
- (void)xTaskCreate( vRegTask2, ( signed char * ) "Reg 2", configMINIMAL_STACK_SIZE, &ulRegisterTest2Count, uxPriority, NULL );\r
+ /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set\r
+ to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle\r
+ task. It is essential that code added to this hook function never attempts\r
+ to block in any way (for example, call xQueueReceive() with a block time\r
+ specified, or call vTaskDelay()). If the application makes use of the\r
+ vTaskDelete() API function (as this demo application does) then it is also\r
+ important that vApplicationIdleHook() is permitted to return to its calling\r
+ function, because it is the responsibility of the idle task to clean up\r
+ memory allocated by the kernel to any task that has since been deleted. */\r
}\r
/*-----------------------------------------------------------*/\r
\r
-portBASE_TYPE xAreRegTestTasksStillRunning( void )\r
+static portBASE_TYPE prvAreRegTestTasksStillRunning( void )\r
{\r
static unsigned long ulPreviousRegisterTest1Count = 0;\r
static unsigned long ulPreviousRegisterTest2Count = 0;\r
-portBASE_TYPE xReturn = pdFALSE;\r
+portBASE_TYPE xReturn = pdPASS;\r
\r
/* Check to see if the Counts have changed since the last check. */\r
- xReturn = ( ulPreviousRegisterTest1Count != ulRegisterTest1Count );\r
- xReturn = xReturn && ( ulPreviousRegisterTest2Count != ulRegisterTest2Count );\r
+ if( ulRegisterTest1Count == ulPreviousRegisterTest1Count )\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
\r
- /* Record the last count. */\r
+ if( ulRegisterTest2Count == ulPreviousRegisterTest2Count )\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
+\r
+ /* Remember the current count for the next time this function is called. */\r
ulPreviousRegisterTest1Count = ulRegisterTest1Count;\r
ulPreviousRegisterTest2Count = ulRegisterTest2Count;\r
\r
}\r
/*-----------------------------------------------------------*/\r
\r
-/*\r
- * Set all of the registers that are used as part of the task context\r
- * to known values and test that those values are maintained across\r
- * context switches.\r
- */\r
-void vRegTask1( void *pvParameters )\r
+static void prvRegTask1( void *pvParameters )\r
{\r
/* Make space on the stack for the parameter and a counter. */\r
__asm volatile( " sub.a %sp, 4 \n"\r
" mov %d15, 0 \n"\r
" st.w [%sp]4, %d15 \n" );\r
\r
- for (;;)\r
- {\r
- /* Change all of the Context sensitive registers (except SP and RA). */\r
- __asm volatile(\r
- " mov %d0, 0 \n"\r
- " mov %d1, 1 \n"\r
- " mov %d2, 2 \n"\r
- " mov %d3, 3 \n"\r
- " mov %d4, 4 \n"\r
- " mov %d5, 5 \n"\r
- " mov %d6, 6 \n"\r
- " mov %d7, 7 \n"\r
- " mov %d8, 8 \n"\r
- " mov %d9, 9 \n"\r
- " mov %d10, 10 \n"\r
- " mov %d11, 11 \n"\r
- " mov %d12, 12 \n"\r
- " mov %d13, 13 \n"\r
- " mov %d14, 14 \n"\r
- " mov %d15, 15 \n"\r
- " mov.a %a2, 2 \n"\r
- " mov.a %a3, 3 \n"\r
- " mov.a %a4, 4 \n"\r
- " mov.a %a5, 5 \n"\r
- " mov.a %a6, 6 \n"\r
- " mov.a %a7, 7 \n"\r
- " mov.a %a12, 12 \n"\r
- " mov.a %a13, 13 \n"\r
- " mov.a %a14, 14 \n" );\r
- /* Yield to force a context switch. */\r
- taskYIELD();\r
- /* Check the values of the registers. */\r
- __asm( " eq %d0, %d0, 0 \n" \\r
- " jne %d0, 1, _task1_loop \n" \\r
- " eq %d1, %d1, 1 \n" \\r
- " jne %d1, 1, _task1_loop \n" \\r
- " eq %d2, %d2, 2 \n" \\r
- " jne %d2, 1, _task1_loop \n" \\r
- " eq %d3, %d3, 3 \n" \\r
- " jne %d3, 1, _task1_loop \n" \\r
- " eq %d4, %d4, 4 \n" \\r
- " jne %d4, 1, _task1_loop \n" \\r
- " eq %d5, %d5, 5 \n" \\r
- " jne %d5, 1, _task1_loop \n" \\r
- " eq %d6, %d6, 6 \n" \\r
- " jne %d6, 1, _task1_loop \n" \\r
- " eq %d7, %d7, 7 \n" \\r
- " jne %d7, 1, _task1_loop \n" \\r
- " eq %d8, %d8, 8 \n" \\r
- " jne %d8, 1, _task1_loop \n" \\r
- " eq %d9, %d9, 9 \n" \\r
- " jne %d9, 1, _task1_loop \n" \\r
- " eq %d10, %d10, 10 \n" \\r
- " jne %d10, 1, _task1_loop \n" \\r
- " eq %d11, %d11, 11 \n" \\r
- " jne %d11, 1, _task1_loop \n" \\r
- " eq %d12, %d12, 12 \n" \\r
- " jne %d12, 1, _task1_loop \n" \\r
- " eq %d13, %d13, 13 \n" \\r
- " jne %d13, 1, _task1_loop \n" \\r
- " eq %d14, %d14, 14 \n" \\r
- " jne %d14, 1, _task1_loop \n" \\r
- " eq %d15, %d15, 15 \n" \\r
- " jne %d15, 1, _task1_loop \n" \\r
- " mov.a %a15, 2 \n" \\r
- " jne.a %a15, %a2, _task1_loop \n" \\r
- " mov.a %a15, 3 \n" \\r
- " jne.a %a15, %a3, _task1_loop \n" \\r
- " mov.a %a15, 4 \n" \\r
- " jne.a %a15, %a4, _task1_loop \n" \\r
- " mov.a %a15, 5 \n" \\r
- " jne.a %a15, %a5, _task1_loop \n" \\r
- " mov.a %a15, 6 \n" \\r
- " jne.a %a15, %a6, _task1_loop \n" \\r
- " mov.a %a15, 7 \n" \\r
- " jne.a %a15, %a7, _task1_loop \n" \\r
- " mov.a %a15, 12 \n" \\r
- " jne.a %a15, %a12, _task1_loop \n" \\r
- " mov.a %a15, 13 \n" \\r
- " jne.a %a15, %a13, _task1_loop \n" \\r
- " mov.a %a15, 14 \n" \\r
- " jne.a %a15, %a14, _task1_loop \n" \\r
- " j _task1_skip \n" \\r
- "_task1_loop: \n" \\r
- " debug \n" \\r
- " j _task1_loop \n" \\r
- "_task1_skip: \n" );\r
-\r
- /* Load the parameter address from the stack and modify the value. */\r
- __asm volatile( \\r
- " ld.w %d15, [%sp]4 \n" \\r
- " add %d15, %d15, 1 \n" \\r
- " st.w [%sp]4, %d15 \n" \\r
- " ld.a %a4, [%sp] \n" \\r
- " st.w [%a4], %d15 \n" );\r
- }\r
+ /* Change all of the Context sensitive registers (except SP and RA). */\r
+ __asm volatile(\r
+ " mov %d0, 0 \n"\r
+ " mov %d1, 1 \n"\r
+ " mov %d2, 2 \n"\r
+ " mov %d3, 3 \n"\r
+ " mov %d4, 4 \n"\r
+ " mov %d5, 5 \n"\r
+ " mov %d6, 6 \n"\r
+ " mov %d7, 7 \n"\r
+ " mov %d8, 8 \n"\r
+ " mov %d9, 9 \n"\r
+ " mov %d10, 10 \n"\r
+ " mov %d11, 11 \n"\r
+ " mov %d12, 12 \n"\r
+ " mov %d13, 13 \n"\r
+ " mov %d14, 14 \n"\r
+ " mov %d15, 15 \n"\r
+ " mov.a %a2, 2 \n"\r
+ " mov.a %a3, 3 \n"\r
+ " mov.a %a4, 4 \n"\r
+ " mov.a %a5, 5 \n"\r
+ " mov.a %a6, 6 \n"\r
+ " mov.a %a7, 7 \n"\r
+ " mov.a %a12, 12 \n"\r
+ " mov.a %a13, 13 \n"\r
+ " mov.a %a14, 14 \n" );\r
+\r
+ /* Check the values of the registers. */\r
+ __asm( " _task1_loop: \n" \\r
+ " eq %d1, %d0, 0 \n" \\r
+ " jne %d1, 1, _task1_error_loop \n" \\r
+ " eq %d1, %d1, 1 \n" \\r
+ " jne %d1, 1, _task1_error_loop \n" \\r
+ " eq %d1, %d2, 2 \n" \\r
+ " jne %d1, 1, _task1_error_loop \n" \\r
+ " eq %d1, %d3, 3 \n" \\r
+ " jne %d1, 1, _task1_error_loop \n" \\r
+ " eq %d1, %d4, 4 \n" \\r
+ " jne %d1, 1, _task1_error_loop \n" \\r
+ " eq %d1, %d5, 5 \n" \\r
+ " jne %d1, 1, _task1_error_loop \n" \\r
+ " eq %d1, %d6, 6 \n" \\r
+ " jne %d1, 1, _task1_error_loop \n" \\r
+ " eq %d1, %d7, 7 \n" \\r
+ " jne %d1, 1, _task1_error_loop \n" \\r
+ " eq %d1, %d8, 8 \n" \\r
+ " jne %d1, 1, _task1_error_loop \n" \\r
+ " eq %d1, %d9, 9 \n" \\r
+ " jne %d1, 1, _task1_error_loop \n" \\r
+ " eq %d1, %d10, 10 \n" \\r
+ " jne %d1, 1, _task1_error_loop \n" \\r
+ " eq %d1, %d11, 11 \n" \\r
+ " jne %d1, 1, _task1_error_loop \n" \\r
+ " eq %d1, %d12, 12 \n" \\r
+ " jne %d1, 1, _task1_error_loop \n" \\r
+ " eq %d1, %d13, 13 \n" \\r
+ " jne %d1, 1, _task1_error_loop \n" \\r
+ " eq %d1, %d14, 14 \n" \\r
+ " jne %d1, 1, _task1_error_loop \n" \\r
+ " eq %d1, %d15, 15 \n" \\r
+ " jne %d1, 1, _task1_error_loop \n" \\r
+ " mov.a %a15, 2 \n" \\r
+ " jne.a %a15, %a2, _task1_error_loop \n" \\r
+ " mov.a %a15, 3 \n" \\r
+ " jne.a %a15, %a3, _task1_error_loop \n" \\r
+ " mov.a %a15, 4 \n" \\r
+ " jne.a %a15, %a4, _task1_error_loop \n" \\r
+ " mov.a %a15, 5 \n" \\r
+ " jne.a %a15, %a5, _task1_error_loop \n" \\r
+ " mov.a %a15, 6 \n" \\r
+ " jne.a %a15, %a6, _task1_error_loop \n" \\r
+ " mov.a %a15, 7 \n" \\r
+ " jne.a %a15, %a7, _task1_error_loop \n" \\r
+ " mov.a %a15, 12 \n" \\r
+ " jne.a %a15, %a12, _task1_error_loop \n" \\r
+ " mov.a %a15, 13 \n" \\r
+ " jne.a %a15, %a13, _task1_error_loop \n" \\r
+ " mov.a %a15, 14 \n" \\r
+ " jne.a %a15, %a14, _task1_error_loop \n" \\r
+ " j _task1_skip_error_loop \n" \\r
+ "_task1_error_loop: \n" /* Hitting this error loop will stop the counter incrementing, allowing the check task to recognise an error. */ \\r
+ " debug \n" \\r
+ " j _task1_error_loop \n" \\r
+ "_task1_skip_error_loop: \n" );\r
+\r
+ /* Load the parameter address from the stack and modify the value. */\r
+ __asm volatile( \\r
+ " ld.w %d1, [%sp]4 \n" \\r
+ " add %d1, %d15, 1 \n" \\r
+ " st.w [%sp]4, %d1 \n" \\r
+ " ld.a %a15, [%sp] \n" \\r
+ " st.w [%a15], %d1 \n" \\r
+ " j _task1_loop \n" );\r
\r
/* The parameter is used but in the assembly. */\r
(void)pvParameters;\r
}\r
/*-----------------------------------------------------------*/\r
\r
-/*\r
- * Set all of the registers that are used as part of the task context\r
- * to known values and test that those values are maintained across\r
- * context switches.\r
- */\r
-void vRegTask2( void *pvParameters )\r
+static void prvRegTask2( void *pvParameters )\r
{\r
/* Make space on the stack for the parameter and a counter. */\r
__asm volatile( " sub.a %sp, 4 \n" \\r
" mov %d15, 0 \n" \\r
" st.w [%sp]4, %d15 \n" );\r
\r
- for (;;)\r
- {\r
- /* Change all of the Context sensitive registers (except SP and RA). */\r
- __asm( " mov %d0, 7 \n" \\r
- " mov %d1, 6 \n" \\r
- " mov %d2, 5 \n" \\r
- " mov %d3, 4 \n" \\r
- " mov %d4, 3 \n" \\r
- " mov %d5, 2 \n" \\r
- " mov %d6, 1 \n" \\r
- " mov %d7, 0 \n" \\r
- " mov %d8, 15 \n" \\r
- " mov %d9, 14 \n" \\r
- " mov %d10, 13 \n" \\r
- " mov %d11, 12 \n" \\r
- " mov %d12, 11 \n" \\r
- " mov %d13, 10 \n" \\r
- " mov %d14, 9 \n" \\r
- " mov %d15, 8 \n" \\r
- " mov.a %a2, 14 \n" \\r
- " mov.a %a3, 13 \n" \\r
- " mov.a %a4, 12 \n" \\r
- " mov.a %a5, 7 \n" \\r
- " mov.a %a6, 6 \n" \\r
- " mov.a %a7, 5 \n" \\r
- " mov.a %a12, 4 \n" \\r
- " mov.a %a13, 3 \n" \\r
- " mov.a %a14, 2 \n" );\r
- /* Yield to force a context switch. */\r
- taskYIELD();\r
- /* Check the values of the registers. */\r
- __asm( " eq %d0, %d0, 7 \n" \\r
- " jne %d0, 1, _task2_loop \n" \\r
- " eq %d1, %d1, 6 \n" \\r
- " jne %d1, 1, _task2_loop \n" \\r
- " eq %d2, %d2, 5 \n" \\r
- " jne %d2, 1, _task2_loop \n" \\r
- " eq %d3, %d3, 4 \n" \\r
- " jne %d3, 1, _task2_loop \n" \\r
- " eq %d4, %d4, 3 \n" \\r
- " jne %d4, 1, _task2_loop \n" \\r
- " eq %d5, %d5, 2 \n" \\r
- " jne %d5, 1, _task2_loop \n" \\r
- " eq %d6, %d6, 1 \n" \\r
- " jne %d6, 1, _task2_loop \n" \\r
- " eq %d7, %d7, 0 \n" \\r
- " jne %d7, 1, _task2_loop \n" \\r
- " eq %d8, %d8, 15 \n" \\r
- " jne %d8, 1, _task2_loop \n" \\r
- " eq %d9, %d9, 14 \n" \\r
- " jne %d9, 1, _task2_loop \n" \\r
- " eq %d10, %d10, 13 \n" \\r
- " jne %d10, 1, _task2_loop \n" \\r
- " eq %d11, %d11, 12 \n" \\r
- " jne %d11, 1, _task2_loop \n" \\r
- " eq %d12, %d12, 11 \n" \\r
- " jne %d12, 1, _task2_loop \n" \\r
- " eq %d13, %d13, 10 \n" \\r
- " jne %d13, 1, _task2_loop \n" \\r
- " eq %d14, %d14, 9 \n" \\r
- " jne %d14, 1, _task2_loop \n" \\r
- " eq %d15, %d15, 8 \n" \\r
- " jne %d15, 1, _task2_loop \n" \\r
- " mov.a %a15, 14 \n" \\r
- " jne.a %a15, %a2, _task2_loop \n" \\r
- " mov.a %a15, 13 \n" \\r
- " jne.a %a15, %a3, _task2_loop \n" \\r
- " mov.a %a15, 12 \n" \\r
- " jne.a %a15, %a4, _task2_loop \n" \\r
- " mov.a %a15, 7 \n" \\r
- " jne.a %a15, %a5, _task2_loop \n" \\r
- " mov.a %a15, 6 \n" \\r
- " jne.a %a15, %a6, _task2_loop \n" \\r
- " mov.a %a15, 5 \n" \\r
- " jne.a %a15, %a7, _task2_loop \n" \\r
- " mov.a %a15, 4 \n" \\r
- " jne.a %a15, %a12, _task2_loop \n" \\r
- " mov.a %a15, 3 \n" \\r
- " jne.a %a15, %a13, _task2_loop \n" \\r
- " mov.a %a15, 2 \n" \\r
- " jne.a %a15, %a14, _task2_loop \n" \\r
- " j _task2_skip \n" \\r
- "_task2_loop: \n" \\r
- " j _task2_loop \n" \\r
- "_task2_skip: \n" );\r
-\r
- /* Load the parameter address from the stack and modify the value. */\r
- __asm volatile( \\r
- " ld.w %d15, [%sp]4 \n" \\r
- " add %d15, %d15, 1 \n" \\r
- " st.w [%sp]4, %d15 \n" \\r
- " ld.a %a4, [%sp] \n" \\r
- " st.w [%a4], %d15 \n" );\r
- }\r
+ /* Change all of the Context sensitive registers (except SP and RA). */\r
+ __asm volatile( " mov %d0, 7 \n" \\r
+ " mov %d1, 1 \n" \\r
+ " mov %d2, 5 \n" \\r
+ " mov %d3, 4 \n" \\r
+ " mov %d4, 3 \n" \\r
+ " mov %d5, 2 \n" \\r
+ " mov %d6, 1 \n" \\r
+ " mov %d7, 0 \n" \\r
+ " mov %d8, 15 \n" \\r
+ " mov %d9, 14 \n" \\r
+ " mov %d10, 13 \n" \\r
+ " mov %d11, 12 \n" \\r
+ " mov %d12, 11 \n" \\r
+ " mov %d13, 10 \n" \\r
+ " mov %d14, 9 \n" \\r
+ " mov %d15, 8 \n" \\r
+ " mov.a %a2, 14 \n" \\r
+ " mov.a %a3, 13 \n" \\r
+ " mov.a %a4, 12 \n" \\r
+ " mov.a %a5, 7 \n" \\r
+ " mov.a %a6, 6 \n" \\r
+ " mov.a %a7, 5 \n" \\r
+ " mov.a %a12, 4 \n" \\r
+ " mov.a %a13, 3 \n" \\r
+ " mov.a %a14, 2 \n" );\r
+ /* Yield to force a context switch. */\r
+ taskYIELD();\r
+\r
+ /* Check the values of the registers. */\r
+ __asm volatile( " _task2_loop: \n" \\r
+ " eq %d1, %d0, 7 \n" \\r
+ " jne %d1, 1, _task2_error_loop \n" \\r
+ " eq %d1, %d1, 1 \n" \\r
+ " jne %d1, 1, _task2_error_loop \n" \\r
+ " eq %d1, %d2, 5 \n" \\r
+ " jne %d1, 1, _task2_error_loop \n" \\r
+ " eq %d1, %d3, 4 \n" \\r
+ " jne %d1, 1, _task2_error_loop \n" \\r
+ " eq %d1, %d4, 3 \n" \\r
+ " jne %d1, 1, _task2_error_loop \n" \\r
+ " eq %d1, %d5, 2 \n" \\r
+ " jne %d1, 1, _task2_error_loop \n" \\r
+ " eq %d1, %d6, 1 \n" \\r
+ " jne %d1, 1, _task2_error_loop \n" \\r
+ " eq %d1, %d7, 0 \n" \\r
+ " jne %d1, 1, _task2_error_loop \n" \\r
+ " eq %d1, %d8, 15 \n" \\r
+ " jne %d1, 1, _task2_error_loop \n" \\r
+ " eq %d1, %d9, 14 \n" \\r
+ " jne %d1, 1, _task2_error_loop \n" \\r
+ " eq %d1, %d10, 13 \n" \\r
+ " jne %d1, 1, _task2_error_loop \n" \\r
+ " eq %d1, %d11, 12 \n" \\r
+ " jne %d1, 1, _task2_error_loop \n" \\r
+ " eq %d1, %d12, 11 \n" \\r
+ " jne %d1, 1, _task2_error_loop \n" \\r
+ " eq %d1, %d13, 10 \n" \\r
+ " jne %d1, 1, _task2_error_loop \n" \\r
+ " eq %d1, %d14, 9 \n" \\r
+ " jne %d1, 1, _task2_error_loop \n" \\r
+ " eq %d1, %d15, 8 \n" \\r
+ " jne %d1, 1, _task2_error_loop \n" \\r
+ " mov.a %a15, 14 \n" \\r
+ " jne.a %a15, %a2, _task2_error_loop \n" \\r
+ " mov.a %a15, 13 \n" \\r
+ " jne.a %a15, %a3, _task2_error_loop \n" \\r
+ " mov.a %a15, 12 \n" \\r
+ " jne.a %a15, %a4, _task2_error_loop \n" \\r
+ " mov.a %a15, 7 \n" \\r
+ " jne.a %a15, %a5, _task2_error_loop \n" \\r
+ " mov.a %a15, 6 \n" \\r
+ " jne.a %a15, %a6, _task2_error_loop \n" \\r
+ " mov.a %a15, 5 \n" \\r
+ " jne.a %a15, %a7, _task2_error_loop \n" \\r
+ " mov.a %a15, 4 \n" \\r
+ " jne.a %a15, %a12, _task2_error_loop \n" \\r
+ " mov.a %a15, 3 \n" \\r
+ " jne.a %a15, %a13, _task2_error_loop \n" \\r
+ " mov.a %a15, 2 \n" \\r
+ " jne.a %a15, %a14, _task2_error_loop \n" \\r
+ " j _task2_skip_error_loop \n" \\r
+ "_task2_error_loop: \n" /* Hitting this error loop will stop the counter incrementing, allowing the check task to recognise an error. */ \\r
+ " j _task2_error_loop \n" \\r
+ "_task2_skip_error_loop: \n" );\r
+\r
+ /* Load the parameter address from the stack and modify the value. */\r
+ __asm volatile( " ld.w %d1, [%sp]4 \n" \\r
+ " add %d1, %d1, 1 \n" \\r
+ " st.w [%sp]4, %d1 \n" \\r
+ " ld.a %a15, [%sp] \n" \\r
+ " st.w [%a15], %d1 \n" \\r
+ " j _task2_loop \n" );\r
\r
/* The parameter is used but in the assembly. */\r
(void)pvParameters;\r
}\r
/*-----------------------------------------------------------*/\r
-#endif /* mainREG_TEST_TASKS */\r
+\r