]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/SuperH_SH7216_Renesas/RTOSDemo/flop.c
Update to MIT licensed FreeRTOS V10.0.0 - see https://www.freertos.org/History.txt
[freertos] / FreeRTOS / Demo / SuperH_SH7216_Renesas / RTOSDemo / flop.c
1 /*\r
2  * FreeRTOS Kernel V10.0.0\r
3  * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software. If you wish to use our Amazon\r
14  * FreeRTOS name, please do so in a fair use way that does not cause confusion.\r
15  *\r
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
18  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
19  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
22  *\r
23  * http://www.FreeRTOS.org\r
24  * http://aws.amazon.com/freertos\r
25  *\r
26  * 1 tab == 4 spaces!\r
27  */\r
28 \r
29 /*\r
30  * Creates eight tasks, each of which loops continuously performing a floating \r
31  * point calculation and in so doing test the floating point context switching.\r
32  * This file also demonstrates the use of the xPortUsesFloatingPoint() function\r
33  * which informs the kernel that the task requires its floating point context\r
34  * saved on each switch.\r
35  *\r
36  * All the tasks run at the idle priority and never block or yield.  This causes \r
37  * all eight tasks to time slice with the idle task.  Running at the idle \r
38  * priority means that these tasks will get pre-empted any time another task is \r
39  * ready to run or a time slice occurs.  More often than not the pre-emption \r
40  * will occur mid calculation, creating a good test of the schedulers context \r
41  * switch mechanism - a calculation producing an unexpected result could be a \r
42  * symptom of a corruption in the context of a task.\r
43  */\r
44 \r
45 #include <stdlib.h>\r
46 #include <math.h>\r
47 \r
48 /* Scheduler include files. */\r
49 #include "FreeRTOS.h"\r
50 #include "task.h"\r
51 \r
52 /* Demo program include files. */\r
53 #include "flop.h"\r
54 \r
55 #define mathSTACK_SIZE          configMINIMAL_STACK_SIZE\r
56 #define mathNUMBER_OF_TASKS  ( 8 )\r
57 \r
58 /* Four tasks, each of which performs a different floating point calculation.  \r
59 Each of the four is created twice. */\r
60 static void vCompetingMathTask1( void *pvParameters );\r
61 static void vCompetingMathTask2( void *pvParameters );\r
62 static void vCompetingMathTask3( void *pvParameters );\r
63 static void vCompetingMathTask4( void *pvParameters );\r
64 \r
65 /* These variables are used to check that all the tasks are still running.  If a \r
66 task gets a calculation wrong it will stop incrementing its check variable,\r
67 otherwise the check variable will get incremented on each iteration of the \r
68 tasks execution. */\r
69 static volatile unsigned short usTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };\r
70 \r
71 /*-----------------------------------------------------------*/\r
72 \r
73 void vStartMathTasks( unsigned portBASE_TYPE uxPriority )\r
74 {\r
75 TaskHandle_t xCreatedTask;\r
76 \r
77         /* Create one of the floating point tasks... */\r
78         xTaskCreate( vCompetingMathTask1, "Math1", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, &xCreatedTask );\r
79         \r
80         /* ... then enable floating point support for the created task so its flop\r
81         flop registers are maintained in a consistent state. */\r
82         xPortUsesFloatingPoint( xCreatedTask );\r
83 \r
84         xTaskCreate( vCompetingMathTask2, "Math2", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, &xCreatedTask );\r
85         xPortUsesFloatingPoint( xCreatedTask );\r
86         \r
87         xTaskCreate( vCompetingMathTask3, "Math3", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, &xCreatedTask );\r
88         xPortUsesFloatingPoint( xCreatedTask );\r
89         \r
90         xTaskCreate( vCompetingMathTask4, "Math4", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, &xCreatedTask );\r
91         xPortUsesFloatingPoint( xCreatedTask );\r
92         \r
93         xTaskCreate( vCompetingMathTask1, "Math5", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, &xCreatedTask );\r
94         xPortUsesFloatingPoint( xCreatedTask );\r
95         \r
96         xTaskCreate( vCompetingMathTask2, "Math6", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, &xCreatedTask );\r
97         xPortUsesFloatingPoint( xCreatedTask );\r
98         \r
99         xTaskCreate( vCompetingMathTask3, "Math7", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, &xCreatedTask );\r
100         xPortUsesFloatingPoint( xCreatedTask );\r
101         \r
102         xTaskCreate( vCompetingMathTask4, "Math8", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, &xCreatedTask );\r
103         xPortUsesFloatingPoint( xCreatedTask );\r
104 }\r
105 /*-----------------------------------------------------------*/\r
106 \r
107 static void vCompetingMathTask1( void *pvParameters )\r
108 {\r
109 volatile double d1, d2, d3, d4;\r
110 volatile unsigned short *pusTaskCheckVariable;\r
111 volatile double dAnswer;\r
112 short sError = pdFALSE;\r
113 \r
114         d1 = 123.4567;\r
115         d2 = 2345.6789;\r
116         d3 = -918.222;\r
117 \r
118         /* Calculate the expected answer. */\r
119         dAnswer = ( d1 + d2 ) * d3;\r
120 \r
121         /* The variable this task increments to show it is still running is passed in \r
122         as the parameter. */\r
123         pusTaskCheckVariable = ( unsigned short * ) pvParameters;\r
124 \r
125         /* Keep performing a calculation and checking the result against a constant. */\r
126         for(;;)\r
127         {\r
128                 /* Perform the calculation. */\r
129                 d1 = 123.4567;\r
130                 d2 = 2345.6789;\r
131                 d3 = -918.222;\r
132 \r
133                 d4 = ( d1 + d2 ) * d3;\r
134 \r
135                 /* If the calculation does not match the expected constant, stop the \r
136                 increment of the check variable. */\r
137                 if( fabs( d4 - dAnswer ) > 0.001 )\r
138                 {\r
139                         sError = pdTRUE;\r
140                 }\r
141 \r
142                 if( sError == pdFALSE )\r
143                 {\r
144                         /* If the calculation has always been correct, increment the check \r
145                         variable so we know this task is still running okay. */\r
146                         ( *pusTaskCheckVariable )++;\r
147                 }\r
148         }\r
149 }\r
150 /*-----------------------------------------------------------*/\r
151 \r
152 static void vCompetingMathTask2( void *pvParameters )\r
153 {\r
154 volatile double d1, d2, d3, d4;\r
155 volatile unsigned short *pusTaskCheckVariable;\r
156 volatile double dAnswer;\r
157 short sError = pdFALSE;\r
158 \r
159         d1 = -389.38;\r
160         d2 = 32498.2;\r
161         d3 = -2.0001;\r
162 \r
163         /* Calculate the expected answer. */\r
164         dAnswer = ( d1 / d2 ) * d3;\r
165 \r
166 \r
167         /* The variable this task increments to show it is still running is passed in \r
168         as the parameter. */\r
169         pusTaskCheckVariable = ( unsigned short * ) pvParameters;\r
170 \r
171         /* Keep performing a calculation and checking the result against a constant. */\r
172         for( ;; )\r
173         {\r
174                 /* Perform the calculation. */\r
175                 d1 = -389.38;\r
176                 d2 = 32498.2;\r
177                 d3 = -2.0001;\r
178 \r
179                 d4 = ( d1 / d2 ) * d3;\r
180 \r
181                 /* If the calculation does not match the expected constant, stop the \r
182                 increment of the check variable. */\r
183                 if( fabs( d4 - dAnswer ) > 0.001 )\r
184                 {\r
185                         sError = pdTRUE;\r
186                 }\r
187 \r
188                 if( sError == pdFALSE )\r
189                 {\r
190                         /* If the calculation has always been correct, increment the check \r
191                         variable so we know\r
192                         this task is still running okay. */\r
193                         ( *pusTaskCheckVariable )++;\r
194                 }\r
195         }\r
196 }\r
197 /*-----------------------------------------------------------*/\r
198 \r
199 static void vCompetingMathTask3( void *pvParameters )\r
200 {\r
201 volatile double *pdArray, dTotal1, dTotal2, dDifference;\r
202 volatile unsigned short *pusTaskCheckVariable;\r
203 const size_t xArraySize = 10;\r
204 size_t xPosition;\r
205 short sError = pdFALSE;\r
206 \r
207         /* The variable this task increments to show it is still running is passed \r
208         in as the parameter. */\r
209         pusTaskCheckVariable = ( unsigned short * ) pvParameters;\r
210 \r
211         /* Allocate memory for use as an array. */\r
212         pdArray = ( double * ) pvPortMalloc( xArraySize * sizeof( double ) );\r
213 \r
214         /* Keep filling an array, keeping a running total of the values placed in \r
215         the array.  Then run through the array adding up all the values.  If the two \r
216         totals do not match, stop the check variable from incrementing. */\r
217         for( ;; )\r
218         {\r
219                 dTotal1 = 0.0;\r
220                 dTotal2 = 0.0;\r
221 \r
222                 for( xPosition = 0; xPosition < xArraySize; xPosition++ )\r
223                 {\r
224                         pdArray[ xPosition ] = ( double ) xPosition + 5.5;\r
225                         dTotal1 += ( double ) xPosition + 5.5;  \r
226                 }\r
227 \r
228                 for( xPosition = 0; xPosition < xArraySize; xPosition++ )\r
229                 {\r
230                         dTotal2 += pdArray[ xPosition ];\r
231                 }\r
232 \r
233                 dDifference = dTotal1 - dTotal2;\r
234                 if( fabs( dDifference ) > 0.001 )\r
235                 {\r
236                         sError = pdTRUE;\r
237                 }\r
238 \r
239                 if( sError == pdFALSE )\r
240                 {\r
241                         /* If the calculation has always been correct, increment the check \r
242                         variable so we know     this task is still running okay. */\r
243                         ( *pusTaskCheckVariable )++;\r
244                 }\r
245         }\r
246 }\r
247 /*-----------------------------------------------------------*/\r
248 \r
249 static void vCompetingMathTask4( void *pvParameters )\r
250 {\r
251 volatile double *pdArray, dTotal1, dTotal2, dDifference;\r
252 volatile unsigned short *pusTaskCheckVariable;\r
253 const size_t xArraySize = 10;\r
254 size_t xPosition;\r
255 short sError = pdFALSE;\r
256 \r
257         /* The variable this task increments to show it is still running is passed in \r
258         as the parameter. */\r
259         pusTaskCheckVariable = ( unsigned short * ) pvParameters;\r
260 \r
261         /* Allocate RAM for use as an array. */\r
262         pdArray = ( double * ) pvPortMalloc( xArraySize * sizeof( double ) );\r
263 \r
264         /* Keep filling an array, keeping a running total of the values placed in the \r
265         array.  Then run through the array adding up all the values.  If the two totals \r
266         do not match, stop the check variable from incrementing. */\r
267         for( ;; )\r
268         {\r
269                 dTotal1 = 0.0;\r
270                 dTotal2 = 0.0;\r
271 \r
272                 for( xPosition = 0; xPosition < xArraySize; xPosition++ )\r
273                 {\r
274                         pdArray[ xPosition ] = ( double ) xPosition * 12.123;\r
275                         dTotal1 += ( double ) xPosition * 12.123;       \r
276                 }\r
277 \r
278                 for( xPosition = 0; xPosition < xArraySize; xPosition++ )\r
279                 {\r
280                         dTotal2 += pdArray[ xPosition ];\r
281                 }\r
282 \r
283                 dDifference = dTotal1 - dTotal2;\r
284                 if( fabs( dDifference ) > 0.001 )\r
285                 {\r
286                         sError = pdTRUE;\r
287                 }\r
288 \r
289                 if( sError == pdFALSE )\r
290                 {\r
291                         /* If the calculation has always been correct, increment the check \r
292                         variable so we know     this task is still running okay. */\r
293                         ( *pusTaskCheckVariable )++;\r
294                 }\r
295         }\r
296 }                                \r
297 /*-----------------------------------------------------------*/\r
298 \r
299 /* This is called to check that all the created tasks are still running. */\r
300 portBASE_TYPE xAreMathsTaskStillRunning( void )\r
301 {\r
302 /* Keep a history of the check variables so we know if they have been \r
303 incremented since the last call. */\r
304 static unsigned short usLastTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };\r
305 portBASE_TYPE xReturn = pdTRUE, xTask;\r
306 \r
307         /* Check the maths tasks are still running by ensuring their check variables \r
308         are still incrementing. */\r
309         for( xTask = 0; xTask < mathNUMBER_OF_TASKS; xTask++ )\r
310         {\r
311                 if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] )\r
312                 {\r
313                         /* The check has not incremented so an error exists. */\r
314                         xReturn = pdFALSE;\r
315                 }\r
316 \r
317                 usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ];\r
318         }\r
319 \r
320         return xReturn;\r
321 }\r
322 \r
323 \r
324 \r