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