mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-06-05 11:59:05 -04:00
Just updated comments.
This commit is contained in:
parent
8dd9c7dfd9
commit
73b49130c6
|
@ -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 )
|
||||
|
|
|
@ -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 <stdlib.h>
|
||||
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue