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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 581 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
/*
56
 * This project contains an application demonstrating the use of the
57
 * FreeRTOS.org mini real time scheduler on the Luminary Micro LM3S811 Eval
58
 * board.  See http://www.FreeRTOS.org for more information.
59
 *
60
 * main() simply sets up the hardware, creates all the demo application tasks,
61
 * then starts the scheduler.  http://www.freertos.org/a00102.html provides
62
 * more information on the standard demo tasks.
63
 *
64
 * In addition to a subset of the standard demo application tasks, main.c also
65
 * defines the following tasks:
66
 *
67
 * + A 'Print' task.  The print task is the only task permitted to access the
68
 * LCD - thus ensuring mutual exclusion and consistent access to the resource.
69
 * Other tasks do not access the LCD directly, but instead send the text they
70
 * wish to display to the print task.  The print task spends most of its time
71
 * blocked - only waking when a message is queued for display.
72
 *
73
 * + A 'Button handler' task.  The eval board contains a user push button that
74
 * is configured to generate interrupts.  The interrupt handler uses a
75
 * semaphore to wake the button handler task - demonstrating how the priority
76
 * mechanism can be used to defer interrupt processing to the task level.  The
77
 * button handler task sends a message both to the LCD (via the print task) and
78
 * the UART where it can be viewed using a dumb terminal (via the UART to USB
79
 * converter on the eval board).  NOTES:  The dumb terminal must be closed in
80
 * order to reflash the microcontroller.  A very basic interrupt driven UART
81
 * driver is used that does not use the FIFO.  19200 baud is used.
82
 *
83
 * + A 'check' task.  The check task only executes every five seconds but has a
84
 * high priority so is guaranteed to get processor time.  Its function is to
85
 * check that all the other tasks are still operational and that no errors have
86
 * been detected at any time.  If no errors have every been detected 'PASS' is
87
 * written to the display (via the print task) - if an error has ever been
88
 * detected the message is changed to 'FAIL'.  The position of the message is
89
 * changed for each write.
90
 */
91
 
92
 
93
 
94
/* Environment includes. */
95
#include "DriverLib.h"
96
 
97
/* Scheduler includes. */
98
#include "FreeRTOS.h"
99
#include "task.h"
100
#include "queue.h"
101
#include "semphr.h"
102
 
103
/* Demo app includes. */
104
#include "integer.h"
105
#include "PollQ.h"
106
#include "semtest.h"
107
#include "BlockQ.h"
108
 
109
/* Delay between cycles of the 'check' task. */
110
#define mainCHECK_DELAY                                         ( ( portTickType ) 5000 / portTICK_RATE_MS )
111
 
112
/* UART configuration - note this does not use the FIFO so is not very
113
efficient. */
114
#define mainBAUD_RATE                           ( 19200 )
115
#define mainFIFO_SET                            ( 0x10 )
116
 
117
/* Demo task priorities. */
118
#define mainQUEUE_POLL_PRIORITY         ( tskIDLE_PRIORITY + 2 )
119
#define mainCHECK_TASK_PRIORITY         ( tskIDLE_PRIORITY + 3 )
120
#define mainSEM_TEST_PRIORITY           ( tskIDLE_PRIORITY + 1 )
121
#define mainBLOCK_Q_PRIORITY            ( tskIDLE_PRIORITY + 2 )
122
 
123
/* Demo board specifics. */
124
#define mainPUSH_BUTTON             GPIO_PIN_4
125
 
126
/* Misc. */
127
#define mainQUEUE_SIZE                          ( 3 )
128
#define mainDEBOUNCE_DELAY                      ( ( portTickType ) 150 / portTICK_RATE_MS )
129
#define mainNO_DELAY                            ( ( portTickType ) 0 )
130
/*
131
 * Configure the processor and peripherals for this demo.
132
 */
133
static void prvSetupHardware( void );
134
 
135
/*
136
 * The 'check' task, as described at the top of this file.
137
 */
138
static void vCheckTask( void *pvParameters );
139
 
140
/*
141
 * The task that is woken by the ISR that processes GPIO interrupts originating
142
 * from the push button.
143
 */
144
static void vButtonHandlerTask( void *pvParameters );
145
 
146
/*
147
 * The task that controls access to the LCD.
148
 */
149
static void vPrintTask( void *pvParameter );
150
 
151
/* String that is transmitted on the UART. */
152
static portCHAR *cMessage = "Task woken by button interrupt! --- ";
153
static volatile portCHAR *pcNextChar;
154
 
155
/* The semaphore used to wake the button handler task from within the GPIO
156
interrupt handler. */
157
xSemaphoreHandle xButtonSemaphore;
158
 
159
/* The queue used to send strings to the print task for display on the LCD. */
160
xQueueHandle xPrintQueue;
161
 
162
/*-----------------------------------------------------------*/
163
 
164
int main( void )
165
{
166
        /* Configure the clocks, UART and GPIO. */
167
        prvSetupHardware();
168
 
169
        /* Create the semaphore used to wake the button handler task from the GPIO
170
        ISR. */
171
        vSemaphoreCreateBinary( xButtonSemaphore );
172
        xSemaphoreTake( xButtonSemaphore, 0 );
173
 
174
        /* Create the queue used to pass message to vPrintTask. */
175
        xPrintQueue = xQueueCreate( mainQUEUE_SIZE, sizeof( portCHAR * ) );
176
 
177
        /* Start the standard demo tasks. */
178
        vStartIntegerMathTasks( tskIDLE_PRIORITY );
179
        vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
180
        vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
181
        vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
182
 
183
        /* Start the tasks defined within the file. */
184
        xTaskCreate( vCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
185
        xTaskCreate( vButtonHandlerTask, "Status", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY + 1, NULL );
186
        xTaskCreate( vPrintTask, "Print", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY - 1, NULL );
187
 
188
        /* Start the scheduler. */
189
        vTaskStartScheduler();
190
 
191
        /* Will only get here if there was insufficient heap to start the
192
        scheduler. */
193
 
194
        return 0;
195
}
196
/*-----------------------------------------------------------*/
197
 
198
static void vCheckTask( void *pvParameters )
199
{
200
portBASE_TYPE xErrorOccurred = pdFALSE;
201
portTickType xLastExecutionTime;
202
const portCHAR *pcPassMessage = "PASS";
203
const portCHAR *pcFailMessage = "FAIL";
204
 
205
        /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
206
        works correctly. */
207
        xLastExecutionTime = xTaskGetTickCount();
208
 
209
        for( ;; )
210
        {
211
                /* Perform this check every mainCHECK_DELAY milliseconds. */
212
                vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );
213
 
214
                /* Has an error been found in any task? */
215
 
216
                if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
217
                {
218
                        xErrorOccurred = pdTRUE;
219
                }
220
 
221
                if( xArePollingQueuesStillRunning() != pdTRUE )
222
                {
223
                        xErrorOccurred = pdTRUE;
224
                }
225
 
226
                if( xAreSemaphoreTasksStillRunning() != pdTRUE )
227
                {
228
                        xErrorOccurred = pdTRUE;
229
                }
230
 
231
                if( xAreBlockingQueuesStillRunning() != pdTRUE )
232
                {
233
                        xErrorOccurred = pdTRUE;
234
                }
235
 
236
                /* Send either a pass or fail message.  If an error is found it is
237
                never cleared again.  We do not write directly to the LCD, but instead
238
                queue a message for display by the print task. */
239
                if( xErrorOccurred == pdTRUE )
240
                {
241
                        xQueueSend( xPrintQueue, &pcFailMessage, portMAX_DELAY );
242
                }
243
                else
244
                {
245
                        xQueueSend( xPrintQueue, &pcPassMessage, portMAX_DELAY );
246
                }
247
        }
248
}
249
/*-----------------------------------------------------------*/
250
 
251
static void prvSetupHardware( void )
252
{
253
        /* Setup the PLL. */
254
        SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ );
255
 
256
        /* Setup the push button. */
257
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
258
    GPIODirModeSet(GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN);
259
        GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON,GPIO_FALLING_EDGE );
260
        IntPrioritySet( INT_GPIOC, configKERNEL_INTERRUPT_PRIORITY );
261
        GPIOPinIntEnable( GPIO_PORTC_BASE, mainPUSH_BUTTON );
262
        IntEnable( INT_GPIOC );
263
 
264
 
265
 
266
        /* Enable the UART.  */
267
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
268
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
269
 
270
        /* Set GPIO A0 and A1 as peripheral function.  They are used to output the
271
        UART signals. */
272
        GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW );
273
 
274
        /* Configure the UART for 8-N-1 operation. */
275
        UARTConfigSet( UART0_BASE, mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE );
276
 
277
        /* We don't want to use the fifo.  This is for test purposes to generate
278
        as many interrupts as possible. */
279
        HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET;
280
 
281
        /* Enable Tx interrupts. */
282
        HWREG( UART0_BASE + UART_O_IM ) |= UART_INT_TX;
283
        IntPrioritySet( INT_UART0, configKERNEL_INTERRUPT_PRIORITY );
284
        IntEnable( INT_UART0 );
285
 
286
 
287
        /* Initialise the LCD> */
288
    OSRAMInit( false );
289
    OSRAMStringDraw("www.FreeRTOS.org", 0, 0);
290
        OSRAMStringDraw("LM3S811 demo", 16, 1);
291
}
292
/*-----------------------------------------------------------*/
293
 
294
static void vButtonHandlerTask( void *pvParameters )
295
{
296
const portCHAR *pcInterruptMessage = "Int";
297
 
298
        for( ;; )
299
        {
300
                /* Wait for a GPIO interrupt to wake this task. */
301
                while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS );
302
 
303
                /* Start the Tx of the message on the UART. */
304
                UARTIntDisable( UART0_BASE, UART_INT_TX );
305
                {
306
                        pcNextChar = cMessage;
307
 
308
                        /* Send the first character. */
309
                        if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) )
310
                        {
311
                                HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar;
312
                        }
313
 
314
                        pcNextChar++;
315
                }
316
                UARTIntEnable(UART0_BASE, UART_INT_TX);
317
 
318
                /* Queue a message for the print task to display on the LCD. */
319
                xQueueSend( xPrintQueue, &pcInterruptMessage, portMAX_DELAY );
320
 
321
                /* Make sure we don't process bounces. */
322
                vTaskDelay( mainDEBOUNCE_DELAY );
323
                xSemaphoreTake( xButtonSemaphore, mainNO_DELAY );
324
        }
325
}
326
 
327
/*-----------------------------------------------------------*/
328
 
329
void vUART_ISR(void)
330
{
331
unsigned portLONG ulStatus;
332
 
333
        /* What caused the interrupt. */
334
        ulStatus = UARTIntStatus( UART0_BASE, pdTRUE );
335
 
336
        /* Clear the interrupt. */
337
        UARTIntClear( UART0_BASE, ulStatus );
338
 
339
        /* Was a Tx interrupt pending? */
340
        if( ulStatus & UART_INT_TX )
341
        {
342
                /* Send the next character in the string.  We are not using the FIFO. */
343
                if( *pcNextChar != 0 )
344
                {
345
                        if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) )
346
                        {
347
                                HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar;
348
                        }
349
                        pcNextChar++;
350
                }
351
        }
352
}
353
/*-----------------------------------------------------------*/
354
 
355
void vGPIO_ISR( void )
356
{
357
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
358
 
359
        /* Clear the interrupt. */
360
        GPIOPinIntClear(GPIO_PORTC_BASE, mainPUSH_BUTTON);
361
 
362
        /* Wake the button handler task. */
363
        xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken );
364
 
365
        portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
366
}
367
/*-----------------------------------------------------------*/
368
 
369
static void vPrintTask( void *pvParameters )
370
{
371
portCHAR *pcMessage;
372
unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
373
 
374
        for( ;; )
375
        {
376
                /* Wait for a message to arrive. */
377
                xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY );
378
 
379
                /* Write the message to the LCD. */
380
                uxRow++;
381
                uxLine++;
382
                OSRAMClear();
383
                OSRAMStringDraw( pcMessage, uxLine & 0x3f, uxRow & 0x01);
384
        }
385
}
386
 

powered by: WebSVN 2.1.0

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