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