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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [RX600_RX62N-RDK_IAR/] [main-full.c] - Blame information for rev 585

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 585 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
 * This project includes a lot of tasks and tests and is therefore complex.
56
 * If you would prefer a much simpler project to get started with then select
57
 * the 'Blinky' build configuration within the Embedded Workbench IDE.
58
 * ****************************************************************************
59
 *
60
 * Creates all the demo application tasks, then starts the scheduler.  The web
61
 * documentation provides more details of the standard demo application tasks,
62
 * which provide no particular functionality but do provide a good example of
63
 * how to use the FreeRTOS API.  The tasks defined in flop.c are included in the
64
 * set of standard demo tasks to ensure the floating point unit gets some
65
 * exercise.
66
 *
67
 * In addition to the standard demo tasks, the following tasks and tests are
68
 * defined and/or created within this file:
69
 *
70
 * Webserver ("uIP") task - This serves a number of dynamically generated WEB
71
 * pages to a standard WEB browser.  The IP and MAC addresses are configured by
72
 * constants defined at the bottom of FreeRTOSConfig.h.  Use either a standard
73
 * Ethernet cable to connect through a hug, or a cross over (point to point)
74
 * cable to connect directly.  Ensure the IP address used is compatible with the
75
 * IP address of the machine running the browser - the easiest way to achieve
76
 * this is to ensure the first three octets of the IP addresses are the same.
77
 *
78
 * "Reg test" tasks - These fill the registers with known values, then check
79
 * that each register still contains its expected value.  Each task uses
80
 * different values.  The tasks run with very low priority so get preempted
81
 * very frequently.  A check variable is incremented on each iteration of the
82
 * test loop.  A register containing an unexpected value is indicative of an
83
 * error in the context switching mechanism and will result in a branch to a
84
 * null loop - which in turn will prevent the check variable from incrementing
85
 * any further and allow the check task (described below) to determine that an
86
 * error has occurred.  The nature of the reg test tasks necessitates that they
87
 * are written in assembly code.
88
 *
89
 * "Check" task - This only executes every five seconds but has a high priority
90
 * to ensure it gets processor time.  Its main function is to check that all the
91
 * standard demo tasks are still operational.  While no errors have been
92
 * discovered the check task will toggle LED 5 every 5 seconds - the toggle
93
 * rate increasing to 200ms being a visual indication that at least one task has
94
 * reported unexpected behaviour.
95
 *
96
 * "High frequency timer test" - A high frequency periodic interrupt is
97
 * generated using a timer - the interrupt is assigned a priority above
98
 * configMAX_SYSCALL_INTERRUPT_PRIORITY so should not be effected by anything
99
 * the kernel is doing.  The frequency and priority of the interrupt, in
100
 * combination with other standard tests executed in this demo, should result
101
 * in interrupts nesting at least 3 and probably 4 deep.  This test is only
102
 * included in build configurations that have the optimiser switched on.  In
103
 * optimised builds the count of high frequency ticks is used as the time base
104
 * for the run time stats.
105
 *
106
 * *NOTE 1* If LED5 is toggling every 5 seconds then all the demo application
107
 * tasks are executing as expected and no errors have been reported in any
108
 * tasks.  The toggle rate increasing to 200ms indicates that at least one task
109
 * has reported unexpected behaviour.
110
 *
111
 * *NOTE 2* vApplicationSetupTimerInterrupt() is called by the kernel to let
112
 * the application set up a timer to generate the tick interrupt.  In this
113
 * example a compare match timer is used for this purpose.
114
 *
115
 * *NOTE 3* The CPU must be in Supervisor mode when the scheduler is started.
116
 * The PowerON_Reset_PC() supplied in resetprg.c with this demo has
117
 * Change_PSW_PM_to_UserMode() commented out to ensure this is the case.
118
 *
119
 * *NOTE 4* The IntQueue common demo tasks test interrupt nesting and make use
120
 * of all the 8bit timers (as two cascaded 16bit units).
121
*/
122
 
123
/* Standard includes. */
124
#include <string.h>
125
#include <stdio.h>
126
 
127
/* Hardware specific includes. */
128
#include <iorx62n.h>
129
 
130
/* Kernel includes. */
131
#include "FreeRTOS.h"
132
#include "task.h"
133
 
134
/* Standard demo includes. */
135
#include "partest.h"
136
#include "flash.h"
137
#include "IntQueue.h"
138
#include "BlockQ.h"
139
#include "death.h"
140
#include "integer.h"
141
#include "blocktim.h"
142
#include "semtest.h"
143
#include "PollQ.h"
144
#include "GenQTest.h"
145
#include "QPeek.h"
146
#include "recmutex.h"
147
#include "flop.h"
148
 
149
/* Values that are passed into the reg test tasks using the task parameter.  The
150
tasks check that the values are passed in correctly. */
151
#define mainREG_TEST_1_PARAMETER        ( 0x12121212UL )
152
#define mainREG_TEST_2_PARAMETER        ( 0x12345678UL )
153
 
154
/* Priorities at which the tasks are created. */
155
#define mainCHECK_TASK_PRIORITY         ( configMAX_PRIORITIES - 1 )
156
#define mainQUEUE_POLL_PRIORITY         ( tskIDLE_PRIORITY + 1 )
157
#define mainSEM_TEST_PRIORITY           ( tskIDLE_PRIORITY + 1 )
158
#define mainBLOCK_Q_PRIORITY            ( tskIDLE_PRIORITY + 2 )
159
#define mainCREATOR_TASK_PRIORITY   ( tskIDLE_PRIORITY + 3 )
160
#define mainFLASH_TASK_PRIORITY         ( tskIDLE_PRIORITY + 1 )
161
#define mainuIP_TASK_PRIORITY           ( tskIDLE_PRIORITY + 2 )
162
#define mainINTEGER_TASK_PRIORITY   ( tskIDLE_PRIORITY )
163
#define mainGEN_QUEUE_TASK_PRIORITY     ( tskIDLE_PRIORITY )
164
#define mainFLOP_TASK_PRIORITY          ( tskIDLE_PRIORITY )
165
 
166
/* The WEB server uses string handling functions, which in turn use a bit more
167
stack than most of the other tasks. */
168
#define mainuIP_STACK_SIZE                      ( configMINIMAL_STACK_SIZE * 3 )
169
 
170
/* The LED toggled by the check task. */
171
#define mainCHECK_LED                           ( 5 )
172
 
173
/* The rate at which mainCHECK_LED will toggle when all the tasks are running
174
without error.  Controlled by the check task as described at the top of this
175
file. */
176
#define mainNO_ERROR_CYCLE_TIME         ( 5000 / portTICK_RATE_MS )
177
 
178
/* The rate at which mainCHECK_LED will toggle when an error has been reported
179
by at least one task.  Controlled by the check task as described at the top of
180
this file. */
181
#define mainERROR_CYCLE_TIME            ( 200 / portTICK_RATE_MS )
182
 
183
/* For outputing debug console messages - just maps to printf. */
184
#ifdef DEBUG_BUILD
185
        #define xPrintf( x )    printf( x )
186
#else
187
        #define xPrintf( x )    ( void ) x
188
#endif
189
 
190
/*
191
 * vApplicationMallocFailedHook() will only be called if
192
 * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h.  It is a hook
193
 * function that will execute if a call to pvPortMalloc() fails.
194
 * pvPortMalloc() is called internally by the kernel whenever a task, queue or
195
 * semaphore is created.  It is also called by various parts of the demo
196
 * application.
197
 */
198
void vApplicationMallocFailedHook( void );
199
 
200
/*
201
 * vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set to 1
202
 * in FreeRTOSConfig.h.  It is a hook function that is called on each iteration
203
 * of the idle task.  It is essential that code added to this hook function
204
 * never attempts to block in any way (for example, call xQueueReceive() with
205
 * a block time specified).  If the application makes use of the vTaskDelete()
206
 * API function (as this demo application does) then it is also important that
207
 * vApplicationIdleHook() is permitted to return to its calling function because
208
 * it is the responsibility of the idle task to clean up memory allocated by the
209
 * kernel to any task that has since been deleted.
210
 */
211
void vApplicationIdleHook( void );
212
 
213
/*
214
 * vApplicationStackOverflowHook() will only be called if
215
 * configCHECK_FOR_STACK_OVERFLOW is set to a non-zero value.  The handle and
216
 * name of the offending task should be passed in the function parameters, but
217
 * it is possible that the stack overflow will have corrupted these - in which
218
 * case pxCurrentTCB can be inspected to find the same information.
219
 */
220
void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName );
221
 
222
/*
223
 * The reg test tasks as described at the top of this file.
224
 */
225
static void prvRegTest1Task( void *pvParameters );
226
static void prvRegTest2Task( void *pvParameters );
227
 
228
/*
229
 * The actual implementation of the reg test functionality, which, because of
230
 * the direct register access, have to be in assembly.
231
 */
232
extern void prvRegTest1Implementation( void );
233
extern void prvRegTest2Implementation( void );
234
 
235
 
236
/*
237
 * The check task as described at the top of this file.
238
 */
239
static void prvCheckTask( void *pvParameters );
240
 
241
/*
242
 * Contains the implementation of the WEB server.
243
 */
244
extern void vuIP_Task( void *pvParameters );
245
 
246
/*-----------------------------------------------------------*/
247
 
248
/* Variables that are incremented on each iteration of the reg test tasks -
249
provided the tasks have not reported any errors.  The check task inspects these
250
variables to ensure they are still incrementing as expected.  If a variable
251
stops incrementing then it is likely that its associate task has stalled. */
252
unsigned long ulRegTest1CycleCount = 0UL, ulRegTest2CycleCount = 0UL;
253
 
254
/* The status message that is displayed at the bottom of the "task stats" web
255
page, which is served by the uIP task.  This will report any errors picked up
256
by the reg test task. */
257
static const char *pcStatusMessage = NULL;
258
 
259
/*-----------------------------------------------------------*/
260
 
261
void main(void)
262
{
263
extern void HardwareSetup( void );
264
 
265
        /* Renesas provided CPU configuration routine.  The clocks are configured in
266
        here. */
267
        HardwareSetup();
268
 
269
        xPrintf( "http://www.FreeRTOS.org\r\n" );
270
 
271
        /* Start the reg test tasks which test the context switching mechanism. */
272
        xTaskCreate( prvRegTest1Task, "RegTst1", configMINIMAL_STACK_SIZE, ( void * ) mainREG_TEST_1_PARAMETER, tskIDLE_PRIORITY, NULL );
273
        xTaskCreate( prvRegTest2Task, "RegTst2", configMINIMAL_STACK_SIZE, ( void * ) mainREG_TEST_2_PARAMETER, tskIDLE_PRIORITY, NULL );
274
 
275
        /* The web server task. */
276
        xTaskCreate( vuIP_Task, "uIP", mainuIP_STACK_SIZE, NULL, mainuIP_TASK_PRIORITY, NULL );
277
 
278
        /* Start the check task as described at the top of this file. */
279
        xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE * 3, NULL, mainCHECK_TASK_PRIORITY, NULL );
280
 
281
        /* Create the standard demo tasks. */
282
        vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
283
        vCreateBlockTimeTasks();
284
        vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
285
        vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
286
        vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );
287
        vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
288
        vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY );
289
        vStartQueuePeekTasks();
290
        vStartRecursiveMutexTasks();
291
        vStartInterruptQueueTasks();
292
        vStartMathTasks( mainFLOP_TASK_PRIORITY );
293
 
294
        /* The suicide tasks must be created last as they need to know how many
295
        tasks were running prior to their creation in order to ascertain whether
296
        or not the correct/expected number of tasks are running at any given time. */
297
        vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
298
 
299
        /* Start the tasks running. */
300
        vTaskStartScheduler();
301
 
302
        /* If all is well we will never reach here as the scheduler will now be
303
        running.  If we do reach here then it is likely that there was insufficient
304
        heap available for the idle task to be created. */
305
        for( ;; );
306
}
307
/*-----------------------------------------------------------*/
308
 
309
static void prvCheckTask( void *pvParameters )
310
{
311
static volatile unsigned long ulLastRegTest1CycleCount = 0UL, ulLastRegTest2CycleCount = 0UL;
312
portTickType xNextWakeTime, xCycleFrequency = mainNO_ERROR_CYCLE_TIME;
313
extern void vSetupHighFrequencyTimer( void );
314
 
315
        /* If this is being executed then the kernel has been started.  Start the high
316
        frequency timer test as described at the top of this file.  This is only
317
        included in the optimised build configuration - otherwise it takes up too much
318
        CPU time. */
319
        #ifdef INCLUDE_HIGH_FREQUENCY_TIMER_TEST
320
                vSetupHighFrequencyTimer();
321
        #endif
322
 
323
        /* Initialise xNextWakeTime - this only needs to be done once. */
324
        xNextWakeTime = xTaskGetTickCount();
325
 
326
        for( ;; )
327
        {
328
                /* Place this task in the blocked state until it is time to run again. */
329
                vTaskDelayUntil( &xNextWakeTime, xCycleFrequency );
330
 
331
                /* Check the standard demo tasks are running without error. */
332
                if( xAreGenericQueueTasksStillRunning() != pdTRUE )
333
                {
334
                        /* Increase the rate at which this task cycles, which will increase the
335
                        rate at which mainCHECK_LED flashes to give visual feedback that an error
336
                        has occurred. */
337
                        pcStatusMessage = "Error: GenQueue";
338
                        xPrintf( pcStatusMessage );
339
                }
340
 
341
                if( xAreQueuePeekTasksStillRunning() != pdTRUE )
342
                {
343
                        pcStatusMessage = "Error: QueuePeek\r\n";
344
                        xPrintf( pcStatusMessage );
345
                }
346
 
347
                if( xAreBlockingQueuesStillRunning() != pdTRUE )
348
                {
349
                        pcStatusMessage = "Error: BlockQueue\r\n";
350
                        xPrintf( pcStatusMessage );
351
                }
352
 
353
                if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
354
                {
355
                        pcStatusMessage = "Error: BlockTime\r\n";
356
                        xPrintf( pcStatusMessage );
357
                }
358
 
359
                if( xAreSemaphoreTasksStillRunning() != pdTRUE )
360
                {
361
                        pcStatusMessage = "Error: SemTest\r\n";
362
                        xPrintf( pcStatusMessage );
363
                }
364
 
365
                if( xArePollingQueuesStillRunning() != pdTRUE )
366
                {
367
                        pcStatusMessage = "Error: PollQueue\r\n";
368
                        xPrintf( pcStatusMessage );
369
                }
370
 
371
                if( xIsCreateTaskStillRunning() != pdTRUE )
372
                {
373
                        pcStatusMessage = "Error: Death\r\n";
374
                        xPrintf( pcStatusMessage );
375
                }
376
 
377
                if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
378
                {
379
                        pcStatusMessage = "Error: IntMath\r\n";
380
                        xPrintf( pcStatusMessage );
381
                }
382
 
383
                if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
384
                {
385
                        pcStatusMessage = "Error: RecMutex\r\n";
386
                        xPrintf( pcStatusMessage );
387
                }
388
 
389
                if( xAreIntQueueTasksStillRunning() != pdPASS )
390
                {
391
                        pcStatusMessage = "Error: IntQueue\r\n";
392
                        xPrintf( pcStatusMessage );
393
                }
394
 
395
                if( xAreMathsTaskStillRunning() != pdPASS )
396
                {
397
                        pcStatusMessage = "Error: Flop\r\n";
398
                        xPrintf( pcStatusMessage );
399
                }
400
 
401
                /* Check the reg test tasks are still cycling.  They will stop incrementing
402
                their loop counters if they encounter an error. */
403
                if( ulRegTest1CycleCount == ulLastRegTest1CycleCount )
404
                {
405
                        pcStatusMessage = "Error: RegTest1\r\n";
406
                        xPrintf( pcStatusMessage );
407
                }
408
 
409
                if( ulRegTest2CycleCount == ulLastRegTest2CycleCount )
410
                {
411
                        pcStatusMessage = "Error: RegTest2\r\n";
412
                        xPrintf( pcStatusMessage );
413
                }
414
 
415
                ulLastRegTest1CycleCount = ulRegTest1CycleCount;
416
                ulLastRegTest2CycleCount = ulRegTest2CycleCount;
417
 
418
                /* Toggle the check LED to give an indication of the system status.  If
419
                the LED toggles every 5 seconds then everything is ok.  A faster toggle
420
                indicates an error. */
421
                vParTestToggleLED( mainCHECK_LED );
422
 
423
                /* Ensure the LED toggles at a faster rate if an error has occurred. */
424
                if( pcStatusMessage != NULL )
425
                {
426
                        xCycleFrequency = mainERROR_CYCLE_TIME;
427
                }
428
        }
429
}
430
/*-----------------------------------------------------------*/
431
 
432
/* The RX port uses this callback function to configure its tick interrupt.
433
This allows the application to choose the tick interrupt source. */
434
void vApplicationSetupTimerInterrupt( void )
435
{
436
        /* Enable compare match timer 0. */
437
        MSTP( CMT0 ) = 0;
438
 
439
        /* Interrupt on compare match. */
440
        CMT0.CMCR.BIT.CMIE = 1;
441
 
442
        /* Set the compare match value. */
443
        CMT0.CMCOR = ( unsigned short ) ( ( ( configPERIPHERAL_CLOCK_HZ / configTICK_RATE_HZ ) -1 ) / 8 );
444
 
445
        /* Divide the PCLK by 8. */
446
        CMT0.CMCR.BIT.CKS = 0;
447
 
448
        /* Enable the interrupt... */
449
        _IEN( _CMT0_CMI0 ) = 1;
450
 
451
        /* ...and set its priority to the application defined kernel priority. */
452
        _IPR( _CMT0_CMI0 ) = configKERNEL_INTERRUPT_PRIORITY;
453
 
454
        /* Start the timer. */
455
        CMT.CMSTR0.BIT.STR0 = 1;
456
}
457
/*-----------------------------------------------------------*/
458
 
459
/* This function is explained by the comments above its prototype at the top
460
of this file. */
461
void vApplicationMallocFailedHook( void )
462
{
463
        for( ;; );
464
}
465
/*-----------------------------------------------------------*/
466
 
467
/* This function is explained by the comments above its prototype at the top
468
of this file. */
469
void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )
470
{
471
        for( ;; );
472
}
473
/*-----------------------------------------------------------*/
474
 
475
/* This function is explained by the comments above its prototype at the top
476
of this file. */
477
void vApplicationIdleHook( void )
478
{
479
}
480
/*-----------------------------------------------------------*/
481
 
482
/* This function is explained in the comments at the top of this file. */
483
static void prvRegTest1Task( void *pvParameters )
484
{
485
        if( ( ( unsigned long ) pvParameters ) != mainREG_TEST_1_PARAMETER )
486
        {
487
                /* The parameter did not contain the expected value. */
488
                for( ;; )
489
                {
490
                        /* Stop the tick interrupt so its obvious something has gone wrong. */
491
                        taskDISABLE_INTERRUPTS();
492
                }
493
        }
494
 
495
        /* This is an asm function that never returns. */
496
        prvRegTest1Implementation();
497
}
498
/*-----------------------------------------------------------*/
499
 
500
/* This function is explained in the comments at the top of this file. */
501
static void prvRegTest2Task( void *pvParameters )
502
{
503
        if( ( ( unsigned long ) pvParameters ) != mainREG_TEST_2_PARAMETER )
504
        {
505
                /* The parameter did not contain the expected value. */
506
                for( ;; )
507
                {
508
                        /* Stop the tick interrupt so its obvious something has gone wrong. */
509
                        taskDISABLE_INTERRUPTS();
510
                }
511
        }
512
 
513
        /* This is an asm function that never returns. */
514
        prvRegTest2Implementation();
515
}
516
/*-----------------------------------------------------------*/
517
 
518
char *pcGetTaskStatusMessage( void )
519
{
520
        /* Not bothered about a critical section here although technically because of
521
        the task priorities the pointer could change it will be atomic if not near
522
        atomic and its not critical. */
523
        if( pcStatusMessage == NULL )
524
        {
525
                return "All tasks running without error";
526
        }
527
        else
528
        {
529
                return ( char * ) pcStatusMessage;
530
        }
531
}
532
/*-----------------------------------------------------------*/
533
 
534
 

powered by: WebSVN 2.1.0

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