From 99c1bc3dece5135cad780a0aeaecdc80ccfbf714 Mon Sep 17 00:00:00 2001 From: RichardBarry Date: Sun, 17 Jan 2010 15:45:37 +0000 Subject: [PATCH] Just updated comments. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@964 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../RTOSDemo/FreeRTOSConfig.h | 2 +- Demo/SuperH_SH7216_Renesas/RTOSDemo/flop.c | 93 ++++++--------- Demo/SuperH_SH7216_Renesas/RTOSDemo/main.c | 106 +++++++++++++++++- 3 files changed, 137 insertions(+), 64 deletions(-) diff --git a/Demo/SuperH_SH7216_Renesas/RTOSDemo/FreeRTOSConfig.h b/Demo/SuperH_SH7216_Renesas/RTOSDemo/FreeRTOSConfig.h index d6de0ff89..bebfcf62b 100644 --- a/Demo/SuperH_SH7216_Renesas/RTOSDemo/FreeRTOSConfig.h +++ b/Demo/SuperH_SH7216_Renesas/RTOSDemo/FreeRTOSConfig.h @@ -70,7 +70,7 @@ #define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 1 -#define configUSE_TICK_HOOK 1 +#define configUSE_TICK_HOOK 1 /* Must be set to one for the timer interrupt to be cleared. */ #define configCPU_CLOCK_HZ ( 200000000UL ) #define configPERIPHERAL_CLOCK_HZ ( 50000000UL ) #define configTICK_RATE_HZ ( ( portTickType ) 1000 ) diff --git a/Demo/SuperH_SH7216_Renesas/RTOSDemo/flop.c b/Demo/SuperH_SH7216_Renesas/RTOSDemo/flop.c index 6f0342e14..992e6f761 100644 --- a/Demo/SuperH_SH7216_Renesas/RTOSDemo/flop.c +++ b/Demo/SuperH_SH7216_Renesas/RTOSDemo/flop.c @@ -52,16 +52,19 @@ */ /* - * Creates eight tasks, each of which loops continuously performing an (emulated) - * floating point calculation. + * Creates eight tasks, each of which loops continuously performing a floating + * point calculation and in so doing test the floating point context switching. + * This file also demonstrates the use of the xPortUsesFloatingPoint() function + * which informs the kernel that the task requires its floating point context + * saved on each switch. * * All the tasks run at the idle priority and never block or yield. This causes - * all eight tasks to time slice with the idle task. Running at the idle priority - * means that these tasks will get pre-empted any time another task is ready to run - * or a time slice occurs. More often than not the pre-emption will occur mid - * calculation, creating a good test of the schedulers context switch mechanism - a - * calculation producing an unexpected result could be a symptom of a corruption in - * the context of a task. + * all eight tasks to time slice with the idle task. Running at the idle + * priority means that these tasks will get pre-empted any time another task is + * ready to run or a time slice occurs. More often than not the pre-emption + * will occur mid calculation, creating a good test of the schedulers context + * switch mechanism - a calculation producing an unexpected result could be a + * symptom of a corruption in the context of a task. */ #include @@ -79,14 +82,15 @@ /* Four tasks, each of which performs a different floating point calculation. Each of the four is created twice. */ -static portTASK_FUNCTION_PROTO( vCompetingMathTask1, pvParameters ); -static portTASK_FUNCTION_PROTO( vCompetingMathTask2, pvParameters ); -static portTASK_FUNCTION_PROTO( vCompetingMathTask3, pvParameters ); -static portTASK_FUNCTION_PROTO( vCompetingMathTask4, pvParameters ); +static void vCompetingMathTask1( void *pvParameters ); +static void vCompetingMathTask2( void *pvParameters ); +static void vCompetingMathTask3( void *pvParameters ); +static void vCompetingMathTask4( void *pvParameters ); /* These variables are used to check that all the tasks are still running. If a -task gets a calculation wrong it will -stop incrementing its check variable. */ +task gets a calculation wrong it will stop incrementing its check variable, +otherwise the check variable will get incremented on each iteration of the +tasks execution. */ static volatile unsigned short usTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 }; /*-----------------------------------------------------------*/ @@ -125,7 +129,7 @@ xTaskHandle xCreatedTask; } /*-----------------------------------------------------------*/ -static portTASK_FUNCTION( vCompetingMathTask1, pvParameters ) +static void vCompetingMathTask1( void *pvParameters ) { volatile double d1, d2, d3, d4; volatile unsigned short *pusTaskCheckVariable; @@ -136,6 +140,7 @@ short sError = pdFALSE; d2 = 2345.6789; d3 = -918.222; + /* Calculate the expected answer. */ dAnswer = ( d1 + d2 ) * d3; /* The variable this task increments to show it is still running is passed in @@ -145,16 +150,13 @@ short sError = pdFALSE; /* Keep performing a calculation and checking the result against a constant. */ for(;;) { + /* Perform the calculation. */ d1 = 123.4567; d2 = 2345.6789; d3 = -918.222; d4 = ( d1 + d2 ) * d3; - #if configUSE_PREEMPTION == 0 - taskYIELD(); - #endif - /* If the calculation does not match the expected constant, stop the increment of the check variable. */ if( fabs( d4 - dAnswer ) > 0.001 ) @@ -168,16 +170,11 @@ short sError = pdFALSE; variable so we know this task is still running okay. */ ( *pusTaskCheckVariable )++; } - - #if configUSE_PREEMPTION == 0 - taskYIELD(); - #endif - } } /*-----------------------------------------------------------*/ -static portTASK_FUNCTION( vCompetingMathTask2, pvParameters ) +static void vCompetingMathTask2( void *pvParameters ) { volatile double d1, d2, d3, d4; volatile unsigned short *pusTaskCheckVariable; @@ -188,6 +185,7 @@ short sError = pdFALSE; d2 = 32498.2; d3 = -2.0001; + /* Calculate the expected answer. */ dAnswer = ( d1 / d2 ) * d3; @@ -198,16 +196,13 @@ short sError = pdFALSE; /* Keep performing a calculation and checking the result against a constant. */ for( ;; ) { + /* Perform the calculation. */ d1 = -389.38; d2 = 32498.2; d3 = -2.0001; d4 = ( d1 / d2 ) * d3; - #if configUSE_PREEMPTION == 0 - taskYIELD(); - #endif - /* If the calculation does not match the expected constant, stop the increment of the check variable. */ if( fabs( d4 - dAnswer ) > 0.001 ) @@ -222,15 +217,11 @@ short sError = pdFALSE; this task is still running okay. */ ( *pusTaskCheckVariable )++; } - - #if configUSE_PREEMPTION == 0 - taskYIELD(); - #endif } } /*-----------------------------------------------------------*/ -static portTASK_FUNCTION( vCompetingMathTask3, pvParameters ) +static void vCompetingMathTask3( void *pvParameters ) { volatile double *pdArray, dTotal1, dTotal2, dDifference; volatile unsigned short *pusTaskCheckVariable; @@ -238,15 +229,16 @@ const size_t xArraySize = 10; size_t xPosition; short sError = pdFALSE; - /* The variable this task increments to show it is still running is passed in - as the parameter. */ + /* The variable this task increments to show it is still running is passed + in as the parameter. */ pusTaskCheckVariable = ( unsigned short * ) pvParameters; + /* Allocate memory for use as an array. */ pdArray = ( double * ) pvPortMalloc( xArraySize * sizeof( double ) ); - /* Keep filling an array, keeping a running total of the values placed in the - array. Then run through the array adding up all the values. If the two totals - do not match, stop the check variable from incrementing. */ + /* Keep filling an array, keeping a running total of the values placed in + the array. Then run through the array adding up all the values. If the two + totals do not match, stop the check variable from incrementing. */ for( ;; ) { dTotal1 = 0.0; @@ -258,10 +250,6 @@ short sError = pdFALSE; dTotal1 += ( double ) xPosition + 5.5; } - #if configUSE_PREEMPTION == 0 - taskYIELD(); - #endif - for( xPosition = 0; xPosition < xArraySize; xPosition++ ) { dTotal2 += pdArray[ xPosition ]; @@ -273,10 +261,6 @@ short sError = pdFALSE; sError = pdTRUE; } - #if configUSE_PREEMPTION == 0 - taskYIELD(); - #endif - if( sError == pdFALSE ) { /* If the calculation has always been correct, increment the check @@ -287,7 +271,7 @@ short sError = pdFALSE; } /*-----------------------------------------------------------*/ -static portTASK_FUNCTION( vCompetingMathTask4, pvParameters ) +static void vCompetingMathTask4( void *pvParameters ) { volatile double *pdArray, dTotal1, dTotal2, dDifference; volatile unsigned short *pusTaskCheckVariable; @@ -299,6 +283,7 @@ short sError = pdFALSE; as the parameter. */ pusTaskCheckVariable = ( unsigned short * ) pvParameters; + /* Allocate RAM for use as an array. */ pdArray = ( double * ) pvPortMalloc( xArraySize * sizeof( double ) ); /* Keep filling an array, keeping a running total of the values placed in the @@ -315,10 +300,6 @@ short sError = pdFALSE; dTotal1 += ( double ) xPosition * 12.123; } - #if configUSE_PREEMPTION == 0 - taskYIELD(); - #endif - for( xPosition = 0; xPosition < xArraySize; xPosition++ ) { dTotal2 += pdArray[ xPosition ]; @@ -330,10 +311,6 @@ short sError = pdFALSE; sError = pdTRUE; } - #if configUSE_PREEMPTION == 0 - taskYIELD(); - #endif - if( sError == pdFALSE ) { /* If the calculation has always been correct, increment the check @@ -347,8 +324,8 @@ short sError = pdFALSE; /* This is called to check that all the created tasks are still running. */ portBASE_TYPE xAreMathsTaskStillRunning( void ) { -/* Keep a history of the check variables so we know if they have been incremented -since the last call. */ +/* Keep a history of the check variables so we know if they have been +incremented since the last call. */ static unsigned short usLastTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 }; portBASE_TYPE xReturn = pdTRUE, xTask; diff --git a/Demo/SuperH_SH7216_Renesas/RTOSDemo/main.c b/Demo/SuperH_SH7216_Renesas/RTOSDemo/main.c index 9d6f718e7..25105274f 100644 --- a/Demo/SuperH_SH7216_Renesas/RTOSDemo/main.c +++ b/Demo/SuperH_SH7216_Renesas/RTOSDemo/main.c @@ -51,6 +51,57 @@ licensing and training services. */ + + +/* + * Creates all the demo application tasks, then starts the scheduler. The WEB + * documentation provides more details of the standard demo application tasks, + * which provide no particular functionality but do provide a good example of + * how to use the FreeRTOS API. In addition to the standard demo tasks, the + * following tasks and tests are defined and/or created within this file: + * + * "Reg test" tasks - These fill the registers with known values, then check + * that each register still contains its expected value. Each task uses + * different values. The tasks run with very low priority so get preempted very + * frequently. A register containing an unexpected value is indicative of an + * error in the context switching mechanism. Both standard and floating point + * registers are checked. The nature of the reg test tasks necessitates that + * they are written in assembly code. They are defined in regtest.src. + * + * "math" tasks - These are a set of 8 tasks that perform various double + * precision floating point calculations in order to check that the tasks + * floating point registers are being correctly saved and restored during + * context switches. The math tasks are defined in flop.c. + * + * "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 + * standard demo tasks are still operational. While no errors have been + * discovered the check task will toggle an LED every 5 seconds - the toggle + * rate increasing to 500ms being a visual indication that at least one task has + * reported unexpected behaviour. + * + * *NOTE 1* If LED5 is toggling every 5 seconds then all the demo application + * tasks are executing as expected and no errors have been reported in any + * tasks. The toggle rate increasing to 200ms indicates that at least one task + * has reported unexpected behaviour. + * + * *NOTE 2* This file and flop.c both demonstrate the use of + * xPortUsesFloatingPoint() which informs the kernel that a task should maintain + * a floating point context. + * + * *NOTE 3* vApplicationSetupTimerInterrupt() is called by the kernel to let + * the application set up a timer to generate the tick interrupt. In this + * example a compare match timer is used for this purpose. + * vApplicationTickHook() is used to clear the timer interrupt and relies on + * configUSE_TICK_HOOK being set to 1 in FreeRTOSConfig.h. + * + * *NOTE 4* The traceTASK_SWITCHED_IN and traceTASK_SWITCHED_OUT trace hooks + * are used to save and restore the floating point context respectively for + * those tasks that require it (those for which xPortUsesFloatingPoint() has + * been called). + * + */ + /* Kernel includes. */ #include "FreeRTOS.h" #include "task.h" @@ -94,18 +145,58 @@ without error. */ by at least one task. */ #define mainERROR_CYCLE_TIME ( 200 / portTICK_RATE_MS ) +/* + * vApplicationMallocFailedHook() will only be called if + * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook + * function that will execute if a call to pvPortMalloc() fails. + * pvPortMalloc() is called internally by the kernel whenever a task, queue or + * semaphore is created. It is also called by various parts of the demo + * application. + */ void vApplicationMallocFailedHook( void ); + +/* + * vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set to 1 + * in FreeRTOSConfig.h. It is a hook function that is called on each iteration + * of the idle task. It is essential that code added to this hook function + * never attempts to block in any way (for example, call xQueueReceive() with + * a block time specified). If the application makes use of the vTaskDelete() + * API function (as this demo application does) then it is also important that + * vApplicationIdleHook() is permitted to return to its calling function because + * it is the responsibility of the idle task to clean up memory allocated by the + * kernel to any task that has since been deleted. + */ void vApplicationIdleHook( void ); + +/* + * Just sets up clocks, ports, etc. used by the demo application. + */ static void prvSetupHardware( void ); + +/* + * The check task as described at the top of this file. + */ static void prvCheckTask( void *pvParameters ); +/* + * The reg test tasks as described at the top of this file. + */ extern void vRegTest1Task( void *pvParameters ); extern void vRegTest2Task( void *pvParameters ); +/*-----------------------------------------------------------*/ + +/* Variables that are incremented on each iteration of the reg test tasks - +provided the tasks have not reported any errors. The check task inspects these +variables to ensure they are still incrementing as expected. */ volatile unsigned long ulRegTest1CycleCount = 0UL, ulRegTest2CycleCount = 0UL; /*-----------------------------------------------------------*/ +/* + * Creates the majority of the demo application tasks before starting the + * scheduler. + */ void main(void) { xTaskHandle xCreatedTask; @@ -113,10 +204,10 @@ xTaskHandle xCreatedTask; prvSetupHardware(); /* Start the reg test tasks which test the context switching mechanism. */ - xTaskCreate( vRegTest1Task, "RegTest1", configMINIMAL_STACK_SIZE, ( void * ) 0x12345678UL, tskIDLE_PRIORITY, &xCreatedTask ); + xTaskCreate( vRegTest1Task, "RegTest1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, &xCreatedTask ); xPortUsesFloatingPoint( xCreatedTask ); - xTaskCreate( vRegTest2Task, "RegTest2", configMINIMAL_STACK_SIZE, ( void * ) 0x11223344UL, tskIDLE_PRIORITY, &xCreatedTask ); + xTaskCreate( vRegTest2Task, "RegTest2", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, &xCreatedTask ); xPortUsesFloatingPoint( xCreatedTask ); /* Start the check task as described at the top of this file. */ @@ -133,6 +224,8 @@ xTaskHandle xCreatedTask; vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY ); vStartQueuePeekTasks(); vStartRecursiveMutexTasks(); + + /* Start the math tasks as described at the top of this file. */ vStartMathTasks( mainFLOP_TASK_PRIORITY ); /* The suicide tasks must be created last as they need to know how many @@ -165,7 +258,7 @@ unsigned long ulLastRegTest1CycleCount = 0UL, ulLastRegTest2CycleCount = 0UL; /* Place this task in the blocked state until it is time to run again. */ vTaskDelayUntil( &xNextWakeTime, xCycleFrequency ); - /* Inspect all the other tasks to esnure none have experienced any errors. */ + /* Inspect all the other tasks to ensure none have experienced any errors. */ if( xAreGenericQueueTasksStillRunning() != pdTRUE ) { /* Increase the rate at which this task cycles, which will increase the @@ -253,7 +346,10 @@ void vApplicationIdleHook( void ) void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ) { - /* Just to remove compiler warnings. */ + /* Just to remove compiler warnings. This function will only actually + get called if configCHECK_FOR_STACK_OVERFLOW is set to a non zero value. + By default this demo does not use the stack overflow checking functionality + as the SuperH will normally execute an exception if the stack overflows. */ ( void ) pxTask; ( void ) pcTaskName; @@ -282,7 +378,7 @@ volatile unsigned long ul; void vApplicationSetupTimerInterrupt( void ) { /* The peripheral clock is divided by 32 before feeding the compare match -periphersl (CMT). */ +peripheral (CMT). */ unsigned long ulCompareMatch = ( configPERIPHERAL_CLOCK_HZ / ( configTICK_RATE_HZ * 32 ) ) + 1; /* Configure a timer to create the RTOS tick interrupt. This example uses -- 2.39.2