2 FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
\r
4 FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
\r
5 http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
\r
7 ***************************************************************************
\r
9 * FreeRTOS tutorial books are available in pdf and paperback. *
\r
10 * Complete, revised, and edited pdf reference manuals are also *
\r
13 * Purchasing FreeRTOS documentation will not only help you, by *
\r
14 * ensuring you get running as quickly as possible and with an *
\r
15 * in-depth knowledge of how to use FreeRTOS, it will also help *
\r
16 * the FreeRTOS project to continue with its mission of providing *
\r
17 * professional grade, cross platform, de facto standard solutions *
\r
18 * for microcontrollers - completely free of charge! *
\r
20 * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
\r
22 * Thank you for using FreeRTOS, and thank you for your support! *
\r
24 ***************************************************************************
\r
27 This file is part of the FreeRTOS distribution.
\r
29 FreeRTOS is free software; you can redistribute it and/or modify it under
\r
30 the terms of the GNU General Public License (version 2) as published by the
\r
31 Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
\r
32 >>>NOTE<<< The modification to the GPL is included to allow you to
\r
33 distribute a combined work that includes FreeRTOS without being obliged to
\r
34 provide the source code for proprietary components outside of the FreeRTOS
\r
35 kernel. FreeRTOS is distributed in the hope that it will be useful, but
\r
36 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
\r
37 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
\r
38 more details. You should have received a copy of the GNU General Public
\r
39 License and the FreeRTOS license exception along with FreeRTOS; if not it
\r
40 can be viewed here: http://www.freertos.org/a00114.html and also obtained
\r
41 by writing to Richard Barry, contact details for whom are available on the
\r
46 ***************************************************************************
\r
48 * Having a problem? Start by reading the FAQ "My application does *
\r
49 * not run, what could be wrong?" *
\r
51 * http://www.FreeRTOS.org/FAQHelp.html *
\r
53 ***************************************************************************
\r
56 http://www.FreeRTOS.org - Documentation, training, latest versions, license
\r
57 and contact details.
\r
59 http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
\r
60 including FreeRTOS+Trace - an indispensable productivity tool.
\r
62 Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
\r
63 the code with commercial support, indemnification, and middleware, under
\r
64 the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
\r
65 provide a safety engineered and independently SIL3 certified version under
\r
66 the SafeRTOS brand: http://www.SafeRTOS.com.
\r
70 * Creates eight tasks, each of which loops continuously performing an (emulated)
\r
71 * floating point calculation.
\r
73 * All the tasks run at the idle priority and never block or yield. This causes
\r
74 * all eight tasks to time slice with the idle task. Running at the idle priority
\r
75 * means that these tasks will get pre-empted any time another task is ready to run
\r
76 * or a time slice occurs. More often than not the pre-emption will occur mid
\r
77 * calculation, creating a good test of the schedulers context switch mechanism - a
\r
78 * calculation producing an unexpected result could be a symptom of a corruption in
\r
79 * the context of a task.
\r
85 /* Scheduler include files. */
\r
86 #include "FreeRTOS.h"
\r
89 /* Demo program include files. */
\r
92 #define mathSTACK_SIZE configMINIMAL_STACK_SIZE
\r
93 #define mathNUMBER_OF_TASKS ( 8 )
\r
95 /* Four tasks, each of which performs a different floating point calculation.
\r
96 Each of the four is created twice. */
\r
97 static portTASK_FUNCTION_PROTO( vCompetingMathTask1, pvParameters );
\r
98 static portTASK_FUNCTION_PROTO( vCompetingMathTask2, pvParameters );
\r
99 static portTASK_FUNCTION_PROTO( vCompetingMathTask3, pvParameters );
\r
100 static portTASK_FUNCTION_PROTO( vCompetingMathTask4, pvParameters );
\r
102 /* These variables are used to check that all the tasks are still running. If a
\r
103 task gets a calculation wrong it will
\r
104 stop incrementing its check variable. */
\r
105 static volatile unsigned short usTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };
\r
107 /* Must be called before any hardware floating point operations are
\r
108 performed to let the RTOS portable layer know that this task requires
\r
109 a floating point context. */
\r
110 #if __TI_VFP_SUPPORT__
\r
111 extern void vPortTaskUsesFPU( void );
\r
114 /*-----------------------------------------------------------*/
\r
116 void vStartMathTasks( unsigned portBASE_TYPE uxPriority )
\r
118 xTaskCreate( vCompetingMathTask1, ( signed char * ) "Math1", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL );
\r
119 xTaskCreate( vCompetingMathTask2, ( signed char * ) "Math2", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL );
\r
120 xTaskCreate( vCompetingMathTask3, ( signed char * ) "Math3", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL );
\r
121 xTaskCreate( vCompetingMathTask4, ( signed char * ) "Math4", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL );
\r
122 xTaskCreate( vCompetingMathTask1, ( signed char * ) "Math5", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL );
\r
123 xTaskCreate( vCompetingMathTask2, ( signed char * ) "Math6", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL );
\r
124 xTaskCreate( vCompetingMathTask3, ( signed char * ) "Math7", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL );
\r
125 xTaskCreate( vCompetingMathTask4, ( signed char * ) "Math8", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL );
\r
127 /*-----------------------------------------------------------*/
\r
129 static portTASK_FUNCTION( vCompetingMathTask1, pvParameters )
\r
131 volatile portDOUBLE d1, d2, d3, d4;
\r
132 volatile unsigned short *pusTaskCheckVariable;
\r
133 volatile portDOUBLE dAnswer;
\r
134 short sError = pdFALSE;
\r
137 /* Must be called before any hardware floating point operations are
\r
138 performed to let the RTOS portable layer know that this task requires
\r
139 a floating point context. */
\r
140 #if __TI_VFP_SUPPORT__
\r
141 vPortTaskUsesFPU();
\r
148 dAnswer = ( d1 + d2 ) * d3;
\r
150 /* The variable this task increments to show it is still running is passed in
\r
151 as the parameter. */
\r
152 pusTaskCheckVariable = ( unsigned short * ) pvParameters;
\r
154 /* Keep performing a calculation and checking the result against a constant. */
\r
161 d4 = ( d1 + d2 ) * d3;
\r
163 #if configUSE_PREEMPTION == 0
\r
167 /* If the calculation does not match the expected constant, stop the
\r
168 increment of the check variable. */
\r
169 if( fabs( d4 - dAnswer ) > 0.001 )
\r
174 if( sError == pdFALSE )
\r
176 /* If the calculation has always been correct, increment the check
\r
177 variable so we know this task is still running okay. */
\r
178 ( *pusTaskCheckVariable )++;
\r
181 #if configUSE_PREEMPTION == 0
\r
187 /*-----------------------------------------------------------*/
\r
189 static portTASK_FUNCTION( vCompetingMathTask2, pvParameters )
\r
191 volatile portDOUBLE d1, d2, d3, d4;
\r
192 volatile unsigned short *pusTaskCheckVariable;
\r
193 volatile portDOUBLE dAnswer;
\r
194 short sError = pdFALSE;
\r
196 /* Must be called before any hardware floating point operations are
\r
197 performed to let the RTOS portable layer know that this task requires
\r
198 a floating point context. */
\r
199 #if __TI_VFP_SUPPORT__
\r
200 vPortTaskUsesFPU();
\r
207 dAnswer = ( d1 / d2 ) * d3;
\r
210 /* The variable this task increments to show it is still running is passed in
\r
211 as the parameter. */
\r
212 pusTaskCheckVariable = ( unsigned short * ) pvParameters;
\r
214 /* Keep performing a calculation and checking the result against a constant. */
\r
221 d4 = ( d1 / d2 ) * d3;
\r
223 #if configUSE_PREEMPTION == 0
\r
227 /* If the calculation does not match the expected constant, stop the
\r
228 increment of the check variable. */
\r
229 if( fabs( d4 - dAnswer ) > 0.001 )
\r
234 if( sError == pdFALSE )
\r
236 /* If the calculation has always been correct, increment the check
\r
237 variable so we know
\r
238 this task is still running okay. */
\r
239 ( *pusTaskCheckVariable )++;
\r
242 #if configUSE_PREEMPTION == 0
\r
247 /*-----------------------------------------------------------*/
\r
249 static portTASK_FUNCTION( vCompetingMathTask3, pvParameters )
\r
251 volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;
\r
252 volatile unsigned short *pusTaskCheckVariable;
\r
253 const size_t xArraySize = 10;
\r
255 short sError = pdFALSE;
\r
257 /* Must be called before any hardware floating point operations are
\r
258 performed to let the RTOS portable layer know that this task requires
\r
259 a floating point context. */
\r
260 #if __TI_VFP_SUPPORT__
\r
261 vPortTaskUsesFPU();
\r
264 /* The variable this task increments to show it is still running is passed in
\r
265 as the parameter. */
\r
266 pusTaskCheckVariable = ( unsigned short * ) pvParameters;
\r
268 pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) );
\r
270 /* Keep filling an array, keeping a running total of the values placed in the
\r
271 array. Then run through the array adding up all the values. If the two totals
\r
272 do not match, stop the check variable from incrementing. */
\r
278 for( xPosition = 0; xPosition < xArraySize; xPosition++ )
\r
280 pdArray[ xPosition ] = ( portDOUBLE ) xPosition + 5.5;
\r
281 dTotal1 += ( portDOUBLE ) xPosition + 5.5;
\r
284 #if configUSE_PREEMPTION == 0
\r
288 for( xPosition = 0; xPosition < xArraySize; xPosition++ )
\r
290 dTotal2 += pdArray[ xPosition ];
\r
293 dDifference = dTotal1 - dTotal2;
\r
294 if( fabs( dDifference ) > 0.001 )
\r
299 #if configUSE_PREEMPTION == 0
\r
303 if( sError == pdFALSE )
\r
305 /* If the calculation has always been correct, increment the check
\r
306 variable so we know this task is still running okay. */
\r
307 ( *pusTaskCheckVariable )++;
\r
311 /*-----------------------------------------------------------*/
\r
313 static portTASK_FUNCTION( vCompetingMathTask4, pvParameters )
\r
315 volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;
\r
316 volatile unsigned short *pusTaskCheckVariable;
\r
317 const size_t xArraySize = 10;
\r
319 short sError = pdFALSE;
\r
321 /* Must be called before any hardware floating point operations are
\r
322 performed to let the RTOS portable layer know that this task requires
\r
323 a floating point context. */
\r
324 #if __TI_VFP_SUPPORT__
\r
325 vPortTaskUsesFPU();
\r
328 /* The variable this task increments to show it is still running is passed in
\r
329 as the parameter. */
\r
330 pusTaskCheckVariable = ( unsigned short * ) pvParameters;
\r
332 pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) );
\r
334 /* Keep filling an array, keeping a running total of the values placed in the
\r
335 array. Then run through the array adding up all the values. If the two totals
\r
336 do not match, stop the check variable from incrementing. */
\r
342 for( xPosition = 0; xPosition < xArraySize; xPosition++ )
\r
344 pdArray[ xPosition ] = ( portDOUBLE ) xPosition * 12.123;
\r
345 dTotal1 += ( portDOUBLE ) xPosition * 12.123;
\r
348 #if configUSE_PREEMPTION == 0
\r
352 for( xPosition = 0; xPosition < xArraySize; xPosition++ )
\r
354 dTotal2 += pdArray[ xPosition ];
\r
357 dDifference = dTotal1 - dTotal2;
\r
358 if( fabs( dDifference ) > 0.001 )
\r
363 #if configUSE_PREEMPTION == 0
\r
367 if( sError == pdFALSE )
\r
369 /* If the calculation has always been correct, increment the check
\r
370 variable so we know this task is still running okay. */
\r
371 ( *pusTaskCheckVariable )++;
\r
375 /*-----------------------------------------------------------*/
\r
377 /* This is called to check that all the created tasks are still running. */
\r
378 portBASE_TYPE xAreMathsTaskStillRunning( void )
\r
380 /* Keep a history of the check variables so we know if they have been incremented
\r
381 since the last call. */
\r
382 static unsigned short usLastTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };
\r
383 portBASE_TYPE xReturn = pdTRUE, xTask;
\r
385 /* Check the maths tasks are still running by ensuring their check variables
\r
386 are still incrementing. */
\r
387 for( xTask = 0; xTask < mathNUMBER_OF_TASKS; xTask++ )
\r
389 if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] )
\r
391 /* The check has not incremented so an error exists. */
\r
395 usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ];
\r