]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_R4_RM48_TMS570_CCS5/flop_hercules.c
Make loop counters in flop_hercules.c 32-bit instead of 16-bit.
[freertos] / FreeRTOS / Demo / CORTEX_R4_RM48_TMS570_CCS5 / flop_hercules.c
1 /*\r
2     FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
3 \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
6 \r
7     ***************************************************************************\r
8      *                                                                       *\r
9      *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
10      *    Complete, revised, and edited pdf reference manuals are also       *\r
11      *    available.                                                         *\r
12      *                                                                       *\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
19      *                                                                       *\r
20      *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
21      *                                                                       *\r
22      *    Thank you for using FreeRTOS, and thank you for your support!      *\r
23      *                                                                       *\r
24     ***************************************************************************\r
25 \r
26 \r
27     This file is part of the FreeRTOS distribution.\r
28 \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
42     FreeRTOS WEB site.\r
43 \r
44     1 tab == 4 spaces!\r
45     \r
46     ***************************************************************************\r
47      *                                                                       *\r
48      *    Having a problem?  Start by reading the FAQ "My application does   *\r
49      *    not run, what could be wrong?"                                     *\r
50      *                                                                       *\r
51      *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
52      *                                                                       *\r
53     ***************************************************************************\r
54 \r
55     \r
56     http://www.FreeRTOS.org - Documentation, training, latest versions, license \r
57     and contact details.  \r
58     \r
59     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
60     including FreeRTOS+Trace - an indispensable productivity tool.\r
61 \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
67 */\r
68 \r
69 /*\r
70  * Creates eight tasks, each of which loops continuously performing an (emulated) \r
71  * floating point calculation.\r
72  *\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
80  */\r
81 \r
82 #include <stdlib.h>\r
83 #include <math.h>\r
84 \r
85 /* Scheduler include files. */\r
86 #include "FreeRTOS.h"\r
87 #include "task.h"\r
88 \r
89 /* Demo program include files. */\r
90 #include "flop.h"\r
91 \r
92 #define mathSTACK_SIZE          configMINIMAL_STACK_SIZE\r
93 #define mathNUMBER_OF_TASKS  ( 8 )\r
94 \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
101 \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 long ulTaskCheck[ mathNUMBER_OF_TASKS ] = { 0 };\r
106 \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
112 #endif\r
113 \r
114 /*-----------------------------------------------------------*/\r
115 \r
116 void vStartMathTasks( unsigned portBASE_TYPE uxPriority )\r
117 {\r
118         xTaskCreate( vCompetingMathTask1, ( signed char * ) "Math1", mathSTACK_SIZE, ( void * ) &( ulTaskCheck[ 0 ] ), uxPriority, NULL );\r
119         xTaskCreate( vCompetingMathTask2, ( signed char * ) "Math2", mathSTACK_SIZE, ( void * ) &( ulTaskCheck[ 1 ] ), uxPriority, NULL );\r
120         xTaskCreate( vCompetingMathTask3, ( signed char * ) "Math3", mathSTACK_SIZE, ( void * ) &( ulTaskCheck[ 2 ] ), uxPriority, NULL );\r
121         xTaskCreate( vCompetingMathTask4, ( signed char * ) "Math4", mathSTACK_SIZE, ( void * ) &( ulTaskCheck[ 3 ] ), uxPriority, NULL );\r
122         xTaskCreate( vCompetingMathTask1, ( signed char * ) "Math5", mathSTACK_SIZE, ( void * ) &( ulTaskCheck[ 4 ] ), uxPriority, NULL );\r
123         xTaskCreate( vCompetingMathTask2, ( signed char * ) "Math6", mathSTACK_SIZE, ( void * ) &( ulTaskCheck[ 5 ] ), uxPriority, NULL );\r
124         xTaskCreate( vCompetingMathTask3, ( signed char * ) "Math7", mathSTACK_SIZE, ( void * ) &( ulTaskCheck[ 6 ] ), uxPriority, NULL );\r
125         xTaskCreate( vCompetingMathTask4, ( signed char * ) "Math8", mathSTACK_SIZE, ( void * ) &( ulTaskCheck[ 7 ] ), uxPriority, NULL );\r
126 }\r
127 /*-----------------------------------------------------------*/\r
128 \r
129 static portTASK_FUNCTION( vCompetingMathTask1, pvParameters )\r
130 {\r
131 volatile portDOUBLE d1, d2, d3, d4;\r
132 volatile unsigned long *pulTaskCheckVariable;\r
133 volatile portDOUBLE dAnswer;\r
134 short sError = pdFALSE;\r
135 \r
136 \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
142         #endif\r
143 \r
144         d1 = 123.4567;\r
145         d2 = 2345.6789;\r
146         d3 = -918.222;\r
147 \r
148         dAnswer = ( d1 + d2 ) * d3;\r
149 \r
150         /* The variable this task increments to show it is still running is passed in \r
151         as the parameter. */\r
152         pulTaskCheckVariable = ( unsigned long * ) pvParameters;\r
153 \r
154         /* Keep performing a calculation and checking the result against a constant. */\r
155         for(;;)\r
156         {\r
157                 d1 = 123.4567;\r
158                 d2 = 2345.6789;\r
159                 d3 = -918.222;\r
160 \r
161                 d4 = ( d1 + d2 ) * d3;\r
162 \r
163                 #if configUSE_PREEMPTION == 0\r
164                         taskYIELD();\r
165                 #endif\r
166 \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
170                 {\r
171                         sError = pdTRUE;\r
172                 }\r
173 \r
174                 if( sError == pdFALSE )\r
175                 {\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                         ( *pulTaskCheckVariable )++;\r
179                 }\r
180 \r
181                 #if configUSE_PREEMPTION == 0\r
182                         taskYIELD();\r
183                 #endif\r
184 \r
185         }\r
186 }\r
187 /*-----------------------------------------------------------*/\r
188 \r
189 static portTASK_FUNCTION( vCompetingMathTask2, pvParameters )\r
190 {\r
191 volatile portDOUBLE d1, d2, d3, d4;\r
192 volatile unsigned long *pulTaskCheckVariable;\r
193 volatile portDOUBLE dAnswer;\r
194 short sError = pdFALSE;\r
195 \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
201         #endif\r
202 \r
203         d1 = -389.38;\r
204         d2 = 32498.2;\r
205         d3 = -2.0001;\r
206 \r
207         dAnswer = ( d1 / d2 ) * d3;\r
208 \r
209 \r
210         /* The variable this task increments to show it is still running is passed in \r
211         as the parameter. */\r
212         pulTaskCheckVariable = ( unsigned long * ) pvParameters;\r
213 \r
214         /* Keep performing a calculation and checking the result against a constant. */\r
215         for( ;; )\r
216         {\r
217                 d1 = -389.38;\r
218                 d2 = 32498.2;\r
219                 d3 = -2.0001;\r
220 \r
221                 d4 = ( d1 / d2 ) * d3;\r
222 \r
223                 #if configUSE_PREEMPTION == 0\r
224                         taskYIELD();\r
225                 #endif\r
226                 \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
230                 {\r
231                         sError = pdTRUE;\r
232                 }\r
233 \r
234                 if( sError == pdFALSE )\r
235                 {\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                         ( *pulTaskCheckVariable )++;\r
240                 }\r
241 \r
242                 #if configUSE_PREEMPTION == 0\r
243                         taskYIELD();\r
244                 #endif\r
245         }\r
246 }\r
247 /*-----------------------------------------------------------*/\r
248 \r
249 static portTASK_FUNCTION( vCompetingMathTask3, pvParameters )\r
250 {\r
251 volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;\r
252 volatile unsigned long *pulTaskCheckVariable;\r
253 const size_t xArraySize = 10;\r
254 size_t xPosition;\r
255 short sError = pdFALSE;\r
256 \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
262         #endif\r
263 \r
264         /* The variable this task increments to show it is still running is passed in \r
265         as the parameter. */\r
266         pulTaskCheckVariable = ( unsigned long * ) pvParameters;\r
267 \r
268         pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) );\r
269 \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
273         for( ;; )\r
274         {\r
275                 dTotal1 = 0.0;\r
276                 dTotal2 = 0.0;\r
277 \r
278                 for( xPosition = 0; xPosition < xArraySize; xPosition++ )\r
279                 {\r
280                         pdArray[ xPosition ] = ( portDOUBLE ) xPosition + 5.5;\r
281                         dTotal1 += ( portDOUBLE ) xPosition + 5.5;      \r
282                 }\r
283 \r
284                 #if configUSE_PREEMPTION == 0\r
285                         taskYIELD();\r
286                 #endif\r
287 \r
288                 for( xPosition = 0; xPosition < xArraySize; xPosition++ )\r
289                 {\r
290                         dTotal2 += pdArray[ xPosition ];\r
291                 }\r
292 \r
293                 dDifference = dTotal1 - dTotal2;\r
294                 if( fabs( dDifference ) > 0.001 )\r
295                 {\r
296                         sError = pdTRUE;\r
297                 }\r
298 \r
299                 #if configUSE_PREEMPTION == 0\r
300                         taskYIELD();\r
301                 #endif\r
302 \r
303                 if( sError == pdFALSE )\r
304                 {\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                         ( *pulTaskCheckVariable )++;\r
308                 }\r
309         }\r
310 }\r
311 /*-----------------------------------------------------------*/\r
312 \r
313 static portTASK_FUNCTION( vCompetingMathTask4, pvParameters )\r
314 {\r
315 volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;\r
316 volatile unsigned long *pulTaskCheckVariable;\r
317 const size_t xArraySize = 10;\r
318 size_t xPosition;\r
319 short sError = pdFALSE;\r
320 \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
326         #endif\r
327 \r
328         /* The variable this task increments to show it is still running is passed in \r
329         as the parameter. */\r
330         pulTaskCheckVariable = ( unsigned long * ) pvParameters;\r
331 \r
332         pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) );\r
333 \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
337         for( ;; )\r
338         {\r
339                 dTotal1 = 0.0;\r
340                 dTotal2 = 0.0;\r
341 \r
342                 for( xPosition = 0; xPosition < xArraySize; xPosition++ )\r
343                 {\r
344                         pdArray[ xPosition ] = ( portDOUBLE ) xPosition * 12.123;\r
345                         dTotal1 += ( portDOUBLE ) xPosition * 12.123;   \r
346                 }\r
347 \r
348                 #if configUSE_PREEMPTION == 0\r
349                         taskYIELD();\r
350                 #endif\r
351 \r
352                 for( xPosition = 0; xPosition < xArraySize; xPosition++ )\r
353                 {\r
354                         dTotal2 += pdArray[ xPosition ];\r
355                 }\r
356 \r
357                 dDifference = dTotal1 - dTotal2;\r
358                 if( fabs( dDifference ) > 0.001 )\r
359                 {\r
360                         sError = pdTRUE;\r
361                 }\r
362 \r
363                 #if configUSE_PREEMPTION == 0\r
364                         taskYIELD();\r
365                 #endif\r
366 \r
367                 if( sError == pdFALSE )\r
368                 {\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                         ( *pulTaskCheckVariable )++;\r
372                 }\r
373         }\r
374 }                                \r
375 /*-----------------------------------------------------------*/\r
376 \r
377 /* This is called to check that all the created tasks are still running. */\r
378 portBASE_TYPE xAreMathsTaskStillRunning( void )\r
379 {\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 long ulLastTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };\r
383 portBASE_TYPE xReturn = pdTRUE, xTask;\r
384 \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
388         {\r
389                 if( ulTaskCheck[ xTask ] == ulLastTaskCheck[ xTask ] )\r
390                 {\r
391                         /* The check has not incremented so an error exists. */\r
392                         xReturn = pdFALSE;\r
393                 }\r
394 \r
395                 ulLastTaskCheck[ xTask ] = ulTaskCheck[ xTask ];\r
396         }\r
397 \r
398         return xReturn;\r
399 }\r
400 \r
401 \r
402 \r