root/webserver/example/freeRTOS/Demo/Common/Full/flop.c

Revision 14, 11.9 kB (checked in by phil, 15 years ago)

added unmodified FreeRTOS package V5.4.1 with only web srv demo source for LPC2368 for CrossWorks?

Line 
1 /*
2         FreeRTOS V5.4.1 - Copyright (C) 2009 Real Time Engineers Ltd.
3
4         This file is part of the FreeRTOS distribution.
5
6         FreeRTOS is free software; you can redistribute it and/or modify it     under
7         the terms of the GNU General Public License (version 2) as published by the
8         Free Software Foundation and modified by the FreeRTOS exception.
9         **NOTE** The exception to the GPL is included to allow you to distribute a
10         combined work that includes FreeRTOS without being obliged to provide the
11         source code for proprietary components outside of the FreeRTOS kernel. 
12         Alternative commercial license and support terms are also available upon
13         request.  See the licensing section of http://www.FreeRTOS.org for full
14         license details.
15
16         FreeRTOS is distributed in the hope that it will be useful,     but WITHOUT
17         ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18         FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
19         more details.
20
21         You should have received a copy of the GNU General Public License along
22         with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
23         Temple Place, Suite 330, Boston, MA  02111-1307  USA.
24
25
26         ***************************************************************************
27         *                                                                         *
28         * Looking for a quick start?  Then check out the FreeRTOS eBook!          *
29         * See http://www.FreeRTOS.org/Documentation for details                   *
30         *                                                                         *
31         ***************************************************************************
32
33         1 tab == 4 spaces!
34
35         Please ensure to read the configuration and relevant port sections of the
36         online documentation.
37
38         http://www.FreeRTOS.org - Documentation, latest information, license and
39         contact details.
40
41         http://www.SafeRTOS.com - A version that is certified for use in safety
42         critical systems.
43
44         http://www.OpenRTOS.com - Commercial support, development, porting,
45         licensing and training services.
46 */
47
48 /*
49 Changes from V1.2.3
50        
51         + The created tasks now include calls to tskYIELD(), allowing them to be used
52           with the cooperative scheduler.
53 */
54
55 /**
56  * Creates eight tasks, each of which loops continuously performing an (emulated)
57  * floating point calculation.
58  *
59  * All the tasks run at the idle priority and never block or yield.  This causes
60  * all eight tasks to time slice with the idle task.  Running at the idle priority
61  * means that these tasks will get pre-empted any time another task is ready to run
62  * or a time slice occurs.  More often than not the pre-emption will occur mid
63  * calculation, creating a good test of the schedulers context switch mechanism - a
64  * calculation producing an unexpected result could be a symptom of a corruption in
65  * the context of a task.
66  *
67  * \page FlopC flop.c
68  * \ingroup DemoFiles
69  * <HR>
70  */
71
72 #include <stdlib.h>
73 #include <math.h>
74
75 /* Scheduler include files. */
76 #include "FreeRTOS.h"
77 #include "task.h"
78 #include "print.h"
79
80 /* Demo program include files. */
81 #include "flop.h"
82
83 #define mathSTACK_SIZE          ( ( unsigned portSHORT ) 512 )
84 #define mathNUMBER_OF_TASKS  ( 8 )
85
86 /* Four tasks, each of which performs a different floating point calculation. 
87 Each of the four is created twice. */
88 static void vCompetingMathTask1( void *pvParameters );
89 static void vCompetingMathTask2( void *pvParameters );
90 static void vCompetingMathTask3( void *pvParameters );
91 static void vCompetingMathTask4( void *pvParameters );
92
93 /* These variables are used to check that all the tasks are still running.  If a
94 task gets a calculation wrong it will
95 stop incrementing its check variable. */
96 static volatile unsigned portSHORT usTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned portSHORT ) 0 };
97
98 /*-----------------------------------------------------------*/
99
100 void vStartMathTasks( unsigned portBASE_TYPE uxPriority )
101 {
102         xTaskCreate( vCompetingMathTask1, "Math1", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL );
103         xTaskCreate( vCompetingMathTask2, "Math2", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL );
104         xTaskCreate( vCompetingMathTask3, "Math3", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL );
105         xTaskCreate( vCompetingMathTask4, "Math4", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL );
106         xTaskCreate( vCompetingMathTask1, "Math5", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL );
107         xTaskCreate( vCompetingMathTask2, "Math6", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL );
108         xTaskCreate( vCompetingMathTask3, "Math7", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL );
109         xTaskCreate( vCompetingMathTask4, "Math8", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL );
110 }
111 /*-----------------------------------------------------------*/
112
113 static void vCompetingMathTask1( void *pvParameters )
114 {
115 portDOUBLE d1, d2, d3, d4;
116 volatile unsigned portSHORT *pusTaskCheckVariable;
117 const portDOUBLE dAnswer = ( 123.4567 + 2345.6789 ) * -918.222;
118 const portCHAR * const pcTaskStartMsg = "Math task 1 started.\r\n";
119 const portCHAR * const pcTaskFailMsg = "Math task 1 failed.\r\n";
120 portSHORT sError = pdFALSE;
121
122         /* Queue a message for printing to say the task has started. */
123         vPrintDisplayMessage( &pcTaskStartMsg );
124
125         /* The variable this task increments to show it is still running is passed in
126         as the parameter. */
127         pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters;
128
129         /* Keep performing a calculation and checking the result against a constant. */
130         for(;;)
131         {
132                 d1 = 123.4567;
133                 d2 = 2345.6789;
134                 d3 = -918.222;
135
136                 d4 = ( d1 + d2 ) * d3;
137
138                 taskYIELD();
139
140                 /* If the calculation does not match the expected constant, stop the
141                 increment of the check variable. */
142                 if( fabs( d4 - dAnswer ) > 0.001 )
143                 {
144                         vPrintDisplayMessage( &pcTaskFailMsg );
145                         sError = pdTRUE;
146                 }
147
148                 if( sError == pdFALSE )
149                 {
150                         /* If the calculation has always been correct, increment the check
151                         variable so we know this task is still running okay. */
152                         ( *pusTaskCheckVariable )++;
153                 }
154
155                 taskYIELD();
156         }
157 }
158 /*-----------------------------------------------------------*/
159
160 static void vCompetingMathTask2( void *pvParameters )
161 {
162 portDOUBLE d1, d2, d3, d4;
163 volatile unsigned portSHORT *pusTaskCheckVariable;
164 const portDOUBLE dAnswer = ( -389.38 / 32498.2 ) * -2.0001;
165 const portCHAR * const pcTaskStartMsg = "Math task 2 started.\r\n";
166 const portCHAR * const pcTaskFailMsg = "Math task 2 failed.\r\n";
167 portSHORT sError = pdFALSE;
168
169         /* Queue a message for printing to say the task has started. */
170         vPrintDisplayMessage( &pcTaskStartMsg );
171
172         /* The variable this task increments to show it is still running is passed in
173         as the parameter. */
174         pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters;
175
176         /* Keep performing a calculation and checking the result against a constant. */
177         for( ;; )
178         {
179                 d1 = -389.38;
180                 d2 = 32498.2;
181                 d3 = -2.0001;
182
183                 d4 = ( d1 / d2 ) * d3;
184
185                 taskYIELD();
186                
187                 /* If the calculation does not match the expected constant, stop the
188                 increment of the check variable. */
189                 if( fabs( d4 - dAnswer ) > 0.001 )
190                 {
191                         vPrintDisplayMessage( &pcTaskFailMsg );
192                         sError = pdTRUE;
193                 }
194
195                 if( sError == pdFALSE )
196                 {
197                         /* If the calculation has always been correct, increment the check
198                         variable so we know
199                         this task is still running okay. */
200                         ( *pusTaskCheckVariable )++;
201                 }
202
203                 taskYIELD();
204         }
205 }
206 /*-----------------------------------------------------------*/
207
208 static void vCompetingMathTask3( void *pvParameters )
209 {
210 portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;
211 volatile unsigned portSHORT *pusTaskCheckVariable;
212 const unsigned portSHORT usArraySize = 250;
213 unsigned portSHORT usPosition;
214 const portCHAR * const pcTaskStartMsg = "Math task 3 started.\r\n";
215 const portCHAR * const pcTaskFailMsg = "Math task 3 failed.\r\n";
216 portSHORT sError = pdFALSE;
217
218         /* Queue a message for printing to say the task has started. */
219         vPrintDisplayMessage( &pcTaskStartMsg );
220
221         /* The variable this task increments to show it is still running is passed in
222         as the parameter. */
223         pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters;
224
225         pdArray = ( portDOUBLE * ) pvPortMalloc( ( size_t ) 250 * sizeof( portDOUBLE ) );
226
227         /* Keep filling an array, keeping a running total of the values placed in the
228         array.  Then run through the array adding up all the values.  If the two totals
229         do not match, stop the check variable from incrementing. */
230         for( ;; )
231         {
232                 dTotal1 = 0.0;
233                 dTotal2 = 0.0;
234
235                 for( usPosition = 0; usPosition < usArraySize; usPosition++ )
236                 {
237                         pdArray[ usPosition ] = ( portDOUBLE ) usPosition + 5.5;
238                         dTotal1 += ( portDOUBLE ) usPosition + 5.5;     
239                 }
240
241                 taskYIELD();
242
243                 for( usPosition = 0; usPosition < usArraySize; usPosition++ )
244                 {
245                         dTotal2 += pdArray[ usPosition ];
246                 }
247
248                 dDifference = dTotal1 - dTotal2;
249                 if( fabs( dDifference ) > 0.001 )
250                 {
251                         vPrintDisplayMessage( &pcTaskFailMsg );
252                         sError = pdTRUE;
253                 }
254
255                 taskYIELD();
256
257                 if( sError == pdFALSE )
258                 {
259                         /* If the calculation has always been correct, increment the check
260                         variable so we know     this task is still running okay. */
261                         ( *pusTaskCheckVariable )++;
262                 }
263         }
264 }
265 /*-----------------------------------------------------------*/
266
267 static void vCompetingMathTask4( void *pvParameters )
268 {
269 portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;
270 volatile unsigned portSHORT *pusTaskCheckVariable;
271 const unsigned portSHORT usArraySize = 250;
272 unsigned portSHORT usPosition;
273 const portCHAR * const pcTaskStartMsg = "Math task 4 started.\r\n";
274 const portCHAR * const pcTaskFailMsg = "Math task 4 failed.\r\n";
275 portSHORT sError = pdFALSE;
276
277         /* Queue a message for printing to say the task has started. */
278         vPrintDisplayMessage( &pcTaskStartMsg );
279
280         /* The variable this task increments to show it is still running is passed in
281         as the parameter. */
282         pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters;
283
284         pdArray = ( portDOUBLE * ) pvPortMalloc( ( size_t ) 250 * sizeof( portDOUBLE ) );
285
286         /* Keep filling an array, keeping a running total of the values placed in the
287         array.  Then run through the array adding up all the values.  If the two totals
288         do not match, stop the check variable from incrementing. */
289         for( ;; )
290         {
291                 dTotal1 = 0.0;
292                 dTotal2 = 0.0;
293
294                 for( usPosition = 0; usPosition < usArraySize; usPosition++ )
295                 {
296                         pdArray[ usPosition ] = ( portDOUBLE ) usPosition * 12.123;
297                         dTotal1 += ( portDOUBLE ) usPosition * 12.123; 
298                 }
299
300                 taskYIELD();
301
302                 for( usPosition = 0; usPosition < usArraySize; usPosition++ )
303                 {
304                         dTotal2 += pdArray[ usPosition ];
305                 }
306
307                 dDifference = dTotal1 - dTotal2;
308                 if( fabs( dDifference ) > 0.001 )
309                 {
310                         vPrintDisplayMessage( &pcTaskFailMsg );
311                         sError = pdTRUE;
312                 }
313
314                 taskYIELD();
315
316                 if( sError == pdFALSE )
317                 {
318                         /* If the calculation has always been correct, increment the check
319                         variable so we know     this task is still running okay. */
320                         ( *pusTaskCheckVariable )++;
321                 }
322         }
323 }
324 /*-----------------------------------------------------------*/
325
326 /* This is called to check that all the created tasks are still running. */
327 portBASE_TYPE xAreMathsTaskStillRunning( void )
328 {
329 /* Keep a history of the check variables so we know if they have been incremented
330 since the last call. */
331 static unsigned portSHORT usLastTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned portSHORT ) 0 };
332 portBASE_TYPE xReturn = pdTRUE, xTask;
333
334         /* Check the maths tasks are still running by ensuring their check variables
335         are still incrementing. */
336         for( xTask = 0; xTask < mathNUMBER_OF_TASKS; xTask++ )
337         {
338                 if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] )
339                 {
340                         /* The check has not incremented so an error exists. */
341                         xReturn = pdFALSE;
342                 }
343
344                 usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ];
345         }
346
347         return xReturn;
348 }
349
350
351
Note: See TracBrowser for help on using the browser.