]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_LM3S811_IAR/main.c
Update version numbers in preparation for V8.2.0 release candidate 1.
[freertos] / FreeRTOS / Demo / CORTEX_LM3S811_IAR / main.c
1 /*\r
2     FreeRTOS V8.2.0rc1 - Copyright (C) 2014 Real Time Engineers Ltd.\r
3     All rights reserved\r
4 \r
5     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
6 \r
7     This file is part of the FreeRTOS distribution.\r
8 \r
9     FreeRTOS is free software; you can redistribute it and/or modify it under\r
10     the terms of the GNU General Public License (version 2) as published by the\r
11     Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
12 \r
13     >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
14     >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
15     >>!   obliged to provide the source code for proprietary components     !<<\r
16     >>!   outside of the FreeRTOS kernel.                                   !<<\r
17 \r
18     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
19     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
20     FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
21     link: http://www.freertos.org/a00114.html\r
22 \r
23     1 tab == 4 spaces!\r
24 \r
25     ***************************************************************************\r
26      *                                                                       *\r
27      *    Having a problem?  Start by reading the FAQ "My application does   *\r
28      *    not run, what could be wrong?".  Have you defined configASSERT()?  *\r
29      *                                                                       *\r
30      *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
31      *                                                                       *\r
32     ***************************************************************************\r
33 \r
34     ***************************************************************************\r
35      *                                                                       *\r
36      *    FreeRTOS provides completely free yet professionally developed,    *\r
37      *    robust, strictly quality controlled, supported, and cross          *\r
38      *    platform software that is more than just the market leader, it     *\r
39      *    is the industry's de facto standard.                               *\r
40      *                                                                       *\r
41      *    Help yourself get started quickly while simultaneously helping     *\r
42      *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
43      *    tutorial book, reference manual, or both:                          *\r
44      *    http://www.FreeRTOS.org/Documentation                              *\r
45      *                                                                       *\r
46     ***************************************************************************\r
47 \r
48     ***************************************************************************\r
49      *                                                                       *\r
50      *   Investing in training allows your team to be as productive as       *\r
51      *   possible as early as possible, lowering your overall development    *\r
52      *   cost, and enabling you to bring a more robust product to market     *\r
53      *   earlier than would otherwise be possible.  Richard Barry is both    *\r
54      *   the architect and key author of FreeRTOS, and so also the world's   *\r
55      *   leading authority on what is the world's most popular real time     *\r
56      *   kernel for deeply embedded MCU designs.  Obtaining your training    *\r
57      *   from Richard ensures your team will gain directly from his in-depth *\r
58      *   product knowledge and years of usage experience.  Contact Real Time *\r
59      *   Engineers Ltd to enquire about the FreeRTOS Masterclass, presented  *\r
60      *   by Richard Barry:  http://www.FreeRTOS.org/contact\r
61      *                                                                       *\r
62     ***************************************************************************\r
63 \r
64     ***************************************************************************\r
65      *                                                                       *\r
66      *    You are receiving this top quality software for free.  Please play *\r
67      *    fair and reciprocate by reporting any suspected issues and         *\r
68      *    participating in the community forum:                              *\r
69      *    http://www.FreeRTOS.org/support                                    *\r
70      *                                                                       *\r
71      *    Thank you!                                                         *\r
72      *                                                                       *\r
73     ***************************************************************************\r
74 \r
75     http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
76     license and Real Time Engineers Ltd. contact details.\r
77 \r
78     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
79     including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
80     compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
81 \r
82     http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
83     Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
84 \r
85     http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
86     Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
87     licenses offer ticketed support, indemnification and commercial middleware.\r
88 \r
89     http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
90     engineered and independently SIL3 certified version for use in safety and\r
91     mission critical applications that require provable dependability.\r
92 \r
93     1 tab == 4 spaces!\r
94 */\r
95 \r
96 \r
97 /*\r
98  * This project contains an application demonstrating the use of the\r
99  * FreeRTOS.org mini real time scheduler on the Luminary Micro LM3S811 Eval\r
100  * board.  See http://www.FreeRTOS.org for more information.\r
101  *\r
102  * main() simply sets up the hardware, creates all the demo application tasks,\r
103  * then starts the scheduler.  http://www.freertos.org/a00102.html provides\r
104  * more information on the standard demo tasks.\r
105  *\r
106  * In addition to a subset of the standard demo application tasks, main.c also\r
107  * defines the following tasks:\r
108  *\r
109  * + A 'Print' task.  The print task is the only task permitted to access the\r
110  * LCD - thus ensuring mutual exclusion and consistent access to the resource.\r
111  * Other tasks do not access the LCD directly, but instead send the text they\r
112  * wish to display to the print task.  The print task spends most of its time\r
113  * blocked - only waking when a message is queued for display.\r
114  *\r
115  * + A 'Button handler' task.  The eval board contains a user push button that\r
116  * is configured to generate interrupts.  The interrupt handler uses a\r
117  * semaphore to wake the button handler task - demonstrating how the priority\r
118  * mechanism can be used to defer interrupt processing to the task level.  The\r
119  * button handler task sends a message both to the LCD (via the print task) and\r
120  * the UART where it can be viewed using a dumb terminal (via the UART to USB\r
121  * converter on the eval board).  NOTES:  The dumb terminal must be closed in\r
122  * order to reflash the microcontroller.  A very basic interrupt driven UART\r
123  * driver is used that does not use the FIFO.  19200 baud is used.\r
124  *\r
125  * + A 'check' task.  The check task only executes every five seconds but has a\r
126  * high priority so is guaranteed to get processor time.  Its function is to\r
127  * check that all the other tasks are still operational and that no errors have\r
128  * been detected at any time.  If no errors have every been detected 'PASS' is\r
129  * written to the display (via the print task) - if an error has ever been\r
130  * detected the message is changed to 'FAIL'.  The position of the message is\r
131  * changed for each write.\r
132  */\r
133 \r
134 \r
135 \r
136 /* Environment includes. */\r
137 #include "DriverLib.h"\r
138 \r
139 /* Scheduler includes. */\r
140 #include "FreeRTOS.h"\r
141 #include "task.h"\r
142 #include "queue.h"\r
143 #include "semphr.h"\r
144 \r
145 /* Demo app includes. */\r
146 #include "integer.h"\r
147 #include "PollQ.h"\r
148 #include "semtest.h"\r
149 #include "BlockQ.h"\r
150 \r
151 /* Delay between cycles of the 'check' task. */\r
152 #define mainCHECK_DELAY                                         ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )\r
153 \r
154 /* UART configuration - note this does not use the FIFO so is not very\r
155 efficient. */\r
156 #define mainBAUD_RATE                           ( 19200 )\r
157 #define mainFIFO_SET                            ( 0x10 )\r
158 \r
159 /* Demo task priorities. */\r
160 #define mainQUEUE_POLL_PRIORITY         ( tskIDLE_PRIORITY + 2 )\r
161 #define mainCHECK_TASK_PRIORITY         ( tskIDLE_PRIORITY + 3 )\r
162 #define mainSEM_TEST_PRIORITY           ( tskIDLE_PRIORITY + 1 )\r
163 #define mainBLOCK_Q_PRIORITY            ( tskIDLE_PRIORITY + 2 )\r
164 \r
165 /* Demo board specifics. */\r
166 #define mainPUSH_BUTTON             GPIO_PIN_4\r
167 \r
168 /* Misc. */\r
169 #define mainQUEUE_SIZE                          ( 3 )\r
170 #define mainDEBOUNCE_DELAY                      ( ( TickType_t ) 150 / portTICK_PERIOD_MS )\r
171 #define mainNO_DELAY                            ( ( TickType_t ) 0 )\r
172 /*\r
173  * Configure the processor and peripherals for this demo.\r
174  */\r
175 static void prvSetupHardware( void );\r
176 \r
177 /*\r
178  * The 'check' task, as described at the top of this file.\r
179  */\r
180 static void vCheckTask( void *pvParameters );\r
181 \r
182 /*\r
183  * The task that is woken by the ISR that processes GPIO interrupts originating\r
184  * from the push button.\r
185  */\r
186 static void vButtonHandlerTask( void *pvParameters );\r
187 \r
188 /*\r
189  * The task that controls access to the LCD.\r
190  */\r
191 static void vPrintTask( void *pvParameter );\r
192 \r
193 /* String that is transmitted on the UART. */\r
194 static char *cMessage = "Task woken by button interrupt! --- ";\r
195 static volatile char *pcNextChar;\r
196 \r
197 /* The semaphore used to wake the button handler task from within the GPIO\r
198 interrupt handler. */\r
199 SemaphoreHandle_t xButtonSemaphore;\r
200 \r
201 /* The queue used to send strings to the print task for display on the LCD. */\r
202 QueueHandle_t xPrintQueue;\r
203 \r
204 /*-----------------------------------------------------------*/\r
205 \r
206 int main( void )\r
207 {\r
208         /* Configure the clocks, UART and GPIO. */\r
209         prvSetupHardware();\r
210 \r
211         /* Create the semaphore used to wake the button handler task from the GPIO\r
212         ISR. */\r
213         vSemaphoreCreateBinary( xButtonSemaphore );\r
214         xSemaphoreTake( xButtonSemaphore, 0 );\r
215 \r
216         /* Create the queue used to pass message to vPrintTask. */\r
217         xPrintQueue = xQueueCreate( mainQUEUE_SIZE, sizeof( char * ) );\r
218 \r
219         /* Start the standard demo tasks. */\r
220         vStartIntegerMathTasks( tskIDLE_PRIORITY );\r
221         vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );\r
222         vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );\r
223         vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );\r
224 \r
225         /* Start the tasks defined within the file. */\r
226         xTaskCreate( vCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );\r
227         xTaskCreate( vButtonHandlerTask, "Status", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY + 1, NULL );\r
228         xTaskCreate( vPrintTask, "Print", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY - 1, NULL );\r
229 \r
230         /* Start the scheduler. */\r
231         vTaskStartScheduler();\r
232 \r
233         /* Will only get here if there was insufficient heap to start the\r
234         scheduler. */\r
235 \r
236         return 0;\r
237 }\r
238 /*-----------------------------------------------------------*/\r
239 \r
240 static void vCheckTask( void *pvParameters )\r
241 {\r
242 portBASE_TYPE xErrorOccurred = pdFALSE;\r
243 TickType_t xLastExecutionTime;\r
244 const char *pcPassMessage = "PASS";\r
245 const char *pcFailMessage = "FAIL";\r
246 \r
247         /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()\r
248         works correctly. */\r
249         xLastExecutionTime = xTaskGetTickCount();\r
250 \r
251         for( ;; )\r
252         {\r
253                 /* Perform this check every mainCHECK_DELAY milliseconds. */\r
254                 vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );\r
255 \r
256                 /* Has an error been found in any task? */\r
257 \r
258                 if( xAreIntegerMathsTaskStillRunning() != pdTRUE )\r
259                 {\r
260                         xErrorOccurred = pdTRUE;\r
261                 }\r
262         \r
263                 if( xArePollingQueuesStillRunning() != pdTRUE )\r
264                 {\r
265                         xErrorOccurred = pdTRUE;\r
266                 }\r
267         \r
268                 if( xAreSemaphoreTasksStillRunning() != pdTRUE )\r
269                 {\r
270                         xErrorOccurred = pdTRUE;\r
271                 }\r
272 \r
273                 if( xAreBlockingQueuesStillRunning() != pdTRUE )\r
274                 {\r
275                         xErrorOccurred = pdTRUE;\r
276                 }\r
277 \r
278                 /* Send either a pass or fail message.  If an error is found it is\r
279                 never cleared again.  We do not write directly to the LCD, but instead\r
280                 queue a message for display by the print task. */\r
281                 if( xErrorOccurred == pdTRUE )\r
282                 {\r
283                         xQueueSend( xPrintQueue, &pcFailMessage, portMAX_DELAY );\r
284                 }\r
285                 else\r
286                 {\r
287                         xQueueSend( xPrintQueue, &pcPassMessage, portMAX_DELAY );\r
288                 }\r
289         }\r
290 }\r
291 /*-----------------------------------------------------------*/\r
292 \r
293 static void prvSetupHardware( void )\r
294 {\r
295         /* Setup the PLL. */\r
296         SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ );\r
297 \r
298         /* Setup the push button. */\r
299         SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);\r
300     GPIODirModeSet(GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN);\r
301         GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON,GPIO_FALLING_EDGE );\r
302         IntPrioritySet( INT_GPIOC, configKERNEL_INTERRUPT_PRIORITY );\r
303         GPIOPinIntEnable( GPIO_PORTC_BASE, mainPUSH_BUTTON );\r
304         IntEnable( INT_GPIOC );\r
305 \r
306 \r
307 \r
308         /* Enable the UART.  */\r
309         SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);\r
310         SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);\r
311 \r
312         /* Set GPIO A0 and A1 as peripheral function.  They are used to output the\r
313         UART signals. */\r
314         GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW );\r
315 \r
316         /* Configure the UART for 8-N-1 operation. */\r
317         UARTConfigSetExpClk( UART0_BASE, SysCtlClockGet(), mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE );\r
318 \r
319         /* We don't want to use the fifo.  This is for test purposes to generate\r
320         as many interrupts as possible. */\r
321         HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET;\r
322 \r
323         /* Enable Tx interrupts. */\r
324         HWREG( UART0_BASE + UART_O_IM ) |= UART_INT_TX;\r
325         IntPrioritySet( INT_UART0, configKERNEL_INTERRUPT_PRIORITY );\r
326         IntEnable( INT_UART0 );\r
327 \r
328 \r
329         /* Initialise the LCD> */\r
330     OSRAMInit( false );\r
331     OSRAMStringDraw("www.FreeRTOS.org", 0, 0);\r
332         OSRAMStringDraw("LM3S811 demo", 16, 1);\r
333 }\r
334 /*-----------------------------------------------------------*/\r
335 \r
336 static void vButtonHandlerTask( void *pvParameters )\r
337 {\r
338 const char *pcInterruptMessage = "Int";\r
339 \r
340         for( ;; )\r
341         {\r
342                 /* Wait for a GPIO interrupt to wake this task. */\r
343                 while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS );\r
344 \r
345                 /* Start the Tx of the message on the UART. */\r
346                 UARTIntDisable( UART0_BASE, UART_INT_TX );\r
347                 {\r
348                         pcNextChar = cMessage;\r
349 \r
350                         /* Send the first character. */\r
351                         if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) )\r
352                         {\r
353                                 HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar;\r
354                         }\r
355 \r
356                         pcNextChar++;\r
357                 }\r
358                 UARTIntEnable(UART0_BASE, UART_INT_TX);\r
359 \r
360                 /* Queue a message for the print task to display on the LCD. */\r
361                 xQueueSend( xPrintQueue, &pcInterruptMessage, portMAX_DELAY );\r
362 \r
363                 /* Make sure we don't process bounces. */\r
364                 vTaskDelay( mainDEBOUNCE_DELAY );\r
365                 xSemaphoreTake( xButtonSemaphore, mainNO_DELAY );\r
366         }\r
367 }\r
368 \r
369 /*-----------------------------------------------------------*/\r
370 \r
371 void vUART_ISR(void)\r
372 {\r
373 unsigned long ulStatus;\r
374 \r
375         /* What caused the interrupt. */\r
376         ulStatus = UARTIntStatus( UART0_BASE, pdTRUE );\r
377 \r
378         /* Clear the interrupt. */\r
379         UARTIntClear( UART0_BASE, ulStatus );\r
380 \r
381         /* Was a Tx interrupt pending? */\r
382         if( ulStatus & UART_INT_TX )\r
383         {\r
384                 /* Send the next character in the string.  We are not using the FIFO. */\r
385                 if( *pcNextChar != NULL )\r
386                 {\r
387                         if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) )\r
388                         {\r
389                                 HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar;\r
390                         }\r
391                         pcNextChar++;\r
392                 }\r
393         }\r
394 }\r
395 /*-----------------------------------------------------------*/\r
396 \r
397 void vGPIO_ISR( void )\r
398 {\r
399 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
400 \r
401         /* Clear the interrupt. */\r
402         GPIOPinIntClear(GPIO_PORTC_BASE, mainPUSH_BUTTON);\r
403 \r
404         /* Wake the button handler task. */\r
405         xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken );\r
406         portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );\r
407 }\r
408 /*-----------------------------------------------------------*/\r
409 \r
410 static void vPrintTask( void *pvParameters )\r
411 {\r
412 char *pcMessage;\r
413 unsigned portBASE_TYPE uxLine = 0, uxRow = 0;\r
414 \r
415         for( ;; )\r
416         {\r
417                 /* Wait for a message to arrive. */\r
418                 xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY );\r
419 \r
420                 /* Write the message to the LCD. */\r
421                 uxRow++;\r
422                 uxLine++;\r
423                 OSRAMClear();\r
424                 OSRAMStringDraw( pcMessage, uxLine & 0x3f, uxRow & 0x01);\r
425         }\r
426 }\r
427 \r