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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [Flshlite/] [main.c] - Blame information for rev 773

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

Line No. Rev Author Line
1 616 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 all the demo application tasks, then starts the scheduler.
56
 *
57
 * Main. c also creates a task called "Print".  This only executes every five
58
 * seconds but has the highest priority so is guaranteed to get processor time.
59
 * Its main function is to check that all the other tasks are still operational.
60
 * Nearly all the tasks in the demo application maintain a unique count that is
61
 * incremented each time the task successfully completes its function.  Should any
62
 * error occur within the task the count is permanently halted.  The print task
63
 * checks the count of each task to ensure it has changed since the last time the
64
 * print task executed.  If any count is found not to have changed the print task
65
 * displays an appropriate message, halts, and flashes the on board LED rapidly.
66
 * If all the tasks are still incrementing their unique counts the print task
67
 * displays an "OK" message.
68
 *
69
 * The LED flash tasks do not maintain a count as they already provide visual
70
 * feedback of their status.
71
 *
72
 * The print task blocks on the queue into which messages that require displaying
73
 * are posted.  It will therefore only block for the full 5 seconds if no messages
74
 * are posted onto the queue.
75
 *
76
 * Main. c also provides a demonstration of how the trace visualisation utility can
77
 * be used, and how the scheduler can be stopped.
78
 *
79
 * On the Flashlite it is preferable not to try to write to the console during
80
 * real time operation.  The built in LED is toggled every cycle of the print task
81
 * that does not encounter any errors, so the console IO may be removed if required.
82
 * The build in LED will start flashing rapidly if any task reports an error.
83
 */
84
 
85
/*
86
Changes from V1.01:
87
 
88
        + Previously, if an error occurred in a task the on board LED was stopped from
89
          toggling.  Now if an error occurs the check task enters an infinite loop,
90
          toggling the LED rapidly.
91
 
92
Changes from V1.2.3
93
 
94
        + The integer and comtest tasks are now used when the cooperative scheduler
95
          is being used.  Previously they were only used with the preemptive
96
          scheduler.
97
 
98
Changes from V1.2.5
99
 
100
        + Made the communications RX task a higher priority.
101
 
102
Changes from V2.0.0
103
 
104
        + Delay periods are now specified using variables and constants of
105
          portTickType rather than unsigned long.
106
*/
107
 
108
#include <stdlib.h>
109
#include <conio.h>
110
#include "FreeRTOS.h"
111
#include "task.h"
112
#include "partest.h"
113
#include "serial.h"
114
 
115
/* Demo file headers. */
116
#include "BlockQ.h"
117
#include "PollQ.h"
118
#include "death.h"
119
#include "flash.h"
120
#include "integer.h"
121
#include "print.h"
122
#include "comtest.h"
123
#include "fileio.h"
124
#include "semtest.h"
125
 
126
/* Priority definitions for all the tasks in the demo application. */
127
#define mainLED_TASK_PRIORITY                   ( tskIDLE_PRIORITY + 1 )
128
#define mainCREATOR_TASK_PRIORITY               ( tskIDLE_PRIORITY + 3 )
129
#define mainPRINT_TASK_PRIORITY                 ( tskIDLE_PRIORITY + 5 )
130
#define mainQUEUE_POLL_PRIORITY                 ( tskIDLE_PRIORITY + 2 )
131
#define mainQUEUE_BLOCK_PRIORITY                ( tskIDLE_PRIORITY + 3 )
132
#define mainCOM_TEST_PRIORITY                   ( tskIDLE_PRIORITY + 3 )
133
#define mainSEMAPHORE_TASK_PRIORITY             ( tskIDLE_PRIORITY + 1 )
134
 
135
#define mainPRINT_STACK_SIZE            ( ( unsigned short ) 256 )
136
#define mainDEBUG_LOG_BUFFER_SIZE       ( ( unsigned short ) 20480 )
137
 
138
/* Constant definitions for accessing the build in LED on the Flashlite 186. */
139
#define mainLED_REG_DIR                         ( ( unsigned short ) 0xff78 )
140
#define mainLED_REG                             ( ( unsigned short ) 0xff7a )
141
 
142
/* If an error is detected in a task then the vErrorChecks() task will enter
143
an infinite loop flashing the LED at this rate. */
144
#define mainERROR_FLASH_RATE            ( ( portTickType ) 100 / portTICK_RATE_MS )
145
 
146
/* Task function for the "Print" task as described at the top of the file. */
147
static void vErrorChecks( void *pvParameters );
148
 
149
/* Function that checks the unique count of all the other tasks as described at
150
the top of the file. */
151
static void prvCheckOtherTasksAreStillRunning( void );
152
 
153
/* Functions to setup and use the built in LED on the Flashlite 186 board. */
154
static void prvToggleLED( void );
155
static void prvInitLED( void );
156
 
157
/* Key presses can be used to start/stop the trace visualisation utility or stop
158
the scheduler. */
159
static void     prvCheckForKeyPresses( void );
160
 
161
/* Buffer used by the trace visualisation utility. */
162
static char pcWriteBuffer[ mainDEBUG_LOG_BUFFER_SIZE ];
163
 
164
/*-----------------------------------------------------------*/
165
short main( void )
166
{
167
        /* Initialise hardware and utilities. */
168
        vParTestInitialise();
169
        vPrintInitialise();
170
        prvInitLED();
171
 
172
        /* CREATE ALL THE DEMO APPLICATION TASKS. */
173
 
174
        vStartComTestTasks( mainCOM_TEST_PRIORITY, serCOM2, ser38400 );
175
        vStartIntegerMathTasks( tskIDLE_PRIORITY );
176
        vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
177
        vStartBlockingQueueTasks( mainQUEUE_BLOCK_PRIORITY );
178
        vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
179
        vStartSemaphoreTasks( mainSEMAPHORE_TASK_PRIORITY );
180
 
181
        /* Create the "Print" task as described at the top of the file. */
182
        xTaskCreate( vErrorChecks, "Print", mainPRINT_STACK_SIZE, NULL, mainPRINT_TASK_PRIORITY, NULL );
183
 
184
        /* This task has to be created last as it keeps account of the number of tasks
185
        it expects to see running. */
186
        vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
187
 
188
        /* Set the scheduler running.  This function will not return unless a task
189
        calls vTaskEndScheduler(). */
190
        vTaskStartScheduler();
191
 
192
        return 1;
193
}
194
/*-----------------------------------------------------------*/
195
 
196
static void vErrorChecks( void *pvParameters )
197
{
198
portTickType xExpectedWakeTime;
199
const portTickType xPrintRate = ( portTickType ) 5000 / portTICK_RATE_MS;
200
const long lMaxAllowableTimeDifference = ( long ) 0;
201
portTickType xWakeTime;
202
long lTimeDifference;
203
const char *pcReceivedMessage;
204
const char * const pcTaskBlockedTooLongMsg = "Print task blocked too long!\r\n";
205
 
206
        /* Stop warnings. */
207
    ( void ) pvParameters;
208
 
209
        /* Loop continuously, blocking, then checking all the other tasks are still
210
        running, before blocking once again.  This task blocks on the queue of messages
211
        that require displaying so will wake either by its time out expiring, or a
212
        message becoming available. */
213
        for( ;; )
214
        {
215
                /* Calculate the time we will unblock if no messages are received
216
                on the queue.  This is used to check that we have not blocked for too long. */
217
                xExpectedWakeTime = xTaskGetTickCount();
218
                xExpectedWakeTime += xPrintRate;
219
 
220
                /* Block waiting for either a time out or a message to be posted that
221
                required displaying. */
222
                pcReceivedMessage = pcPrintGetNextMessage( xPrintRate );
223
 
224
                /* Was a message received? */
225
                if( pcReceivedMessage == NULL )
226
                {
227
                        /* A message was not received so we timed out, did we unblock at the
228
                        expected time? */
229
                        xWakeTime = xTaskGetTickCount();
230
 
231
                        /* Calculate the difference between the time we unblocked and the
232
                        time we should have unblocked. */
233
                        if( xWakeTime > xExpectedWakeTime )
234
                        {
235
                                lTimeDifference = ( long ) ( xWakeTime - xExpectedWakeTime );
236
                        }
237
                        else
238
                        {
239
                                lTimeDifference = ( long ) ( xExpectedWakeTime - xWakeTime );
240
                        }
241
 
242
                        if( lTimeDifference > lMaxAllowableTimeDifference )
243
                        {
244
                                /* We blocked too long - create a message that will get
245
                                printed out the next time around. */
246
                                vPrintDisplayMessage( &pcTaskBlockedTooLongMsg );
247
                        }
248
 
249
                        /* Check the other tasks are still running, just in case. */
250
                        prvCheckOtherTasksAreStillRunning();
251
                }
252
                else
253
                {
254
                        /* We unblocked due to a message becoming available.  Send the message
255
                        for printing. */
256
                        vDisplayMessage( pcReceivedMessage );
257
                }
258
 
259
                /* Key presses are used to invoke the trace visualisation utility, or
260
                end the program. */
261
                prvCheckForKeyPresses();
262
        }
263
} /*lint !e715 !e818 pvParameters is not used but all task functions must take this form. */
264
/*-----------------------------------------------------------*/
265
 
266
static void      prvCheckForKeyPresses( void )
267
{
268
        #ifdef USE_STDIO
269
 
270
        short sIn;
271
 
272
 
273
                taskENTER_CRITICAL();
274
                        sIn = kbhit();
275
                taskEXIT_CRITICAL();
276
 
277
                if( sIn )
278
                {
279
                        unsigned long ulBufferLength;
280
 
281
                        /* Key presses can be used to start/stop the trace utility, or end the
282
                        program. */
283
                        sIn = getch();
284
                        switch( sIn )
285
                        {
286
                                /* Only define keys for turning on and off the trace if the trace
287
                                is being used. */
288
                                #if configUSE_TRACE_FACILITY == 1
289
                                        case 't' :      vTaskList( pcWriteBuffer );
290
                                                                vWriteMessageToDisk( pcWriteBuffer );
291
                                                                break;
292
 
293
                                        case 's' :      vTaskStartTrace( pcWriteBuffer, mainDEBUG_LOG_BUFFER_SIZE );
294
                                                                break;
295
 
296
                                        case 'e' :      ulBufferLength = ulTaskEndTrace();
297
                                                                vWriteBufferToDisk( pcWriteBuffer, ulBufferLength );
298
                                                                break;
299
                                #endif
300
 
301
                                default  :      vTaskEndScheduler();
302
                                                        break;
303
                        }
304
                }
305
 
306
        #else
307
                ( void ) pcWriteBuffer;
308
        #endif
309
}
310
/*-----------------------------------------------------------*/
311
 
312
static void prvCheckOtherTasksAreStillRunning( void )
313
{
314
short sErrorHasOccurred = pdFALSE;
315
 
316
        if( xAreComTestTasksStillRunning() != pdTRUE )
317
        {
318
                vDisplayMessage( "Com test count unchanged!\r\n" );
319
                sErrorHasOccurred = pdTRUE;
320
        }
321
 
322
        if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
323
        {
324
                vDisplayMessage( "Integer maths task count unchanged!\r\n" );
325
                sErrorHasOccurred = pdTRUE;
326
        }
327
 
328
        if( xAreBlockingQueuesStillRunning() != pdTRUE )
329
        {
330
                vDisplayMessage( "Blocking queues count unchanged!\r\n" );
331
                sErrorHasOccurred = pdTRUE;
332
        }
333
 
334
        if( xArePollingQueuesStillRunning() != pdTRUE )
335
        {
336
                vDisplayMessage( "Polling queue count unchanged!\r\n" );
337
                sErrorHasOccurred = pdTRUE;
338
        }
339
 
340
        if( xIsCreateTaskStillRunning() != pdTRUE )
341
        {
342
                vDisplayMessage( "Incorrect number of tasks running!\r\n" );
343
                sErrorHasOccurred = pdTRUE;
344
        }
345
 
346
        if( xAreSemaphoreTasksStillRunning() != pdTRUE )
347
        {
348
                vDisplayMessage( "Semaphore take count unchanged!\r\n" );
349
                sErrorHasOccurred = pdTRUE;
350
        }
351
 
352
        if( sErrorHasOccurred == pdFALSE )
353
        {
354
                vDisplayMessage( "OK " );
355
                /* Toggle the LED if everything is okay so we know if an error occurs even if not
356
                using console IO. */
357
                prvToggleLED();
358
        }
359
        else
360
        {
361
                for( ;; )
362
                {
363
                        /* An error has occurred in one of the tasks.  Don't go any further and
364
                        flash the LED rapidly in case console IO is not being used. */
365
                        prvToggleLED();
366
                        vTaskDelay( mainERROR_FLASH_RATE );
367
                }
368
        }
369
}
370
/*-----------------------------------------------------------*/
371
 
372
static void prvInitLED( void )
373
{
374
unsigned short usPortDirection;
375
const unsigned short usLEDOut = 0x400;
376
 
377
        /* Set the LED bit to an output. */
378
 
379
        usPortDirection = inpw( mainLED_REG_DIR );
380
        usPortDirection &= ~usLEDOut;
381
        outpw( mainLED_REG_DIR, usPortDirection );
382
}
383
/*-----------------------------------------------------------*/
384
 
385
static void prvToggleLED( void )
386
{
387
static short sLED = pdTRUE;
388
unsigned short usLEDState;
389
const unsigned short usLEDBit = 0x400;
390
 
391
        /* Flip the state of the LED. */
392
        usLEDState = inpw( mainLED_REG );
393
        if( sLED )
394
        {
395
                usLEDState &= ~usLEDBit;
396
        }
397
        else
398
        {
399
                usLEDState |= usLEDBit;
400
        }
401
        outpw( mainLED_REG, usLEDState );
402
 
403
        sLED = !sLED;
404
}
405
 
406
 

powered by: WebSVN 2.1.0

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