You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
192 lines
6.7 KiB
C
192 lines
6.7 KiB
C
/*
|
|
FreeRTOS V4.0.1 - Copyright (C) 2003-2006 Richard Barry.
|
|
|
|
This file is part of the FreeRTOS distribution.
|
|
|
|
FreeRTOS is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
FreeRTOS is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with FreeRTOS; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
A special exception to the GPL can be applied should you wish to distribute
|
|
a combined work that includes FreeRTOS, without being obliged to provide
|
|
the source code for any proprietary components. See the licensing section
|
|
of http://www.FreeRTOS.org for full details of how and when the exception
|
|
can be applied.
|
|
|
|
***************************************************************************
|
|
See http://www.FreeRTOS.org for documentation, latest information, license
|
|
and contact details. Please ensure to read the configuration and relevant
|
|
port sections of the online documentation.
|
|
***************************************************************************
|
|
*/
|
|
|
|
/*
|
|
* This version of integer. c is for use on systems that have limited stack
|
|
* space and no display facilities. The complete version can be found in
|
|
* the Demo/Common/Full directory.
|
|
*
|
|
* As with the full version, the tasks created in this file are a good test
|
|
* of the scheduler context switch mechanism. The processor has to access
|
|
* 32bit variables in two or four chunks (depending on the processor). The low
|
|
* priority of these tasks means there is a high probability that a context
|
|
* switch will occur mid calculation. See flop. c documentation for
|
|
* more information.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
Changes from V1.2.1
|
|
|
|
+ The constants used in the calculations are larger to ensure the
|
|
optimiser does not truncate them to 16 bits.
|
|
|
|
Changes from V1.2.3
|
|
|
|
+ uxTaskCheck is now just used as a boolean. Instead of incrementing
|
|
the variable each cycle of the task, the variable is simply set to
|
|
true. sAreIntegerMathsTaskStillRunning() sets it back to false and
|
|
expects it to have been set back to true by the time it is called
|
|
again.
|
|
+ A division has been included in the calculation.
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
|
|
/* Scheduler include files. */
|
|
#include "FreeRTOS.h"
|
|
#include "task.h"
|
|
|
|
/* Demo program include files. */
|
|
#include "integer.h"
|
|
|
|
/* The constants used in the calculation. */
|
|
#define intgCONST1 ( ( portLONG ) 123 )
|
|
#define intgCONST2 ( ( portLONG ) 234567 )
|
|
#define intgCONST3 ( ( portLONG ) -3 )
|
|
#define intgCONST4 ( ( portLONG ) 7 )
|
|
#define intgEXPECTED_ANSWER ( ( ( intgCONST1 + intgCONST2 ) * intgCONST3 ) / intgCONST4 )
|
|
|
|
#define intgSTACK_SIZE configMINIMAL_STACK_SIZE
|
|
|
|
/* As this is the minimal version, we will only create one task. */
|
|
#define intgNUMBER_OF_TASKS ( 1 )
|
|
|
|
/* The task function. Repeatedly performs a 32 bit calculation, checking the
|
|
result against the expected result. If the result is incorrect then the
|
|
context switch must have caused some corruption. */
|
|
static portTASK_FUNCTION_PROTO( vCompeteingIntMathTask, pvParameters );
|
|
|
|
/* Variables that are set to true within the calculation task to indicate
|
|
that the task is still executing. The check task sets the variable back to
|
|
false, flagging an error if the variable is still false the next time it
|
|
is called. */
|
|
static volatile signed portBASE_TYPE xTaskCheck[ intgNUMBER_OF_TASKS ] = { ( signed portBASE_TYPE ) pdFALSE };
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
void vStartIntegerMathTasks( unsigned portBASE_TYPE uxPriority )
|
|
{
|
|
portSHORT sTask;
|
|
|
|
for( sTask = 0; sTask < intgNUMBER_OF_TASKS; sTask++ )
|
|
{
|
|
xTaskCreate( vCompeteingIntMathTask, ( const signed portCHAR * const ) "IntMath", intgSTACK_SIZE, ( void * ) &( xTaskCheck[ sTask ] ), uxPriority, ( xTaskHandle * ) NULL );
|
|
}
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
static portTASK_FUNCTION( vCompeteingIntMathTask, pvParameters )
|
|
{
|
|
/* These variables are all effectively set to constants so they are volatile to
|
|
ensure the compiler does not just get rid of them. */
|
|
volatile portLONG lValue;
|
|
portSHORT sError = pdFALSE;
|
|
volatile signed portBASE_TYPE *pxTaskHasExecuted;
|
|
|
|
/* Set a pointer to the variable we are going to set to true each
|
|
iteration. This is also a good test of the parameter passing mechanism
|
|
within each port. */
|
|
pxTaskHasExecuted = ( volatile signed portBASE_TYPE * ) pvParameters;
|
|
|
|
/* Keep performing a calculation and checking the result against a constant. */
|
|
for( ;; )
|
|
{
|
|
/* Perform the calculation. This will store partial value in
|
|
registers, resulting in a good test of the context switch mechanism. */
|
|
lValue = intgCONST1;
|
|
lValue += intgCONST2;
|
|
|
|
/* Yield in case cooperative scheduling is being used. */
|
|
#if configUSE_PREEMPTION == 0
|
|
{
|
|
taskYIELD();
|
|
}
|
|
#endif
|
|
|
|
/* Finish off the calculation. */
|
|
lValue *= intgCONST3;
|
|
lValue /= intgCONST4;
|
|
|
|
/* If the calculation is found to be incorrect we stop setting the
|
|
TaskHasExecuted variable so the check task can see an error has
|
|
occurred. */
|
|
if( lValue != intgEXPECTED_ANSWER ) /*lint !e774 volatile used to prevent this being optimised out. */
|
|
{
|
|
sError = pdTRUE;
|
|
}
|
|
|
|
if( sError == pdFALSE )
|
|
{
|
|
/* We have not encountered any errors, so set the flag that show
|
|
we are still executing. This will be periodically cleared by
|
|
the check task. */
|
|
portENTER_CRITICAL();
|
|
*pxTaskHasExecuted = pdTRUE;
|
|
portEXIT_CRITICAL();
|
|
}
|
|
|
|
/* Yield in case cooperative scheduling is being used. */
|
|
#if configUSE_PREEMPTION == 0
|
|
{
|
|
taskYIELD();
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
/* This is called to check that all the created tasks are still running. */
|
|
portBASE_TYPE xAreIntegerMathsTaskStillRunning( void )
|
|
{
|
|
portBASE_TYPE xReturn = pdTRUE;
|
|
portSHORT sTask;
|
|
|
|
/* Check the maths tasks are still running by ensuring their check variables
|
|
are still being set to true. */
|
|
for( sTask = 0; sTask < intgNUMBER_OF_TASKS; sTask++ )
|
|
{
|
|
if( xTaskCheck[ sTask ] == pdFALSE )
|
|
{
|
|
/* The check has not incremented so an error exists. */
|
|
xReturn = pdFALSE;
|
|
}
|
|
|
|
/* Reset the check variable so we can tell if it has been set by
|
|
the next time around. */
|
|
xTaskCheck[ sTask ] = pdFALSE;
|
|
}
|
|
|
|
return xReturn;
|
|
}
|
|
|