]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_R4_RM48_TMS570_CCS5/flop_hercules.c
1eae2c6ea40d1dcff0149df0c87387bf17f8474f
[freertos] / FreeRTOS / Demo / CORTEX_R4_RM48_TMS570_CCS5 / flop_hercules.c
1 /*\r
2     FreeRTOS V7.5.0 - Copyright (C) 2013 Real Time Engineers Ltd.\r
3 \r
4     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
5 \r
6     ***************************************************************************\r
7      *                                                                       *\r
8      *    FreeRTOS provides completely free yet professionally developed,    *\r
9      *    robust, strictly quality controlled, supported, and cross          *\r
10      *    platform software that has become a de facto standard.             *\r
11      *                                                                       *\r
12      *    Help yourself get started quickly and support the FreeRTOS         *\r
13      *    project by purchasing a FreeRTOS tutorial book, reference          *\r
14      *    manual, or both from: http://www.FreeRTOS.org/Documentation        *\r
15      *                                                                       *\r
16      *    Thank you!                                                         *\r
17      *                                                                       *\r
18     ***************************************************************************\r
19 \r
20     This file is part of the FreeRTOS distribution.\r
21 \r
22     FreeRTOS is free software; you can redistribute it and/or modify it under\r
23     the terms of the GNU General Public License (version 2) as published by the\r
24     Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
25 \r
26     >>! NOTE: The modification to the GPL is included to allow you to distribute\r
27     >>! a combined work that includes FreeRTOS without being obliged to provide\r
28     >>! the source code for proprietary components outside of the FreeRTOS\r
29     >>! kernel.\r
30 \r
31     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
32     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
33     FOR A PARTICULAR PURPOSE.  Full license text is available from the following\r
34     link: http://www.freertos.org/a00114.html\r
35 \r
36     1 tab == 4 spaces!\r
37 \r
38     ***************************************************************************\r
39      *                                                                       *\r
40      *    Having a problem?  Start by reading the FAQ "My application does   *\r
41      *    not run, what could be wrong?"                                     *\r
42      *                                                                       *\r
43      *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
44      *                                                                       *\r
45     ***************************************************************************\r
46 \r
47     http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
48     license and Real Time Engineers Ltd. contact details.\r
49 \r
50     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
51     including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
52     compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
53 \r
54     http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
55     Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
56     licenses offer ticketed support, indemnification and middleware.\r
57 \r
58     http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
59     engineered and independently SIL3 certified version for use in safety and\r
60     mission critical applications that require provable dependability.\r
61 \r
62     1 tab == 4 spaces!\r
63 */\r
64 \r
65 /*\r
66  * Creates eight tasks, each of which loops continuously performing an (emulated) \r
67  * floating point calculation.\r
68  *\r
69  * All the tasks run at the idle priority and never block or yield.  This causes \r
70  * all eight tasks to time slice with the idle task.  Running at the idle priority \r
71  * means that these tasks will get pre-empted any time another task is ready to run\r
72  * or a time slice occurs.  More often than not the pre-emption will occur mid \r
73  * calculation, creating a good test of the schedulers context switch mechanism - a \r
74  * calculation producing an unexpected result could be a symptom of a corruption in \r
75  * the context of a task.\r
76  */\r
77 \r
78 #include <stdlib.h>\r
79 #include <math.h>\r
80 \r
81 /* Scheduler include files. */\r
82 #include "FreeRTOS.h"\r
83 #include "task.h"\r
84 \r
85 /* Demo program include files. */\r
86 #include "flop.h"\r
87 \r
88 #define mathSTACK_SIZE          configMINIMAL_STACK_SIZE\r
89 #define mathNUMBER_OF_TASKS  ( 8 )\r
90 \r
91 /* Four tasks, each of which performs a different floating point calculation.  \r
92 Each of the four is created twice. */\r
93 static portTASK_FUNCTION_PROTO( vCompetingMathTask1, pvParameters );\r
94 static portTASK_FUNCTION_PROTO( vCompetingMathTask2, pvParameters );\r
95 static portTASK_FUNCTION_PROTO( vCompetingMathTask3, pvParameters );\r
96 static portTASK_FUNCTION_PROTO( vCompetingMathTask4, pvParameters );\r
97 \r
98 /* These variables are used to check that all the tasks are still running.  If a \r
99 task gets a calculation wrong it will\r
100 stop incrementing its check variable. */\r
101 static volatile unsigned long ulTaskCheck[ mathNUMBER_OF_TASKS ] = { 0 };\r
102 \r
103 /* Must be called before any hardware floating point operations are\r
104 performed to let the RTOS portable layer know that this task requires\r
105 a floating point context. */\r
106 #if __TI_VFP_SUPPORT__\r
107         extern void vPortTaskUsesFPU( void );\r
108 #endif\r
109 \r
110 /*-----------------------------------------------------------*/\r
111 \r
112 void vStartMathTasks( unsigned portBASE_TYPE uxPriority )\r
113 {\r
114         xTaskCreate( vCompetingMathTask1, ( signed char * ) "Math1", mathSTACK_SIZE, ( void * ) &( ulTaskCheck[ 0 ] ), uxPriority, NULL );\r
115         xTaskCreate( vCompetingMathTask2, ( signed char * ) "Math2", mathSTACK_SIZE, ( void * ) &( ulTaskCheck[ 1 ] ), uxPriority, NULL );\r
116         xTaskCreate( vCompetingMathTask3, ( signed char * ) "Math3", mathSTACK_SIZE, ( void * ) &( ulTaskCheck[ 2 ] ), uxPriority, NULL );\r
117         xTaskCreate( vCompetingMathTask4, ( signed char * ) "Math4", mathSTACK_SIZE, ( void * ) &( ulTaskCheck[ 3 ] ), uxPriority, NULL );\r
118         xTaskCreate( vCompetingMathTask1, ( signed char * ) "Math5", mathSTACK_SIZE, ( void * ) &( ulTaskCheck[ 4 ] ), uxPriority, NULL );\r
119         xTaskCreate( vCompetingMathTask2, ( signed char * ) "Math6", mathSTACK_SIZE, ( void * ) &( ulTaskCheck[ 5 ] ), uxPriority, NULL );\r
120         xTaskCreate( vCompetingMathTask3, ( signed char * ) "Math7", mathSTACK_SIZE, ( void * ) &( ulTaskCheck[ 6 ] ), uxPriority, NULL );\r
121         xTaskCreate( vCompetingMathTask4, ( signed char * ) "Math8", mathSTACK_SIZE, ( void * ) &( ulTaskCheck[ 7 ] ), uxPriority, NULL );\r
122 }\r
123 /*-----------------------------------------------------------*/\r
124 \r
125 static portTASK_FUNCTION( vCompetingMathTask1, pvParameters )\r
126 {\r
127 volatile portDOUBLE d1, d2, d3, d4;\r
128 volatile unsigned long *pulTaskCheckVariable;\r
129 volatile portDOUBLE dAnswer;\r
130 short sError = pdFALSE;\r
131 \r
132 \r
133         /* Must be called before any hardware floating point operations are\r
134         performed to let the RTOS portable layer know that this task requires\r
135         a floating point context. */\r
136         #if __TI_VFP_SUPPORT__\r
137                 vPortTaskUsesFPU();\r
138         #endif\r
139 \r
140         d1 = 123.4567;\r
141         d2 = 2345.6789;\r
142         d3 = -918.222;\r
143 \r
144         dAnswer = ( d1 + d2 ) * d3;\r
145 \r
146         /* The variable this task increments to show it is still running is passed in \r
147         as the parameter. */\r
148         pulTaskCheckVariable = ( unsigned long * ) pvParameters;\r
149 \r
150         /* Keep performing a calculation and checking the result against a constant. */\r
151         for(;;)\r
152         {\r
153                 d1 = 123.4567;\r
154                 d2 = 2345.6789;\r
155                 d3 = -918.222;\r
156 \r
157                 d4 = ( d1 + d2 ) * d3;\r
158 \r
159                 #if configUSE_PREEMPTION == 0\r
160                         taskYIELD();\r
161                 #endif\r
162 \r
163                 /* If the calculation does not match the expected constant, stop the \r
164                 increment of the check variable. */\r
165                 if( fabs( d4 - dAnswer ) > 0.001 )\r
166                 {\r
167                         sError = pdTRUE;\r
168                 }\r
169 \r
170                 if( sError == pdFALSE )\r
171                 {\r
172                         /* If the calculation has always been correct, increment the check \r
173                         variable so we know this task is still running okay. */\r
174                         ( *pulTaskCheckVariable )++;\r
175                 }\r
176 \r
177                 #if configUSE_PREEMPTION == 0\r
178                         taskYIELD();\r
179                 #endif\r
180 \r
181         }\r
182 }\r
183 /*-----------------------------------------------------------*/\r
184 \r
185 static portTASK_FUNCTION( vCompetingMathTask2, pvParameters )\r
186 {\r
187 volatile portDOUBLE d1, d2, d3, d4;\r
188 volatile unsigned long *pulTaskCheckVariable;\r
189 volatile portDOUBLE dAnswer;\r
190 short sError = pdFALSE;\r
191 \r
192         /* Must be called before any hardware floating point operations are\r
193         performed to let the RTOS portable layer know that this task requires\r
194         a floating point context. */\r
195         #if __TI_VFP_SUPPORT__\r
196                 vPortTaskUsesFPU();\r
197         #endif\r
198 \r
199         d1 = -389.38;\r
200         d2 = 32498.2;\r
201         d3 = -2.0001;\r
202 \r
203         dAnswer = ( d1 / d2 ) * d3;\r
204 \r
205 \r
206         /* The variable this task increments to show it is still running is passed in \r
207         as the parameter. */\r
208         pulTaskCheckVariable = ( unsigned long * ) pvParameters;\r
209 \r
210         /* Keep performing a calculation and checking the result against a constant. */\r
211         for( ;; )\r
212         {\r
213                 d1 = -389.38;\r
214                 d2 = 32498.2;\r
215                 d3 = -2.0001;\r
216 \r
217                 d4 = ( d1 / d2 ) * d3;\r
218 \r
219                 #if configUSE_PREEMPTION == 0\r
220                         taskYIELD();\r
221                 #endif\r
222                 \r
223                 /* If the calculation does not match the expected constant, stop the \r
224                 increment of the check variable. */\r
225                 if( fabs( d4 - dAnswer ) > 0.001 )\r
226                 {\r
227                         sError = pdTRUE;\r
228                 }\r
229 \r
230                 if( sError == pdFALSE )\r
231                 {\r
232                         /* If the calculation has always been correct, increment the check \r
233                         variable so we know\r
234                         this task is still running okay. */\r
235                         ( *pulTaskCheckVariable )++;\r
236                 }\r
237 \r
238                 #if configUSE_PREEMPTION == 0\r
239                         taskYIELD();\r
240                 #endif\r
241         }\r
242 }\r
243 /*-----------------------------------------------------------*/\r
244 \r
245 static portTASK_FUNCTION( vCompetingMathTask3, pvParameters )\r
246 {\r
247 volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;\r
248 volatile unsigned long *pulTaskCheckVariable;\r
249 const size_t xArraySize = 10;\r
250 size_t xPosition;\r
251 short sError = pdFALSE;\r
252 \r
253         /* Must be called before any hardware floating point operations are\r
254         performed to let the RTOS portable layer know that this task requires\r
255         a floating point context. */\r
256         #if __TI_VFP_SUPPORT__\r
257                 vPortTaskUsesFPU();\r
258         #endif\r
259 \r
260         /* The variable this task increments to show it is still running is passed in \r
261         as the parameter. */\r
262         pulTaskCheckVariable = ( unsigned long * ) pvParameters;\r
263 \r
264         pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) );\r
265 \r
266         /* Keep filling an array, keeping a running total of the values placed in the \r
267         array.  Then run through the array adding up all the values.  If the two totals \r
268         do not match, stop the check variable from incrementing. */\r
269         for( ;; )\r
270         {\r
271                 dTotal1 = 0.0;\r
272                 dTotal2 = 0.0;\r
273 \r
274                 for( xPosition = 0; xPosition < xArraySize; xPosition++ )\r
275                 {\r
276                         pdArray[ xPosition ] = ( portDOUBLE ) xPosition + 5.5;\r
277                         dTotal1 += ( portDOUBLE ) xPosition + 5.5;      \r
278                 }\r
279 \r
280                 #if configUSE_PREEMPTION == 0\r
281                         taskYIELD();\r
282                 #endif\r
283 \r
284                 for( xPosition = 0; xPosition < xArraySize; xPosition++ )\r
285                 {\r
286                         dTotal2 += pdArray[ xPosition ];\r
287                 }\r
288 \r
289                 dDifference = dTotal1 - dTotal2;\r
290                 if( fabs( dDifference ) > 0.001 )\r
291                 {\r
292                         sError = pdTRUE;\r
293                 }\r
294 \r
295                 #if configUSE_PREEMPTION == 0\r
296                         taskYIELD();\r
297                 #endif\r
298 \r
299                 if( sError == pdFALSE )\r
300                 {\r
301                         /* If the calculation has always been correct, increment the check \r
302                         variable so we know     this task is still running okay. */\r
303                         ( *pulTaskCheckVariable )++;\r
304                 }\r
305         }\r
306 }\r
307 /*-----------------------------------------------------------*/\r
308 \r
309 static portTASK_FUNCTION( vCompetingMathTask4, pvParameters )\r
310 {\r
311 volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;\r
312 volatile unsigned long *pulTaskCheckVariable;\r
313 const size_t xArraySize = 10;\r
314 size_t xPosition;\r
315 short sError = pdFALSE;\r
316 \r
317         /* Must be called before any hardware floating point operations are\r
318         performed to let the RTOS portable layer know that this task requires\r
319         a floating point context. */\r
320         #if __TI_VFP_SUPPORT__\r
321                 vPortTaskUsesFPU();\r
322         #endif\r
323 \r
324         /* The variable this task increments to show it is still running is passed in \r
325         as the parameter. */\r
326         pulTaskCheckVariable = ( unsigned long * ) pvParameters;\r
327 \r
328         pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) );\r
329 \r
330         /* Keep filling an array, keeping a running total of the values placed in the \r
331         array.  Then run through the array adding up all the values.  If the two totals \r
332         do not match, stop the check variable from incrementing. */\r
333         for( ;; )\r
334         {\r
335                 dTotal1 = 0.0;\r
336                 dTotal2 = 0.0;\r
337 \r
338                 for( xPosition = 0; xPosition < xArraySize; xPosition++ )\r
339                 {\r
340                         pdArray[ xPosition ] = ( portDOUBLE ) xPosition * 12.123;\r
341                         dTotal1 += ( portDOUBLE ) xPosition * 12.123;   \r
342                 }\r
343 \r
344                 #if configUSE_PREEMPTION == 0\r
345                         taskYIELD();\r
346                 #endif\r
347 \r
348                 for( xPosition = 0; xPosition < xArraySize; xPosition++ )\r
349                 {\r
350                         dTotal2 += pdArray[ xPosition ];\r
351                 }\r
352 \r
353                 dDifference = dTotal1 - dTotal2;\r
354                 if( fabs( dDifference ) > 0.001 )\r
355                 {\r
356                         sError = pdTRUE;\r
357                 }\r
358 \r
359                 #if configUSE_PREEMPTION == 0\r
360                         taskYIELD();\r
361                 #endif\r
362 \r
363                 if( sError == pdFALSE )\r
364                 {\r
365                         /* If the calculation has always been correct, increment the check \r
366                         variable so we know     this task is still running okay. */\r
367                         ( *pulTaskCheckVariable )++;\r
368                 }\r
369         }\r
370 }                                \r
371 /*-----------------------------------------------------------*/\r
372 \r
373 /* This is called to check that all the created tasks are still running. */\r
374 portBASE_TYPE xAreMathsTaskStillRunning( void )\r
375 {\r
376 /* Keep a history of the check variables so we know if they have been incremented \r
377 since the last call. */\r
378 static unsigned long ulLastTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };\r
379 portBASE_TYPE xReturn = pdTRUE, xTask;\r
380 \r
381         /* Check the maths tasks are still running by ensuring their check variables \r
382         are still incrementing. */\r
383         for( xTask = 0; xTask < mathNUMBER_OF_TASKS; xTask++ )\r
384         {\r
385                 if( ulTaskCheck[ xTask ] == ulLastTaskCheck[ xTask ] )\r
386                 {\r
387                         /* The check has not incremented so an error exists. */\r
388                         xReturn = pdFALSE;\r
389                 }\r
390 \r
391                 ulLastTaskCheck[ xTask ] = ulTaskCheck[ xTask ];\r
392         }\r
393 \r
394         return xReturn;\r
395 }\r
396 \r
397 \r
398 \r