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

Revision 14, 12.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 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  * This does the same as flop. c, but uses variables of type long instead of
57  * type double. 
58  *
59  * As with flop. c, the tasks created in this file are a good test of the
60  * scheduler context switch mechanism.  The processor has to access 32bit
61  * variables in two or four chunks (depending on the processor).  The low
62  * priority of these tasks means there is a high probability that a context
63  * switch will occur mid calculation.  See the flop. c documentation for
64  * more information.
65  *
66  * \page IntegerC integer.c
67  * \ingroup DemoFiles
68  * <HR>
69  */
70
71 /*
72 Changes from V1.2.1
73
74         + The constants used in the calculations are larger to ensure the
75           optimiser does not truncate them to 16 bits.
76 */
77
78 #include <stdlib.h>
79
80 /* Scheduler include files. */
81 #include "FreeRTOS.h"
82 #include "task.h"
83 #include "print.h"
84
85 /* Demo program include files. */
86 #include "integer.h"
87
88 #define intgSTACK_SIZE          ( ( unsigned portSHORT ) 256 )
89 #define intgNUMBER_OF_TASKS  ( 8 )
90
91 /* Four tasks, each of which performs a different calculation on four byte
92 variables.  Each of the four is created twice. */
93 static void vCompeteingIntMathTask1( void *pvParameters );
94 static void vCompeteingIntMathTask2( void *pvParameters );
95 static void vCompeteingIntMathTask3( void *pvParameters );
96 static void vCompeteingIntMathTask4( void *pvParameters );
97
98 /* These variables are used to check that all the tasks are still running.  If a
99 task gets a calculation wrong it will stop incrementing its check variable. */
100 static volatile unsigned portSHORT usTaskCheck[ intgNUMBER_OF_TASKS ] = { ( unsigned portSHORT ) 0 };
101 /*-----------------------------------------------------------*/
102
103 void vStartIntegerMathTasks( unsigned portBASE_TYPE uxPriority )
104 {
105         xTaskCreate( vCompeteingIntMathTask1, "IntMath1", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL );
106         xTaskCreate( vCompeteingIntMathTask2, "IntMath2", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL );
107         xTaskCreate( vCompeteingIntMathTask3, "IntMath3", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL );
108         xTaskCreate( vCompeteingIntMathTask4, "IntMath4", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL );
109         xTaskCreate( vCompeteingIntMathTask1, "IntMath5", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL );
110         xTaskCreate( vCompeteingIntMathTask2, "IntMath6", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL );
111         xTaskCreate( vCompeteingIntMathTask3, "IntMath7", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL );
112         xTaskCreate( vCompeteingIntMathTask4, "IntMath8", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL );
113 }
114 /*-----------------------------------------------------------*/
115
116 static void vCompeteingIntMathTask1( void *pvParameters )
117 {
118 portLONG l1, l2, l3, l4;
119 portSHORT sError = pdFALSE;
120 volatile unsigned portSHORT *pusTaskCheckVariable;
121 const portLONG lAnswer = ( ( portLONG ) 74565L + ( portLONG ) 1234567L ) * ( portLONG ) -918L;
122 const portCHAR * const pcTaskStartMsg = "Integer math task 1 started.\r\n";
123 const portCHAR * const pcTaskFailMsg = "Integer math task 1 failed.\r\n";
124
125         /* Queue a message for printing to say the task has started. */
126         vPrintDisplayMessage( &pcTaskStartMsg );
127
128         /* The variable this task increments to show it is still running is passed in
129         as the parameter. */
130         pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters;
131
132         /* Keep performing a calculation and checking the result against a constant. */
133         for(;;)
134         {
135                 l1 = ( portLONG ) 74565L;
136                 l2 = ( portLONG ) 1234567L;
137                 l3 = ( portLONG ) -918L;
138
139                 l4 = ( l1 + l2 ) * l3;
140
141                 taskYIELD();
142
143                 /* If the calculation does not match the expected constant, stop the
144                 increment of the check variable. */
145                 if( l4 != lAnswer )
146                 {
147                         vPrintDisplayMessage( &pcTaskFailMsg );
148                         sError = pdTRUE;
149                 }
150
151                 if( sError == pdFALSE )
152                 {
153                         /* If the calculation has always been correct, increment the check
154                         variable so we know     this task is still running okay. */
155                         ( *pusTaskCheckVariable )++;
156                 }
157         }
158 }
159 /*-----------------------------------------------------------*/
160
161 static void vCompeteingIntMathTask2( void *pvParameters )
162 {
163 portLONG l1, l2, l3, l4;
164 portSHORT sError = pdFALSE;
165 volatile unsigned portSHORT *pusTaskCheckVariable;
166 const portLONG lAnswer = ( ( portLONG ) -389000L / ( portLONG ) 329999L ) * ( portLONG ) -89L;
167 const portCHAR * const pcTaskStartMsg = "Integer math task 2 started.\r\n";
168 const portCHAR * const pcTaskFailMsg = "Integer math task 2 failed.\r\n";
169
170         /* Queue a message for printing to say the task has started. */
171         vPrintDisplayMessage( &pcTaskStartMsg );
172
173         /* The variable this task increments to show it is still running is passed in
174         as the parameter. */
175         pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters;
176
177         /* Keep performing a calculation and checking the result against a constant. */
178         for( ;; )
179         {
180                 l1 = -389000L;
181                 l2 = 329999L;
182                 l3 = -89L;
183
184                 l4 = ( l1 / l2 ) * l3;
185
186                 taskYIELD();
187
188                 /* If the calculation does not match the expected constant, stop the
189                 increment of the check variable. */
190                 if( l4 != lAnswer )
191                 {
192                         vPrintDisplayMessage( &pcTaskFailMsg );
193                         sError = pdTRUE;
194                 }
195
196                 if( sError == pdFALSE )
197                 {
198                         /* If the calculation has always been correct, increment the check
199                         variable so we know this task is still running okay. */
200                         ( *pusTaskCheckVariable )++;
201                 }
202         }
203 }
204 /*-----------------------------------------------------------*/
205
206 static void vCompeteingIntMathTask3( void *pvParameters )
207 {
208 portLONG *plArray, lTotal1, lTotal2;
209 portSHORT sError = pdFALSE;
210 volatile unsigned portSHORT *pusTaskCheckVariable;
211 const unsigned portSHORT usArraySize = ( unsigned portSHORT ) 250;
212 unsigned portSHORT usPosition;
213 const portCHAR * const pcTaskStartMsg = "Integer math task 3 started.\r\n";
214 const portCHAR * const pcTaskFailMsg = "Integer math task 3 failed.\r\n";
215
216         /* Queue a message for printing to say the task has started. */
217         vPrintDisplayMessage( &pcTaskStartMsg );
218
219         /* The variable this task increments to show it is still running is passed in
220         as the parameter. */
221         pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters;
222
223         /* Create the array we are going to use for our check calculation. */
224         plArray = ( portLONG * ) pvPortMalloc( ( size_t ) 250 * sizeof( portLONG ) );
225
226         /* Keep filling the array, keeping a running total of the values placed in the
227         array.  Then run through the array adding up all the values.  If the two totals
228         do not match, stop the check variable from incrementing. */
229         for( ;; )
230         {
231                 lTotal1 = ( portLONG ) 0;
232                 lTotal2 = ( portLONG ) 0;
233
234                 for( usPosition = 0; usPosition < usArraySize; usPosition++ )
235                 {
236                         plArray[ usPosition ] = ( portLONG ) usPosition + ( portLONG ) 5;
237                         lTotal1 += ( portLONG ) usPosition + ( portLONG ) 5;
238                 }
239
240                 taskYIELD();
241
242                 for( usPosition = 0; usPosition < usArraySize; usPosition++ )
243                 {
244                         lTotal2 += plArray[ usPosition ];
245                 }
246
247                 if( lTotal1 != lTotal2 )
248                 {
249                         vPrintDisplayMessage( &pcTaskFailMsg );
250                         sError = pdTRUE;
251                 }
252
253                 taskYIELD();
254
255                 if( sError == pdFALSE )
256                 {
257                         /* If the calculation has always been correct, increment the check
258                         variable so we know     this task is still running okay. */
259                         ( *pusTaskCheckVariable )++;
260                 }
261         }
262 }
263 /*-----------------------------------------------------------*/
264
265 static void vCompeteingIntMathTask4( void *pvParameters )
266 {
267 portLONG *plArray, lTotal1, lTotal2;
268 portSHORT sError = pdFALSE;
269 volatile unsigned portSHORT *pusTaskCheckVariable;
270 const unsigned portSHORT usArraySize = 250;
271 unsigned portSHORT usPosition;
272 const portCHAR * const pcTaskStartMsg = "Integer math task 4 started.\r\n";
273 const portCHAR * const pcTaskFailMsg = "Integer math task 4 failed.\r\n";
274
275         /* Queue a message for printing to say the task has started. */
276         vPrintDisplayMessage( &pcTaskStartMsg );
277
278         /* The variable this task increments to show it is still running is passed in
279         as the parameter. */
280         pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters;
281
282         /* Create the array we are going to use for our check calculation. */
283         plArray = ( portLONG * ) pvPortMalloc( ( size_t ) 250 * sizeof( portLONG ) );
284
285         /* Keep filling the array, keeping a running total of the values placed in the
286         array.  Then run through the array adding up all the values.  If the two totals
287         do not match, stop the check variable from incrementing. */
288         for( ;; )
289         {
290                 lTotal1 = ( portLONG ) 0;
291                 lTotal2 = ( portLONG ) 0;
292
293                 for( usPosition = 0; usPosition < usArraySize; usPosition++ )
294                 {
295                         plArray[ usPosition ] = ( portLONG ) usPosition * ( portLONG ) 12;
296                         lTotal1 += ( portLONG ) usPosition * ( portLONG ) 12;   
297                 }
298
299                 taskYIELD();
300        
301                 for( usPosition = 0; usPosition < usArraySize; usPosition++ )
302                 {
303                         lTotal2 += plArray[ usPosition ];
304                 }
305
306
307                 if( lTotal1 != lTotal2 )
308                 {
309                         vPrintDisplayMessage( &pcTaskFailMsg );
310                         sError = pdTRUE;
311                 }
312
313                 taskYIELD();
314
315                 if( sError == pdFALSE )
316                 {
317                         /* If the calculation has always been correct, increment the check
318                         variable so we know     this task is still running okay. */
319                         ( *pusTaskCheckVariable )++;
320                 }
321         }
322 }
323 /*-----------------------------------------------------------*/
324
325 /* This is called to check that all the created tasks are still running. */
326 portBASE_TYPE xAreIntegerMathsTaskStillRunning( void )
327 {
328 /* Keep a history of the check variables so we know if they have been incremented
329 since the last call. */
330 static unsigned portSHORT usLastTaskCheck[ intgNUMBER_OF_TASKS ] = { ( unsigned portSHORT ) 0 };
331 portBASE_TYPE xReturn = pdTRUE, xTask;
332
333         /* Check the maths tasks are still running by ensuring their check variables
334         are still incrementing. */
335         for( xTask = 0; xTask < intgNUMBER_OF_TASKS; xTask++ )
336         {
337                 if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] )
338                 {
339                         /* The check has not incremented so an error exists. */
340                         xReturn = pdFALSE;
341                 }
342
343                 usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ];
344         }
345
346         return xReturn;
347 }
Note: See TracBrowser for help on using the browser.