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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [CORTEX_LM3S811_KEIL/] [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 char *cMessage = "Task woken by button interrupt! --- ";
153
static volatile char *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
/* Newer library version. */
163
extern void UARTConfigSetExpClk(unsigned long ulBase, unsigned long ulUARTClk, unsigned long ulBaud, unsigned long ulConfig);
164
/*-----------------------------------------------------------*/
165
 
166
int main( void )
167
{
168
        /* Configure the clocks, UART and GPIO. */
169
        prvSetupHardware();
170
 
171
        /* Create the semaphore used to wake the button handler task from the GPIO
172
        ISR. */
173
        vSemaphoreCreateBinary( xButtonSemaphore );
174
        xSemaphoreTake( xButtonSemaphore, 0 );
175
 
176
        /* Create the queue used to pass message to vPrintTask. */
177
        xPrintQueue = xQueueCreate( mainQUEUE_SIZE, sizeof( char * ) );
178
 
179
        /* Start the standard demo tasks. */
180
        vStartIntegerMathTasks( tskIDLE_PRIORITY );
181
        vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
182
        vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
183
        vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
184
 
185
        /* Start the tasks defined within the file. */
186
        xTaskCreate( vCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
187
        xTaskCreate( vButtonHandlerTask, "Status", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY + 1, NULL );
188
        xTaskCreate( vPrintTask, "Print", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY - 1, NULL );
189
 
190
        /* Start the scheduler. */
191
        vTaskStartScheduler();
192
 
193
        /* Will only get here if there was insufficient heap to start the
194
        scheduler. */
195
 
196
        return 0;
197
}
198
/*-----------------------------------------------------------*/
199
 
200
static void vCheckTask( void *pvParameters )
201
{
202
portBASE_TYPE xErrorOccurred = pdFALSE;
203
portTickType xLastExecutionTime;
204
const char *pcPassMessage = "PASS";
205
const char *pcFailMessage = "FAIL";
206
 
207
        /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
208
        works correctly. */
209
        xLastExecutionTime = xTaskGetTickCount();
210
 
211
        for( ;; )
212
        {
213
                /* Perform this check every mainCHECK_DELAY milliseconds. */
214
                vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );
215
 
216
                /* Has an error been found in any task? */
217
 
218
                if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
219
                {
220
                        xErrorOccurred = pdTRUE;
221
                }
222
 
223
                if( xArePollingQueuesStillRunning() != pdTRUE )
224
                {
225
                        xErrorOccurred = pdTRUE;
226
                }
227
 
228
                if( xAreSemaphoreTasksStillRunning() != pdTRUE )
229
                {
230
                        xErrorOccurred = pdTRUE;
231
                }
232
 
233
                if( xAreBlockingQueuesStillRunning() != pdTRUE )
234
                {
235
                        xErrorOccurred = pdTRUE;
236
                }
237
 
238
                /* Send either a pass or fail message.  If an error is found it is
239
                never cleared again.  We do not write directly to the LCD, but instead
240
                queue a message for display by the print task. */
241
                if( xErrorOccurred == pdTRUE )
242
                {
243
                        xQueueSend( xPrintQueue, &pcFailMessage, portMAX_DELAY );
244
                }
245
                else
246
                {
247
                        xQueueSend( xPrintQueue, &pcPassMessage, portMAX_DELAY );
248
                }
249
        }
250
}
251
/*-----------------------------------------------------------*/
252
 
253
static void prvSetupHardware( void )
254
{
255
        /* Setup the PLL. */
256
        SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ );
257
 
258
        /* Setup the push button. */
259
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
260
    GPIODirModeSet(GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN);
261
        GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON,GPIO_FALLING_EDGE );
262
        IntPrioritySet( INT_GPIOC, configKERNEL_INTERRUPT_PRIORITY );
263
        GPIOPinIntEnable( GPIO_PORTC_BASE, mainPUSH_BUTTON );
264
        IntEnable( INT_GPIOC );
265
 
266
 
267
 
268
        /* Enable the UART.  */
269
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
270
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
271
 
272
        /* Set GPIO A0 and A1 as peripheral function.  They are used to output the
273
        UART signals. */
274
        GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW );
275
 
276
        /* Configure the UART for 8-N-1 operation. */
277
        UARTConfigSetExpClk( UART0_BASE, SysCtlClockGet(), mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE );
278
 
279
        /* We don't want to use the fifo.  This is for test purposes to generate
280
        as many interrupts as possible. */
281
        HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET;
282
 
283
        /* Enable Tx interrupts. */
284
        HWREG( UART0_BASE + UART_O_IM ) |= UART_INT_TX;
285
        IntPrioritySet( INT_UART0, configKERNEL_INTERRUPT_PRIORITY );
286
        IntEnable( INT_UART0 );
287
 
288
 
289
        /* Initialise the LCD> */
290
    OSRAMInit( false );
291
    OSRAMStringDraw("www.FreeRTOS.org", 0, 0);
292
        OSRAMStringDraw("LM3S811 demo", 16, 1);
293
}
294
/*-----------------------------------------------------------*/
295
 
296
static void vButtonHandlerTask( void *pvParameters )
297
{
298
const char *pcInterruptMessage = "Int";
299
 
300
        for( ;; )
301
        {
302
                /* Wait for a GPIO interrupt to wake this task. */
303
                while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS );
304
 
305
                /* Start the Tx of the message on the UART. */
306
                UARTIntDisable( UART0_BASE, UART_INT_TX );
307
                {
308
                        pcNextChar = cMessage;
309
 
310
                        /* Send the first character. */
311
                        if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) )
312
                        {
313
                                HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar;
314
                        }
315
 
316
                        pcNextChar++;
317
                }
318
                UARTIntEnable(UART0_BASE, UART_INT_TX);
319
 
320
                /* Queue a message for the print task to display on the LCD. */
321
                xQueueSend( xPrintQueue, &pcInterruptMessage, portMAX_DELAY );
322
 
323
                /* Make sure we don't process bounces. */
324
                vTaskDelay( mainDEBOUNCE_DELAY );
325
                xSemaphoreTake( xButtonSemaphore, mainNO_DELAY );
326
        }
327
}
328
 
329
/*-----------------------------------------------------------*/
330
 
331
void vUART_ISR(void)
332
{
333
unsigned long ulStatus;
334
 
335
        /* What caused the interrupt. */
336
        ulStatus = UARTIntStatus( UART0_BASE, pdTRUE );
337
 
338
        /* Clear the interrupt. */
339
        UARTIntClear( UART0_BASE, ulStatus );
340
 
341
        /* Was a Tx interrupt pending? */
342
        if( ulStatus & UART_INT_TX )
343
        {
344
                /* Send the next character in the string.  We are not using the FIFO. */
345
                if( *pcNextChar != NULL )
346
                {
347
                        if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) )
348
                        {
349
                                HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar;
350
                        }
351
                        pcNextChar++;
352
                }
353
        }
354
}
355
/*-----------------------------------------------------------*/
356
 
357
void vGPIO_ISR( void )
358
{
359
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
360
 
361
        /* Clear the interrupt. */
362
        GPIOPinIntClear( GPIO_PORTC_BASE, mainPUSH_BUTTON );
363
 
364
        /* Wake the button handler task. */
365
        xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken );
366
        portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
367
}
368
/*-----------------------------------------------------------*/
369
 
370
static void vPrintTask( void *pvParameters )
371
{
372
char *pcMessage;
373
unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
374
 
375
        for( ;; )
376
        {
377
                /* Wait for a message to arrive. */
378
                xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY );
379
 
380
                /* Write the message to the LCD. */
381
                uxRow++;
382
                uxLine++;
383
                OSRAMClear();
384
                OSRAMStringDraw( pcMessage, uxLine & 0x3f, uxRow & 0x01);
385
        }
386
}
387
 

powered by: WebSVN 2.1.0

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