OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [Common/] [Minimal/] [flop.c] - Blame information for rev 615

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 606 jeremybenn
/*
2
    FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
3
 
4
    ***************************************************************************
5
    *                                                                         *
6
    * If you are:                                                             *
7
    *                                                                         *
8
    *    + New to FreeRTOS,                                                   *
9
    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
10
    *    + Looking for basic training,                                        *
11
    *    + Wanting to improve your FreeRTOS skills and productivity           *
12
    *                                                                         *
13
    * then take a look at the FreeRTOS books - available as PDF or paperback  *
14
    *                                                                         *
15
    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
16
    *                  http://www.FreeRTOS.org/Documentation                  *
17
    *                                                                         *
18
    * A pdf reference manual is also available.  Both are usually delivered   *
19
    * to your inbox within 20 minutes to two hours when purchased between 8am *
20
    * and 8pm GMT (although please allow up to 24 hours in case of            *
21
    * exceptional circumstances).  Thank you for your support!                *
22
    *                                                                         *
23
    ***************************************************************************
24
 
25
    This file is part of the FreeRTOS distribution.
26
 
27
    FreeRTOS is free software; you can redistribute it and/or modify it under
28
    the terms of the GNU General Public License (version 2) as published by the
29
    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
30
    ***NOTE*** The exception to the GPL is included to allow you to distribute
31
    a combined work that includes FreeRTOS without being obliged to provide the
32
    source code for proprietary components outside of the FreeRTOS kernel.
33
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
34
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
36
    more details. You should have received a copy of the GNU General Public
37
    License and the FreeRTOS license exception along with FreeRTOS; if not it
38
    can be viewed here: http://www.freertos.org/a00114.html and also obtained
39
    by writing to Richard Barry, contact details for whom are available on the
40
    FreeRTOS WEB site.
41
 
42
    1 tab == 4 spaces!
43
 
44
    http://www.FreeRTOS.org - Documentation, latest information, license and
45
    contact details.
46
 
47
    http://www.SafeRTOS.com - A version that is certified for use in safety
48
    critical systems.
49
 
50
    http://www.OpenRTOS.com - Commercial support, development, porting,
51
    licensing and training services.
52
*/
53
 
54
/*
55
 * Creates eight tasks, each of which loops continuously performing an (emulated)
56
 * floating point calculation.
57
 *
58
 * All the tasks run at the idle priority and never block or yield.  This causes
59
 * all eight tasks to time slice with the idle task.  Running at the idle priority
60
 * means that these tasks will get pre-empted any time another task is ready to run
61
 * or a time slice occurs.  More often than not the pre-emption will occur mid
62
 * calculation, creating a good test of the schedulers context switch mechanism - a
63
 * calculation producing an unexpected result could be a symptom of a corruption in
64
 * the context of a task.
65
 */
66
 
67
#include <stdlib.h>
68
#include <math.h>
69
 
70
/* Scheduler include files. */
71
#include "FreeRTOS.h"
72
#include "task.h"
73
 
74
/* Demo program include files. */
75
#include "flop.h"
76
 
77
#define mathSTACK_SIZE          configMINIMAL_STACK_SIZE
78
#define mathNUMBER_OF_TASKS  ( 8 )
79
 
80
/* Four tasks, each of which performs a different floating point calculation.
81
Each of the four is created twice. */
82
static portTASK_FUNCTION_PROTO( vCompetingMathTask1, pvParameters );
83
static portTASK_FUNCTION_PROTO( vCompetingMathTask2, pvParameters );
84
static portTASK_FUNCTION_PROTO( vCompetingMathTask3, pvParameters );
85
static portTASK_FUNCTION_PROTO( vCompetingMathTask4, pvParameters );
86
 
87
/* These variables are used to check that all the tasks are still running.  If a
88
task gets a calculation wrong it will
89
stop incrementing its check variable. */
90
static volatile unsigned short usTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };
91
 
92
/*-----------------------------------------------------------*/
93
 
94
void vStartMathTasks( unsigned portBASE_TYPE uxPriority )
95
{
96
        xTaskCreate( vCompetingMathTask1, ( signed char * ) "Math1", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL );
97
        xTaskCreate( vCompetingMathTask2, ( signed char * ) "Math2", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL );
98
        xTaskCreate( vCompetingMathTask3, ( signed char * ) "Math3", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL );
99
        xTaskCreate( vCompetingMathTask4, ( signed char * ) "Math4", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL );
100
        xTaskCreate( vCompetingMathTask1, ( signed char * ) "Math5", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL );
101
        xTaskCreate( vCompetingMathTask2, ( signed char * ) "Math6", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL );
102
        xTaskCreate( vCompetingMathTask3, ( signed char * ) "Math7", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL );
103
        xTaskCreate( vCompetingMathTask4, ( signed char * ) "Math8", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL );
104
}
105
/*-----------------------------------------------------------*/
106
 
107
static portTASK_FUNCTION( vCompetingMathTask1, pvParameters )
108
{
109
volatile portDOUBLE d1, d2, d3, d4;
110
volatile unsigned short *pusTaskCheckVariable;
111
volatile portDOUBLE dAnswer;
112
short sError = pdFALSE;
113
 
114
        d1 = 123.4567;
115
        d2 = 2345.6789;
116
        d3 = -918.222;
117
 
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
                d1 = 123.4567;
128
                d2 = 2345.6789;
129
                d3 = -918.222;
130
 
131
                d4 = ( d1 + d2 ) * d3;
132
 
133
                #if configUSE_PREEMPTION == 0
134
                        taskYIELD();
135
                #endif
136
 
137
                /* If the calculation does not match the expected constant, stop the
138
                increment of the check variable. */
139
                if( fabs( d4 - dAnswer ) > 0.001 )
140
                {
141
                        sError = pdTRUE;
142
                }
143
 
144
                if( sError == pdFALSE )
145
                {
146
                        /* If the calculation has always been correct, increment the check
147
                        variable so we know this task is still running okay. */
148
                        ( *pusTaskCheckVariable )++;
149
                }
150
 
151
                #if configUSE_PREEMPTION == 0
152
                        taskYIELD();
153
                #endif
154
 
155
        }
156
}
157
/*-----------------------------------------------------------*/
158
 
159
static portTASK_FUNCTION( vCompetingMathTask2, pvParameters )
160
{
161
volatile portDOUBLE d1, d2, d3, d4;
162
volatile unsigned short *pusTaskCheckVariable;
163
volatile portDOUBLE dAnswer;
164
short sError = pdFALSE;
165
 
166
        d1 = -389.38;
167
        d2 = 32498.2;
168
        d3 = -2.0001;
169
 
170
        dAnswer = ( d1 / d2 ) * d3;
171
 
172
 
173
        /* The variable this task increments to show it is still running is passed in
174
        as the parameter. */
175
        pusTaskCheckVariable = ( unsigned short * ) pvParameters;
176
 
177
        /* Keep performing a calculation and checking the result against a constant. */
178
        for( ;; )
179
        {
180
                d1 = -389.38;
181
                d2 = 32498.2;
182
                d3 = -2.0001;
183
 
184
                d4 = ( d1 / d2 ) * d3;
185
 
186
                #if configUSE_PREEMPTION == 0
187
                        taskYIELD();
188
                #endif
189
 
190
                /* If the calculation does not match the expected constant, stop the
191
                increment of the check variable. */
192
                if( fabs( d4 - dAnswer ) > 0.001 )
193
                {
194
                        sError = pdTRUE;
195
                }
196
 
197
                if( sError == pdFALSE )
198
                {
199
                        /* If the calculation has always been correct, increment the check
200
                        variable so we know
201
                        this task is still running okay. */
202
                        ( *pusTaskCheckVariable )++;
203
                }
204
 
205
                #if configUSE_PREEMPTION == 0
206
                        taskYIELD();
207
                #endif
208
        }
209
}
210
/*-----------------------------------------------------------*/
211
 
212
static portTASK_FUNCTION( vCompetingMathTask3, pvParameters )
213
{
214
volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;
215
volatile unsigned short *pusTaskCheckVariable;
216
const size_t xArraySize = 10;
217
size_t xPosition;
218
short sError = pdFALSE;
219
 
220
        /* The variable this task increments to show it is still running is passed in
221
        as the parameter. */
222
        pusTaskCheckVariable = ( unsigned short * ) pvParameters;
223
 
224
        pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) );
225
 
226
        /* Keep filling an array, keeping a running total of the values placed in the
227
        array.  Then run through the array adding up all the values.  If the two totals
228
        do not match, stop the check variable from incrementing. */
229
        for( ;; )
230
        {
231
                dTotal1 = 0.0;
232
                dTotal2 = 0.0;
233
 
234
                for( xPosition = 0; xPosition < xArraySize; xPosition++ )
235
                {
236
                        pdArray[ xPosition ] = ( portDOUBLE ) xPosition + 5.5;
237
                        dTotal1 += ( portDOUBLE ) xPosition + 5.5;
238
                }
239
 
240
                #if configUSE_PREEMPTION == 0
241
                        taskYIELD();
242
                #endif
243
 
244
                for( xPosition = 0; xPosition < xArraySize; xPosition++ )
245
                {
246
                        dTotal2 += pdArray[ xPosition ];
247
                }
248
 
249
                dDifference = dTotal1 - dTotal2;
250
                if( fabs( dDifference ) > 0.001 )
251
                {
252
                        sError = pdTRUE;
253
                }
254
 
255
                #if configUSE_PREEMPTION == 0
256
                        taskYIELD();
257
                #endif
258
 
259
                if( sError == pdFALSE )
260
                {
261
                        /* If the calculation has always been correct, increment the check
262
                        variable so we know     this task is still running okay. */
263
                        ( *pusTaskCheckVariable )++;
264
                }
265
        }
266
}
267
/*-----------------------------------------------------------*/
268
 
269
static portTASK_FUNCTION( vCompetingMathTask4, pvParameters )
270
{
271
volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;
272
volatile unsigned short *pusTaskCheckVariable;
273
const size_t xArraySize = 10;
274
size_t xPosition;
275
short sError = pdFALSE;
276
 
277
        /* The variable this task increments to show it is still running is passed in
278
        as the parameter. */
279
        pusTaskCheckVariable = ( unsigned short * ) pvParameters;
280
 
281
        pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) );
282
 
283
        /* Keep filling an array, keeping a running total of the values placed in the
284
        array.  Then run through the array adding up all the values.  If the two totals
285
        do not match, stop the check variable from incrementing. */
286
        for( ;; )
287
        {
288
                dTotal1 = 0.0;
289
                dTotal2 = 0.0;
290
 
291
                for( xPosition = 0; xPosition < xArraySize; xPosition++ )
292
                {
293
                        pdArray[ xPosition ] = ( portDOUBLE ) xPosition * 12.123;
294
                        dTotal1 += ( portDOUBLE ) xPosition * 12.123;
295
                }
296
 
297
                #if configUSE_PREEMPTION == 0
298
                        taskYIELD();
299
                #endif
300
 
301
                for( xPosition = 0; xPosition < xArraySize; xPosition++ )
302
                {
303
                        dTotal2 += pdArray[ xPosition ];
304
                }
305
 
306
                dDifference = dTotal1 - dTotal2;
307
                if( fabs( dDifference ) > 0.001 )
308
                {
309
                        sError = pdTRUE;
310
                }
311
 
312
                #if configUSE_PREEMPTION == 0
313
                        taskYIELD();
314
                #endif
315
 
316
                if( sError == pdFALSE )
317
                {
318
                        /* If the calculation has always been correct, increment the check
319
                        variable so we know     this task is still running okay. */
320
                        ( *pusTaskCheckVariable )++;
321
                }
322
        }
323
}
324
/*-----------------------------------------------------------*/
325
 
326
/* This is called to check that all the created tasks are still running. */
327
portBASE_TYPE xAreMathsTaskStillRunning( void )
328
{
329
/* Keep a history of the check variables so we know if they have been incremented
330
since the last call. */
331
static unsigned short usLastTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };
332
portBASE_TYPE xReturn = pdTRUE, xTask;
333
 
334
        /* Check the maths tasks are still running by ensuring their check variables
335
        are still incrementing. */
336
        for( xTask = 0; xTask < mathNUMBER_OF_TASKS; xTask++ )
337
        {
338
                if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] )
339
                {
340
                        /* The check has not incremented so an error exists. */
341
                        xReturn = pdFALSE;
342
                }
343
 
344
                usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ];
345
        }
346
 
347
        return xReturn;
348
}
349
 
350
 
351
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.