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

Subversion Repositories openrisc

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

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
Changes from V1.2.3
56
 
57
        + The created tasks now include calls to tskYIELD(), allowing them to be used
58
          with the cooperative scheduler.
59
*/
60
 
61
/**
62
 * Creates eight tasks, each of which loops continuously performing an (emulated)
63
 * floating point calculation.
64
 *
65
 * All the tasks run at the idle priority and never block or yield.  This causes
66
 * all eight tasks to time slice with the idle task.  Running at the idle priority
67
 * means that these tasks will get pre-empted any time another task is ready to run
68
 * or a time slice occurs.  More often than not the pre-emption will occur mid
69
 * calculation, creating a good test of the schedulers context switch mechanism - a
70
 * calculation producing an unexpected result could be a symptom of a corruption in
71
 * the context of a task.
72
 *
73
 * \page FlopC flop.c
74
 * \ingroup DemoFiles
75
 * <HR>
76
 */
77
 
78
#include <stdlib.h>
79
#include <math.h>
80
 
81
/* Scheduler include files. */
82
#include "FreeRTOS.h"
83
#include "task.h"
84
#include "print.h"
85
 
86
/* Demo program include files. */
87
#include "flop.h"
88
 
89
#define mathSTACK_SIZE          ( ( unsigned short ) 512 )
90
#define mathNUMBER_OF_TASKS  ( 8 )
91
 
92
/* Four tasks, each of which performs a different floating point calculation.
93
Each of the four is created twice. */
94
static void vCompetingMathTask1( void *pvParameters );
95
static void vCompetingMathTask2( void *pvParameters );
96
static void vCompetingMathTask3( void *pvParameters );
97
static void vCompetingMathTask4( void *pvParameters );
98
 
99
/* These variables are used to check that all the tasks are still running.  If a
100
task gets a calculation wrong it will
101
stop incrementing its check variable. */
102
static volatile unsigned short usTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };
103
 
104
/*-----------------------------------------------------------*/
105
 
106
void vStartMathTasks( unsigned portBASE_TYPE uxPriority )
107
{
108
        xTaskCreate( vCompetingMathTask1, "Math1", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL );
109
        xTaskCreate( vCompetingMathTask2, "Math2", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL );
110
        xTaskCreate( vCompetingMathTask3, "Math3", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL );
111
        xTaskCreate( vCompetingMathTask4, "Math4", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL );
112
        xTaskCreate( vCompetingMathTask1, "Math5", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL );
113
        xTaskCreate( vCompetingMathTask2, "Math6", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL );
114
        xTaskCreate( vCompetingMathTask3, "Math7", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL );
115
        xTaskCreate( vCompetingMathTask4, "Math8", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL );
116
}
117
/*-----------------------------------------------------------*/
118
 
119
static void vCompetingMathTask1( void *pvParameters )
120
{
121
portDOUBLE d1, d2, d3, d4;
122
volatile unsigned short *pusTaskCheckVariable;
123
const portDOUBLE dAnswer = ( 123.4567 + 2345.6789 ) * -918.222;
124
const char * const pcTaskStartMsg = "Math task 1 started.\r\n";
125
const char * const pcTaskFailMsg = "Math task 1 failed.\r\n";
126
short sError = pdFALSE;
127
 
128
        /* Queue a message for printing to say the task has started. */
129
        vPrintDisplayMessage( &pcTaskStartMsg );
130
 
131
        /* The variable this task increments to show it is still running is passed in
132
        as the parameter. */
133
        pusTaskCheckVariable = ( unsigned short * ) pvParameters;
134
 
135
        /* Keep performing a calculation and checking the result against a constant. */
136
        for(;;)
137
        {
138
                d1 = 123.4567;
139
                d2 = 2345.6789;
140
                d3 = -918.222;
141
 
142
                d4 = ( d1 + d2 ) * d3;
143
 
144
                taskYIELD();
145
 
146
                /* If the calculation does not match the expected constant, stop the
147
                increment of the check variable. */
148
                if( fabs( d4 - dAnswer ) > 0.001 )
149
                {
150
                        vPrintDisplayMessage( &pcTaskFailMsg );
151
                        sError = pdTRUE;
152
                }
153
 
154
                if( sError == pdFALSE )
155
                {
156
                        /* If the calculation has always been correct, increment the check
157
                        variable so we know this task is still running okay. */
158
                        ( *pusTaskCheckVariable )++;
159
                }
160
 
161
                taskYIELD();
162
        }
163
}
164
/*-----------------------------------------------------------*/
165
 
166
static void vCompetingMathTask2( void *pvParameters )
167
{
168
portDOUBLE d1, d2, d3, d4;
169
volatile unsigned short *pusTaskCheckVariable;
170
const portDOUBLE dAnswer = ( -389.38 / 32498.2 ) * -2.0001;
171
const char * const pcTaskStartMsg = "Math task 2 started.\r\n";
172
const char * const pcTaskFailMsg = "Math task 2 failed.\r\n";
173
short sError = pdFALSE;
174
 
175
        /* Queue a message for printing to say the task has started. */
176
        vPrintDisplayMessage( &pcTaskStartMsg );
177
 
178
        /* The variable this task increments to show it is still running is passed in
179
        as the parameter. */
180
        pusTaskCheckVariable = ( unsigned short * ) pvParameters;
181
 
182
        /* Keep performing a calculation and checking the result against a constant. */
183
        for( ;; )
184
        {
185
                d1 = -389.38;
186
                d2 = 32498.2;
187
                d3 = -2.0001;
188
 
189
                d4 = ( d1 / d2 ) * d3;
190
 
191
                taskYIELD();
192
 
193
                /* If the calculation does not match the expected constant, stop the
194
                increment of the check variable. */
195
                if( fabs( d4 - dAnswer ) > 0.001 )
196
                {
197
                        vPrintDisplayMessage( &pcTaskFailMsg );
198
                        sError = pdTRUE;
199
                }
200
 
201
                if( sError == pdFALSE )
202
                {
203
                        /* If the calculation has always been correct, increment the check
204
                        variable so we know
205
                        this task is still running okay. */
206
                        ( *pusTaskCheckVariable )++;
207
                }
208
 
209
                taskYIELD();
210
        }
211
}
212
/*-----------------------------------------------------------*/
213
 
214
static void vCompetingMathTask3( void *pvParameters )
215
{
216
portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;
217
volatile unsigned short *pusTaskCheckVariable;
218
const unsigned short usArraySize = 250;
219
unsigned short usPosition;
220
const char * const pcTaskStartMsg = "Math task 3 started.\r\n";
221
const char * const pcTaskFailMsg = "Math task 3 failed.\r\n";
222
short sError = pdFALSE;
223
 
224
        /* Queue a message for printing to say the task has started. */
225
        vPrintDisplayMessage( &pcTaskStartMsg );
226
 
227
        /* The variable this task increments to show it is still running is passed in
228
        as the parameter. */
229
        pusTaskCheckVariable = ( unsigned short * ) pvParameters;
230
 
231
        pdArray = ( portDOUBLE * ) pvPortMalloc( ( size_t ) 250 * sizeof( portDOUBLE ) );
232
 
233
        /* Keep filling an array, keeping a running total of the values placed in the
234
        array.  Then run through the array adding up all the values.  If the two totals
235
        do not match, stop the check variable from incrementing. */
236
        for( ;; )
237
        {
238
                dTotal1 = 0.0;
239
                dTotal2 = 0.0;
240
 
241
                for( usPosition = 0; usPosition < usArraySize; usPosition++ )
242
                {
243
                        pdArray[ usPosition ] = ( portDOUBLE ) usPosition + 5.5;
244
                        dTotal1 += ( portDOUBLE ) usPosition + 5.5;
245
                }
246
 
247
                taskYIELD();
248
 
249
                for( usPosition = 0; usPosition < usArraySize; usPosition++ )
250
                {
251
                        dTotal2 += pdArray[ usPosition ];
252
                }
253
 
254
                dDifference = dTotal1 - dTotal2;
255
                if( fabs( dDifference ) > 0.001 )
256
                {
257
                        vPrintDisplayMessage( &pcTaskFailMsg );
258
                        sError = pdTRUE;
259
                }
260
 
261
                taskYIELD();
262
 
263
                if( sError == pdFALSE )
264
                {
265
                        /* If the calculation has always been correct, increment the check
266
                        variable so we know     this task is still running okay. */
267
                        ( *pusTaskCheckVariable )++;
268
                }
269
        }
270
}
271
/*-----------------------------------------------------------*/
272
 
273
static void vCompetingMathTask4( void *pvParameters )
274
{
275
portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;
276
volatile unsigned short *pusTaskCheckVariable;
277
const unsigned short usArraySize = 250;
278
unsigned short usPosition;
279
const char * const pcTaskStartMsg = "Math task 4 started.\r\n";
280
const char * const pcTaskFailMsg = "Math task 4 failed.\r\n";
281
short sError = pdFALSE;
282
 
283
        /* Queue a message for printing to say the task has started. */
284
        vPrintDisplayMessage( &pcTaskStartMsg );
285
 
286
        /* The variable this task increments to show it is still running is passed in
287
        as the parameter. */
288
        pusTaskCheckVariable = ( unsigned short * ) pvParameters;
289
 
290
        pdArray = ( portDOUBLE * ) pvPortMalloc( ( size_t ) 250 * sizeof( portDOUBLE ) );
291
 
292
        /* Keep filling an array, keeping a running total of the values placed in the
293
        array.  Then run through the array adding up all the values.  If the two totals
294
        do not match, stop the check variable from incrementing. */
295
        for( ;; )
296
        {
297
                dTotal1 = 0.0;
298
                dTotal2 = 0.0;
299
 
300
                for( usPosition = 0; usPosition < usArraySize; usPosition++ )
301
                {
302
                        pdArray[ usPosition ] = ( portDOUBLE ) usPosition * 12.123;
303
                        dTotal1 += ( portDOUBLE ) usPosition * 12.123;
304
                }
305
 
306
                taskYIELD();
307
 
308
                for( usPosition = 0; usPosition < usArraySize; usPosition++ )
309
                {
310
                        dTotal2 += pdArray[ usPosition ];
311
                }
312
 
313
                dDifference = dTotal1 - dTotal2;
314
                if( fabs( dDifference ) > 0.001 )
315
                {
316
                        vPrintDisplayMessage( &pcTaskFailMsg );
317
                        sError = pdTRUE;
318
                }
319
 
320
                taskYIELD();
321
 
322
                if( sError == pdFALSE )
323
                {
324
                        /* If the calculation has always been correct, increment the check
325
                        variable so we know     this task is still running okay. */
326
                        ( *pusTaskCheckVariable )++;
327
                }
328
        }
329
}
330
/*-----------------------------------------------------------*/
331
 
332
/* This is called to check that all the created tasks are still running. */
333
portBASE_TYPE xAreMathsTaskStillRunning( void )
334
{
335
/* Keep a history of the check variables so we know if they have been incremented
336
since the last call. */
337
static unsigned short usLastTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };
338
portBASE_TYPE xReturn = pdTRUE, xTask;
339
 
340
        /* Check the maths tasks are still running by ensuring their check variables
341
        are still incrementing. */
342
        for( xTask = 0; xTask < mathNUMBER_OF_TASKS; xTask++ )
343
        {
344
                if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] )
345
                {
346
                        /* The check has not incremented so an error exists. */
347
                        xReturn = pdFALSE;
348
                }
349
 
350
                usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ];
351
        }
352
 
353
        return xReturn;
354
}
355
 
356
 
357
 

powered by: WebSVN 2.1.0

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