2 FreeRTOS V7.4.0 - Copyright (C) 2013 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
33 >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to
\r
34 distribute a combined work that includes FreeRTOS without being obliged to
\r
35 provide the source code for proprietary components outside of the FreeRTOS
\r
38 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
\r
39 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
\r
40 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
\r
41 details. You should have received a copy of the GNU General Public License
\r
42 and the FreeRTOS license exception along with FreeRTOS; if not itcan be
\r
43 viewed here: http://www.freertos.org/a00114.html and also obtained by
\r
44 writing to Real Time Engineers Ltd., contact details for whom are available
\r
45 on the FreeRTOS WEB site.
\r
49 ***************************************************************************
\r
51 * Having a problem? Start by reading the FAQ "My application does *
\r
52 * not run, what could be wrong?" *
\r
54 * http://www.FreeRTOS.org/FAQHelp.html *
\r
56 ***************************************************************************
\r
59 http://www.FreeRTOS.org - Documentation, books, training, latest versions,
\r
60 license and Real Time Engineers Ltd. contact details.
\r
62 http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
\r
63 including FreeRTOS+Trace - an indispensable productivity tool, and our new
\r
64 fully thread aware and reentrant UDP/IP stack.
\r
66 http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
\r
67 Integrity Systems, who sell the code with commercial support,
\r
68 indemnification and middleware, under the OpenRTOS brand.
\r
70 http://www.SafeRTOS.com - High Integrity Systems also provide a safety
\r
71 engineered and independently SIL3 certified version for use in safety and
\r
72 mission critical applications that require provable dependability.
\r
78 + The created tasks now include calls to tskYIELD(), allowing them to be used
\r
79 with the cooperative scheduler.
\r
83 * This does the same as flop. c, but uses variables of type long instead of
\r
86 * As with flop. c, the tasks created in this file are a good test of the
\r
87 * scheduler context switch mechanism. The processor has to access 32bit
\r
88 * variables in two or four chunks (depending on the processor). The low
\r
89 * priority of these tasks means there is a high probability that a context
\r
90 * switch will occur mid calculation. See the flop. c documentation for
\r
93 * \page IntegerC integer.c
\r
94 * \ingroup DemoFiles
\r
101 + The constants used in the calculations are larger to ensure the
\r
102 optimiser does not truncate them to 16 bits.
\r
105 #include <stdlib.h>
\r
107 /* Scheduler include files. */
\r
108 #include "FreeRTOS.h"
\r
112 /* Demo program include files. */
\r
113 #include "integer.h"
\r
115 #define intgSTACK_SIZE ( ( unsigned short ) 256 )
\r
116 #define intgNUMBER_OF_TASKS ( 8 )
\r
118 /* Four tasks, each of which performs a different calculation on four byte
\r
119 variables. Each of the four is created twice. */
\r
120 static void vCompeteingIntMathTask1( void *pvParameters );
\r
121 static void vCompeteingIntMathTask2( void *pvParameters );
\r
122 static void vCompeteingIntMathTask3( void *pvParameters );
\r
123 static void vCompeteingIntMathTask4( void *pvParameters );
\r
125 /* These variables are used to check that all the tasks are still running. If a
\r
126 task gets a calculation wrong it will stop incrementing its check variable. */
\r
127 static volatile unsigned short usTaskCheck[ intgNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };
\r
128 /*-----------------------------------------------------------*/
\r
130 void vStartIntegerMathTasks( unsigned portBASE_TYPE uxPriority )
\r
132 xTaskCreate( vCompeteingIntMathTask1, "IntMath1", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL );
\r
133 xTaskCreate( vCompeteingIntMathTask2, "IntMath2", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL );
\r
134 xTaskCreate( vCompeteingIntMathTask3, "IntMath3", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL );
\r
135 xTaskCreate( vCompeteingIntMathTask4, "IntMath4", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL );
\r
136 xTaskCreate( vCompeteingIntMathTask1, "IntMath5", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL );
\r
137 xTaskCreate( vCompeteingIntMathTask2, "IntMath6", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL );
\r
138 xTaskCreate( vCompeteingIntMathTask3, "IntMath7", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL );
\r
139 xTaskCreate( vCompeteingIntMathTask4, "IntMath8", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL );
\r
141 /*-----------------------------------------------------------*/
\r
143 static void vCompeteingIntMathTask1( void *pvParameters )
\r
145 long l1, l2, l3, l4;
\r
146 short sError = pdFALSE;
\r
147 volatile unsigned short *pusTaskCheckVariable;
\r
148 const long lAnswer = ( ( long ) 74565L + ( long ) 1234567L ) * ( long ) -918L;
\r
149 const char * const pcTaskStartMsg = "Integer math task 1 started.\r\n";
\r
150 const char * const pcTaskFailMsg = "Integer math task 1 failed.\r\n";
\r
152 /* Queue a message for printing to say the task has started. */
\r
153 vPrintDisplayMessage( &pcTaskStartMsg );
\r
155 /* The variable this task increments to show it is still running is passed in
\r
156 as the parameter. */
\r
157 pusTaskCheckVariable = ( unsigned short * ) pvParameters;
\r
159 /* Keep performing a calculation and checking the result against a constant. */
\r
162 l1 = ( long ) 74565L;
\r
163 l2 = ( long ) 1234567L;
\r
164 l3 = ( long ) -918L;
\r
166 l4 = ( l1 + l2 ) * l3;
\r
170 /* If the calculation does not match the expected constant, stop the
\r
171 increment of the check variable. */
\r
172 if( l4 != lAnswer )
\r
174 vPrintDisplayMessage( &pcTaskFailMsg );
\r
178 if( sError == pdFALSE )
\r
180 /* If the calculation has always been correct, increment the check
\r
181 variable so we know this task is still running okay. */
\r
182 ( *pusTaskCheckVariable )++;
\r
186 /*-----------------------------------------------------------*/
\r
188 static void vCompeteingIntMathTask2( void *pvParameters )
\r
190 long l1, l2, l3, l4;
\r
191 short sError = pdFALSE;
\r
192 volatile unsigned short *pusTaskCheckVariable;
\r
193 const long lAnswer = ( ( long ) -389000L / ( long ) 329999L ) * ( long ) -89L;
\r
194 const char * const pcTaskStartMsg = "Integer math task 2 started.\r\n";
\r
195 const char * const pcTaskFailMsg = "Integer math task 2 failed.\r\n";
\r
197 /* Queue a message for printing to say the task has started. */
\r
198 vPrintDisplayMessage( &pcTaskStartMsg );
\r
200 /* The variable this task increments to show it is still running is passed in
\r
201 as the parameter. */
\r
202 pusTaskCheckVariable = ( unsigned short * ) pvParameters;
\r
204 /* Keep performing a calculation and checking the result against a constant. */
\r
211 l4 = ( l1 / l2 ) * l3;
\r
215 /* If the calculation does not match the expected constant, stop the
\r
216 increment of the check variable. */
\r
217 if( l4 != lAnswer )
\r
219 vPrintDisplayMessage( &pcTaskFailMsg );
\r
223 if( sError == pdFALSE )
\r
225 /* If the calculation has always been correct, increment the check
\r
226 variable so we know this task is still running okay. */
\r
227 ( *pusTaskCheckVariable )++;
\r
231 /*-----------------------------------------------------------*/
\r
233 static void vCompeteingIntMathTask3( void *pvParameters )
\r
235 long *plArray, lTotal1, lTotal2;
\r
236 short sError = pdFALSE;
\r
237 volatile unsigned short *pusTaskCheckVariable;
\r
238 const unsigned short usArraySize = ( unsigned short ) 250;
\r
239 unsigned short usPosition;
\r
240 const char * const pcTaskStartMsg = "Integer math task 3 started.\r\n";
\r
241 const char * const pcTaskFailMsg = "Integer math task 3 failed.\r\n";
\r
243 /* Queue a message for printing to say the task has started. */
\r
244 vPrintDisplayMessage( &pcTaskStartMsg );
\r
246 /* The variable this task increments to show it is still running is passed in
\r
247 as the parameter. */
\r
248 pusTaskCheckVariable = ( unsigned short * ) pvParameters;
\r
250 /* Create the array we are going to use for our check calculation. */
\r
251 plArray = ( long * ) pvPortMalloc( ( size_t ) 250 * sizeof( long ) );
\r
253 /* Keep filling the array, keeping a running total of the values placed in the
\r
254 array. Then run through the array adding up all the values. If the two totals
\r
255 do not match, stop the check variable from incrementing. */
\r
258 lTotal1 = ( long ) 0;
\r
259 lTotal2 = ( long ) 0;
\r
261 for( usPosition = 0; usPosition < usArraySize; usPosition++ )
\r
263 plArray[ usPosition ] = ( long ) usPosition + ( long ) 5;
\r
264 lTotal1 += ( long ) usPosition + ( long ) 5;
\r
269 for( usPosition = 0; usPosition < usArraySize; usPosition++ )
\r
271 lTotal2 += plArray[ usPosition ];
\r
274 if( lTotal1 != lTotal2 )
\r
276 vPrintDisplayMessage( &pcTaskFailMsg );
\r
282 if( sError == pdFALSE )
\r
284 /* If the calculation has always been correct, increment the check
\r
285 variable so we know this task is still running okay. */
\r
286 ( *pusTaskCheckVariable )++;
\r
290 /*-----------------------------------------------------------*/
\r
292 static void vCompeteingIntMathTask4( void *pvParameters )
\r
294 long *plArray, lTotal1, lTotal2;
\r
295 short sError = pdFALSE;
\r
296 volatile unsigned short *pusTaskCheckVariable;
\r
297 const unsigned short usArraySize = 250;
\r
298 unsigned short usPosition;
\r
299 const char * const pcTaskStartMsg = "Integer math task 4 started.\r\n";
\r
300 const char * const pcTaskFailMsg = "Integer math task 4 failed.\r\n";
\r
302 /* Queue a message for printing to say the task has started. */
\r
303 vPrintDisplayMessage( &pcTaskStartMsg );
\r
305 /* The variable this task increments to show it is still running is passed in
\r
306 as the parameter. */
\r
307 pusTaskCheckVariable = ( unsigned short * ) pvParameters;
\r
309 /* Create the array we are going to use for our check calculation. */
\r
310 plArray = ( long * ) pvPortMalloc( ( size_t ) 250 * sizeof( long ) );
\r
312 /* Keep filling the array, keeping a running total of the values placed in the
\r
313 array. Then run through the array adding up all the values. If the two totals
\r
314 do not match, stop the check variable from incrementing. */
\r
317 lTotal1 = ( long ) 0;
\r
318 lTotal2 = ( long ) 0;
\r
320 for( usPosition = 0; usPosition < usArraySize; usPosition++ )
\r
322 plArray[ usPosition ] = ( long ) usPosition * ( long ) 12;
\r
323 lTotal1 += ( long ) usPosition * ( long ) 12;
\r
328 for( usPosition = 0; usPosition < usArraySize; usPosition++ )
\r
330 lTotal2 += plArray[ usPosition ];
\r
334 if( lTotal1 != lTotal2 )
\r
336 vPrintDisplayMessage( &pcTaskFailMsg );
\r
342 if( sError == pdFALSE )
\r
344 /* If the calculation has always been correct, increment the check
\r
345 variable so we know this task is still running okay. */
\r
346 ( *pusTaskCheckVariable )++;
\r
350 /*-----------------------------------------------------------*/
\r
352 /* This is called to check that all the created tasks are still running. */
\r
353 portBASE_TYPE xAreIntegerMathsTaskStillRunning( void )
\r
355 /* Keep a history of the check variables so we know if they have been incremented
\r
356 since the last call. */
\r
357 static unsigned short usLastTaskCheck[ intgNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };
\r
358 portBASE_TYPE xReturn = pdTRUE, xTask;
\r
360 /* Check the maths tasks are still running by ensuring their check variables
\r
361 are still incrementing. */
\r
362 for( xTask = 0; xTask < intgNUMBER_OF_TASKS; xTask++ )
\r
364 if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] )
\r
366 /* The check has not incremented so an error exists. */
\r
370 usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ];
\r