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