root/webserver/example/freeRTOSexample/EnergyMeters/Common/Minimal/flop.c

Revision 14, 11.2 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  * Creates eight tasks, each of which loops continuously performing an (emulated)
50  * floating point calculation.
51  *
52  * All the tasks run at the idle priority and never block or yield.  This causes
53  * all eight tasks to time slice with the idle task.  Running at the idle priority
54  * means that these tasks will get pre-empted any time another task is ready to run
55  * or a time slice occurs.  More often than not the pre-emption will occur mid
56  * calculation, creating a good test of the schedulers context switch mechanism - a
57  * calculation producing an unexpected result could be a symptom of a corruption in
58  * the context of a task.
59  */
60
61 #include <stdlib.h>
62 #include <math.h>
63
64 /* Scheduler include files. */
65 #include "FreeRTOS.h"
66 #include "task.h"
67
68 /* Demo program include files. */
69 #include "flop.h"
70
71 #define mathSTACK_SIZE          configMINIMAL_STACK_SIZE
72 #define mathNUMBER_OF_TASKS  ( 8 )
73
74 /* Four tasks, each of which performs a different floating point calculation. 
75 Each of the four is created twice. */
76 static portTASK_FUNCTION_PROTO( vCompetingMathTask1, pvParameters );
77 static portTASK_FUNCTION_PROTO( vCompetingMathTask2, pvParameters );
78 static portTASK_FUNCTION_PROTO( vCompetingMathTask3, pvParameters );
79 static portTASK_FUNCTION_PROTO( vCompetingMathTask4, pvParameters );
80
81 /* These variables are used to check that all the tasks are still running.  If a
82 task gets a calculation wrong it will
83 stop incrementing its check variable. */
84 static volatile unsigned portSHORT usTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned portSHORT ) 0 };
85
86 /*-----------------------------------------------------------*/
87
88 void vStartMathTasks( unsigned portBASE_TYPE uxPriority )
89 {
90         xTaskCreate( vCompetingMathTask1, ( signed portCHAR * ) "Math1", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL );
91         xTaskCreate( vCompetingMathTask2, ( signed portCHAR * ) "Math2", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL );
92         xTaskCreate( vCompetingMathTask3, ( signed portCHAR * ) "Math3", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL );
93         xTaskCreate( vCompetingMathTask4, ( signed portCHAR * ) "Math4", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL );
94         xTaskCreate( vCompetingMathTask1, ( signed portCHAR * ) "Math5", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL );
95         xTaskCreate( vCompetingMathTask2, ( signed portCHAR * ) "Math6", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL );
96         xTaskCreate( vCompetingMathTask3, ( signed portCHAR * ) "Math7", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL );
97         xTaskCreate( vCompetingMathTask4, ( signed portCHAR * ) "Math8", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL );
98 }
99 /*-----------------------------------------------------------*/
100
101 static portTASK_FUNCTION( vCompetingMathTask1, pvParameters )
102 {
103 volatile portDOUBLE d1, d2, d3, d4;
104 volatile unsigned portSHORT *pusTaskCheckVariable;
105 volatile portDOUBLE dAnswer;
106 portSHORT sError = pdFALSE;
107
108         d1 = 123.4567;
109         d2 = 2345.6789;
110         d3 = -918.222;
111
112         dAnswer = ( d1 + d2 ) * d3;
113
114         /* The variable this task increments to show it is still running is passed in
115         as the parameter. */
116         pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters;
117
118         /* Keep performing a calculation and checking the result against a constant. */
119         for(;;)
120         {
121                 d1 = 123.4567;
122                 d2 = 2345.6789;
123                 d3 = -918.222;
124
125                 d4 = ( d1 + d2 ) * d3;
126
127                 #if configUSE_PREEMPTION == 0
128                         taskYIELD();
129                 #endif
130
131                 /* If the calculation does not match the expected constant, stop the
132                 increment of the check variable. */
133                 if( fabs( d4 - dAnswer ) > 0.001 )
134                 {
135                         sError = pdTRUE;
136                 }
137
138                 if( sError == pdFALSE )
139                 {
140                         /* If the calculation has always been correct, increment the check
141                         variable so we know this task is still running okay. */
142                         ( *pusTaskCheckVariable )++;
143                 }
144
145                 #if configUSE_PREEMPTION == 0
146                         taskYIELD();
147                 #endif
148
149         }
150 }
151 /*-----------------------------------------------------------*/
152
153 static portTASK_FUNCTION( vCompetingMathTask2, pvParameters )
154 {
155 volatile portDOUBLE d1, d2, d3, d4;
156 volatile unsigned portSHORT *pusTaskCheckVariable;
157 volatile portDOUBLE dAnswer;
158 portSHORT sError = pdFALSE;
159
160         d1 = -389.38;
161         d2 = 32498.2;
162         d3 = -2.0001;
163
164         dAnswer = ( d1 / d2 ) * d3;
165
166
167         /* The variable this task increments to show it is still running is passed in
168         as the parameter. */
169         pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters;
170
171         /* Keep performing a calculation and checking the result against a constant. */
172         for( ;; )
173         {
174                 d1 = -389.38;
175                 d2 = 32498.2;
176                 d3 = -2.0001;
177
178                 d4 = ( d1 / d2 ) * d3;
179
180                 #if configUSE_PREEMPTION == 0
181                         taskYIELD();
182                 #endif
183                
184                 /* If the calculation does not match the expected constant, stop the
185                 increment of the check variable. */
186                 if( fabs( d4 - dAnswer ) > 0.001 )
187                 {
188                         sError = pdTRUE;
189                 }
190
191                 if( sError == pdFALSE )
192                 {
193                         /* If the calculation has always been correct, increment the check
194                         variable so we know
195                         this task is still running okay. */
196                         ( *pusTaskCheckVariable )++;
197                 }
198
199                 #if configUSE_PREEMPTION == 0
200                         taskYIELD();
201                 #endif
202         }
203 }
204 /*-----------------------------------------------------------*/
205
206 static portTASK_FUNCTION( vCompetingMathTask3, pvParameters )
207 {
208 volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;
209 volatile unsigned portSHORT *pusTaskCheckVariable;
210 const size_t xArraySize = 10;
211 size_t xPosition;
212 portSHORT sError = pdFALSE;
213
214         /* The variable this task increments to show it is still running is passed in
215         as the parameter. */
216         pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters;
217
218         pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) );
219
220         /* Keep filling an array, keeping a running total of the values placed in the
221         array.  Then run through the array adding up all the values.  If the two totals
222         do not match, stop the check variable from incrementing. */
223         for( ;; )
224         {
225                 dTotal1 = 0.0;
226                 dTotal2 = 0.0;
227
228                 for( xPosition = 0; xPosition < xArraySize; xPosition++ )
229                 {
230                         pdArray[ xPosition ] = ( portDOUBLE ) xPosition + 5.5;
231                         dTotal1 += ( portDOUBLE ) xPosition + 5.5;     
232                 }
233
234                 #if configUSE_PREEMPTION == 0
235                         taskYIELD();
236                 #endif
237
238                 for( xPosition = 0; xPosition < xArraySize; xPosition++ )
239                 {
240                         dTotal2 += pdArray[ xPosition ];
241                 }
242
243                 dDifference = dTotal1 - dTotal2;
244                 if( fabs( dDifference ) > 0.001 )
245                 {
246                         sError = pdTRUE;
247                 }
248
249                 #if configUSE_PREEMPTION == 0
250                         taskYIELD();
251                 #endif
252
253                 if( sError == pdFALSE )
254                 {
255                         /* If the calculation has always been correct, increment the check
256                         variable so we know     this task is still running okay. */
257                         ( *pusTaskCheckVariable )++;
258                 }
259         }
260 }
261 /*-----------------------------------------------------------*/
262
263 static portTASK_FUNCTION( vCompetingMathTask4, pvParameters )
264 {
265 volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;
266 volatile unsigned portSHORT *pusTaskCheckVariable;
267 const size_t xArraySize = 10;
268 size_t xPosition;
269 portSHORT sError = pdFALSE;
270
271         /* The variable this task increments to show it is still running is passed in
272         as the parameter. */
273         pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters;
274
275         pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) );
276
277         /* Keep filling an array, keeping a running total of the values placed in the
278         array.  Then run through the array adding up all the values.  If the two totals
279         do not match, stop the check variable from incrementing. */
280         for( ;; )
281         {
282                 dTotal1 = 0.0;
283                 dTotal2 = 0.0;
284
285                 for( xPosition = 0; xPosition < xArraySize; xPosition++ )
286                 {
287                         pdArray[ xPosition ] = ( portDOUBLE ) xPosition * 12.123;
288                         dTotal1 += ( portDOUBLE ) xPosition * 12.123;   
289                 }
290
291                 #if configUSE_PREEMPTION == 0
292                         taskYIELD();
293                 #endif
294
295                 for( xPosition = 0; xPosition < xArraySize; xPosition++ )
296                 {
297                         dTotal2 += pdArray[ xPosition ];
298                 }
299
300                 dDifference = dTotal1 - dTotal2;
301                 if( fabs( dDifference ) > 0.001 )
302                 {
303                         sError = pdTRUE;
304                 }
305
306                 #if configUSE_PREEMPTION == 0
307                         taskYIELD();
308                 #endif
309
310                 if( sError == pdFALSE )
311                 {
312                         /* If the calculation has always been correct, increment the check
313                         variable so we know     this task is still running okay. */
314                         ( *pusTaskCheckVariable )++;
315                 }
316         }
317 }                               
318 /*-----------------------------------------------------------*/
319
320 /* This is called to check that all the created tasks are still running. */
321 portBASE_TYPE xAreMathsTaskStillRunning( void )
322 {
323 /* Keep a history of the check variables so we know if they have been incremented
324 since the last call. */
325 static unsigned portSHORT usLastTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned portSHORT ) 0 };
326 portBASE_TYPE xReturn = pdTRUE, xTask;
327
328         /* Check the maths tasks are still running by ensuring their check variables
329         are still incrementing. */
330         for( xTask = 0; xTask < mathNUMBER_OF_TASKS; xTask++ )
331         {
332                 if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] )
333                 {
334                         /* The check has not incremented so an error exists. */
335                         xReturn = pdFALSE;
336                 }
337
338                 usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ];
339         }
340
341         return xReturn;
342 }
343
344
345
Note: See TracBrowser for help on using the browser.