]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_LPC1768_IAR/main.c
9ba85480054250f1c9e7babee24d6661592ca1c4
[freertos] / FreeRTOS / Demo / CORTEX_LPC1768_IAR / main.c
1 /*\r
2     FreeRTOS V7.6.0 - Copyright (C) 2013 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     ***************************************************************************\r
8      *                                                                       *\r
9      *    FreeRTOS provides completely free yet professionally developed,    *\r
10      *    robust, strictly quality controlled, supported, and cross          *\r
11      *    platform software that has become a de facto standard.             *\r
12      *                                                                       *\r
13      *    Help yourself get started quickly and support the FreeRTOS         *\r
14      *    project by purchasing a FreeRTOS tutorial book, reference          *\r
15      *    manual, or both from: http://www.FreeRTOS.org/Documentation        *\r
16      *                                                                       *\r
17      *    Thank you!                                                         *\r
18      *                                                                       *\r
19     ***************************************************************************\r
20 \r
21     This file is part of the FreeRTOS distribution.\r
22 \r
23     FreeRTOS is free software; you can redistribute it and/or modify it under\r
24     the terms of the GNU General Public License (version 2) as published by the\r
25     Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
26 \r
27     >>! NOTE: The modification to the GPL is included to allow you to distribute\r
28     >>! a combined work that includes FreeRTOS without being obliged to provide\r
29     >>! the source code for proprietary components outside of the FreeRTOS\r
30     >>! kernel.\r
31 \r
32     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
33     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
34     FOR A PARTICULAR PURPOSE.  Full license text is available from the following\r
35     link: http://www.freertos.org/a00114.html\r
36 \r
37     1 tab == 4 spaces!\r
38 \r
39     ***************************************************************************\r
40      *                                                                       *\r
41      *    Having a problem?  Start by reading the FAQ "My application does   *\r
42      *    not run, what could be wrong?"                                     *\r
43      *                                                                       *\r
44      *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
45      *                                                                       *\r
46     ***************************************************************************\r
47 \r
48     http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
49     license and Real Time Engineers Ltd. contact details.\r
50 \r
51     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
52     including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
53     compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
54 \r
55     http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
56     Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
57     licenses offer ticketed support, indemnification and middleware.\r
58 \r
59     http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
60     engineered and independently SIL3 certified version for use in safety and\r
61     mission critical applications that require provable dependability.\r
62 \r
63     1 tab == 4 spaces!\r
64 */\r
65 \r
66 \r
67 /*\r
68  * Creates all the demo application tasks, then starts the scheduler.  The WEB\r
69  * documentation provides more details of the standard demo application tasks\r
70  * (which just exist to test the kernel port and provide an example of how to use\r
71  * each FreeRTOS API function).\r
72  *\r
73  * In addition to the standard demo tasks, the following tasks and tests are\r
74  * defined and/or created within this file:\r
75  *\r
76  * "Check" hook -  This only executes fully every five seconds from the tick\r
77  * hook.  Its main function is to check that all the standard demo tasks are\r
78  * still operational.  The status can be viewed using on the Task Stats page\r
79  * served by the WEB server.\r
80  *\r
81  * "uIP" task -  This is the task that handles the uIP stack.  All TCP/IP\r
82  * processing is performed in this task.\r
83  *\r
84  * "USB" task - Enumerates the USB device as a CDC class, then echoes back all\r
85  * received characters with a configurable offset (for example, if the offset\r
86  * is 1 and 'A' is received then 'B' will be sent back).  A dumb terminal such\r
87  * as Hyperterminal can be used to talk to the USB task.\r
88  */\r
89 \r
90 /* Scheduler includes. */\r
91 #include "FreeRTOS.h"\r
92 #include "task.h"\r
93 \r
94 /* Demo app includes. */\r
95 #include "BlockQ.h"\r
96 #include "integer.h"\r
97 #include "blocktim.h"\r
98 #include "flash.h"\r
99 #include "partest.h"\r
100 #include "semtest.h"\r
101 #include "PollQ.h"\r
102 #include "GenQTest.h"\r
103 #include "QPeek.h"\r
104 #include "recmutex.h"\r
105 \r
106 /*-----------------------------------------------------------*/\r
107 \r
108 /* The time between cycles of the 'check' functionality (defined within the\r
109 tick hook). */\r
110 #define mainCHECK_DELAY                                         ( ( portTickType ) 5000 / portTICK_RATE_MS )\r
111 \r
112 /* The toggle rate for the LED. */\r
113 #define mainLED_TOGGLE_RATE                                     ( ( portTickType ) 1000 / portTICK_RATE_MS )\r
114 \r
115 /* Task priorities. */\r
116 #define mainQUEUE_POLL_PRIORITY                         ( tskIDLE_PRIORITY + 2 )\r
117 #define mainSEM_TEST_PRIORITY                           ( tskIDLE_PRIORITY + 1 )\r
118 #define mainBLOCK_Q_PRIORITY                            ( tskIDLE_PRIORITY + 2 )\r
119 #define mainUIP_TASK_PRIORITY                           ( tskIDLE_PRIORITY + 3 )\r
120 #define mainFLASH_TASK_PRIORITY                         ( tskIDLE_PRIORITY + 2 )\r
121 #define mainINTEGER_TASK_PRIORITY           ( tskIDLE_PRIORITY )\r
122 #define mainGEN_QUEUE_TASK_PRIORITY                     ( tskIDLE_PRIORITY )\r
123 \r
124 /* The WEB server has a larger stack as it utilises stack hungry string\r
125 handling library calls. */\r
126 #define mainBASIC_WEB_STACK_SIZE            ( configMINIMAL_STACK_SIZE * 4 )\r
127 \r
128 /* The message displayed by the WEB server when all tasks are executing\r
129 without an error being reported. */\r
130 #define mainPASS_STATUS_MESSAGE                         "All tasks are executing without error."\r
131 \r
132 /*-----------------------------------------------------------*/\r
133 \r
134 /*\r
135  * Configure the hardware for the demo.\r
136  */\r
137 static void prvSetupHardware( void );\r
138 \r
139 /*\r
140  * The task that handles the uIP stack.  All TCP/IP processing is performed in\r
141  * this task.\r
142  */\r
143 extern void vuIP_Task( void *pvParameters );\r
144 \r
145 /*\r
146  * The task that handles the USB stack.\r
147  */\r
148 extern void vUSBTask( void *pvParameters );\r
149 \r
150 /*\r
151  * Very basic task that does nothing but use delays to flash an LED.\r
152  */\r
153 static void prvFlashTask( void *pvParameters );\r
154 \r
155 /*\r
156  * Simply returns the current status message for display on served WEB pages.\r
157  */\r
158 char *pcGetTaskStatusMessage( void );\r
159 \r
160 /*-----------------------------------------------------------*/\r
161 \r
162 /* Holds the status message displayed by the WEB server. */\r
163 static char *pcStatusMessage = mainPASS_STATUS_MESSAGE;\r
164 \r
165 /*-----------------------------------------------------------*/\r
166 \r
167 int main( void )\r
168 {\r
169         /* Configure the hardware for use by this demo. */\r
170         prvSetupHardware();\r
171 \r
172         /* Start the standard demo tasks.  These are just here to exercise the\r
173         kernel port and provide examples of how the FreeRTOS API can be used. */\r
174         vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );\r
175     vCreateBlockTimeTasks();\r
176     vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );\r
177     vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );\r
178     vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );\r
179     vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );\r
180     vStartQueuePeekTasks();\r
181     vStartRecursiveMutexTasks();\r
182 \r
183         /* Create the simple LED flash task. */\r
184         xTaskCreate( prvFlashTask, "Flash", configMINIMAL_STACK_SIZE, ( void * ) NULL, mainFLASH_TASK_PRIORITY, NULL );\r
185 \r
186     /* Create the USB task. */\r
187     xTaskCreate( vUSBTask, "USB", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );\r
188 \r
189         /* Create the uIP task.  The WEB server runs in this task. */\r
190     xTaskCreate( vuIP_Task, "uIP", mainBASIC_WEB_STACK_SIZE, ( void * ) NULL, mainUIP_TASK_PRIORITY, NULL );\r
191 \r
192     /* Start the scheduler. */\r
193         vTaskStartScheduler();\r
194 \r
195     /* Will only get here if there was insufficient memory to create the idle\r
196     task.  The idle task is created within vTaskStartScheduler(). */\r
197         for( ;; );\r
198 }\r
199 /*-----------------------------------------------------------*/\r
200 \r
201 void vApplicationTickHook( void )\r
202 {\r
203 static unsigned long ulTicksSinceLastDisplay = 0;\r
204 \r
205         /* Called from every tick interrupt as described in the comments at the top\r
206         of this file.\r
207 \r
208         Have enough ticks passed to make it     time to perform our health status\r
209         check again? */\r
210         ulTicksSinceLastDisplay++;\r
211         if( ulTicksSinceLastDisplay >= mainCHECK_DELAY )\r
212         {\r
213                 /* Reset the counter so these checks run again in mainCHECK_DELAY\r
214                 ticks time. */\r
215                 ulTicksSinceLastDisplay = 0;\r
216 \r
217                 /* Has an error been found in any task? */\r
218                 if( xAreGenericQueueTasksStillRunning() != pdTRUE )\r
219                 {\r
220                         pcStatusMessage = "An error has been detected in the Generic Queue test/demo.";\r
221                 }\r
222                 else if( xAreQueuePeekTasksStillRunning() != pdTRUE )\r
223                 {\r
224                         pcStatusMessage = "An error has been detected in the Peek Queue test/demo.";\r
225                 }\r
226                 else if( xAreBlockingQueuesStillRunning() != pdTRUE )\r
227                 {\r
228                         pcStatusMessage = "An error has been detected in the Block Queue test/demo.";\r
229                 }\r
230                 else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )\r
231                 {\r
232                         pcStatusMessage = "An error has been detected in the Block Time test/demo.";\r
233                 }\r
234             else if( xAreSemaphoreTasksStillRunning() != pdTRUE )\r
235             {\r
236                 pcStatusMessage = "An error has been detected in the Semaphore test/demo.";\r
237             }\r
238             else if( xArePollingQueuesStillRunning() != pdTRUE )\r
239             {\r
240                 pcStatusMessage = "An error has been detected in the Poll Queue test/demo.";\r
241             }\r
242             else if( xAreIntegerMathsTaskStillRunning() != pdTRUE )\r
243             {\r
244                 pcStatusMessage = "An error has been detected in the Int Math test/demo.";\r
245             }\r
246             else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )\r
247             {\r
248                 pcStatusMessage = "An error has been detected in the Mutex test/demo.";\r
249             }\r
250         }\r
251 }\r
252 /*-----------------------------------------------------------*/\r
253 \r
254 static void prvFlashTask( void *pvParameters )\r
255 {\r
256 portTickType xLastFlashTime;\r
257 \r
258         /* We need to initialise xLastFlashTime prior to the first call to\r
259         vTaskDelayUntil(). */\r
260         xLastFlashTime = xTaskGetTickCount();\r
261 \r
262         for(;;)\r
263         {\r
264                 /* Simply toggle the LED between delays. */\r
265                 vTaskDelayUntil( &xLastFlashTime, mainLED_TOGGLE_RATE );\r
266                 vParTestToggleLED( 0 );\r
267         }\r
268 }\r
269 /*-----------------------------------------------------------*/\r
270 \r
271 char *pcGetTaskStatusMessage( void )\r
272 {\r
273         /* Not bothered about a critical section here. */\r
274         return pcStatusMessage;\r
275 }\r
276 /*-----------------------------------------------------------*/\r
277 \r
278 void prvSetupHardware( void )\r
279 {\r
280         /* Disable peripherals power. */\r
281         SC->PCONP = 0;\r
282 \r
283         /* Enable GPIO power. */\r
284         SC->PCONP = PCONP_PCGPIO;\r
285 \r
286         /* Disable TPIU. */\r
287         PINCON->PINSEL10 = 0;\r
288 \r
289         if ( SC->PLL0STAT & ( 1 << 25 ) )\r
290         {\r
291                 /* Enable PLL, disconnected. */\r
292                 SC->PLL0CON = 1;\r
293                 SC->PLL0FEED = PLLFEED_FEED1;\r
294                 SC->PLL0FEED = PLLFEED_FEED2;\r
295         }\r
296 \r
297         /* Disable PLL, disconnected. */\r
298         SC->PLL0CON = 0;\r
299         SC->PLL0FEED = PLLFEED_FEED1;\r
300         SC->PLL0FEED = PLLFEED_FEED2;\r
301 \r
302         /* Enable main OSC. */\r
303         SC->SCS |= 0x20;\r
304         while( !( SC->SCS & 0x40 ) );\r
305 \r
306         /* select main OSC, 12MHz, as the PLL clock source. */\r
307         SC->CLKSRCSEL = 0x1;\r
308 \r
309         SC->PLL0CFG = 0x20031;\r
310         SC->PLL0FEED = PLLFEED_FEED1;\r
311         SC->PLL0FEED = PLLFEED_FEED2;\r
312 \r
313         /* Enable PLL, disconnected. */\r
314         SC->PLL0CON = 1;\r
315         SC->PLL0FEED = PLLFEED_FEED1;\r
316         SC->PLL0FEED = PLLFEED_FEED2;\r
317 \r
318         /* Set clock divider. */\r
319         SC->CCLKCFG = 0x03;\r
320 \r
321         /* Configure flash accelerator. */\r
322         SC->FLASHCFG = 0x403a;\r
323 \r
324         /* Check lock bit status. */\r
325         while( ( ( SC->PLL0STAT & ( 1 << 26 ) ) == 0 ) );\r
326 \r
327         /* Enable and connect. */\r
328         SC->PLL0CON = 3;\r
329         SC->PLL0FEED = PLLFEED_FEED1;\r
330         SC->PLL0FEED = PLLFEED_FEED2;\r
331         while( ( ( SC->PLL0STAT & ( 1 << 25 ) ) == 0 ) );\r
332 \r
333 \r
334 \r
335 \r
336         /* Configure the clock for the USB. */\r
337 \r
338         if( SC->PLL1STAT & ( 1 << 9 ) )\r
339         {\r
340                 /* Enable PLL, disconnected. */\r
341                 SC->PLL1CON = 1;\r
342                 SC->PLL1FEED = PLLFEED_FEED1;\r
343                 SC->PLL1FEED = PLLFEED_FEED2;\r
344         }\r
345 \r
346         /* Disable PLL, disconnected. */\r
347         SC->PLL1CON = 0;\r
348         SC->PLL1FEED = PLLFEED_FEED1;\r
349         SC->PLL1FEED = PLLFEED_FEED2;\r
350 \r
351         SC->PLL1CFG = 0x23;\r
352         SC->PLL1FEED = PLLFEED_FEED1;\r
353         SC->PLL1FEED = PLLFEED_FEED2;\r
354 \r
355         /* Enable PLL, disconnected. */\r
356         SC->PLL1CON = 1;\r
357         SC->PLL1FEED = PLLFEED_FEED1;\r
358         SC->PLL1FEED = PLLFEED_FEED2;\r
359         while( ( ( SC->PLL1STAT & ( 1 << 10 ) ) == 0 ) );\r
360 \r
361         /* Enable and connect. */\r
362         SC->PLL1CON = 3;\r
363         SC->PLL1FEED = PLLFEED_FEED1;\r
364         SC->PLL1FEED = PLLFEED_FEED2;\r
365         while( ( ( SC->PLL1STAT & ( 1 << 9 ) ) == 0 ) );\r
366 \r
367         /*  Setup the peripheral bus to be the same as the PLL output (64 MHz). */\r
368         SC->PCLKSEL0 = 0x05555555;\r
369 \r
370         /* Configure the LEDs. */\r
371         vParTestInitialise();\r
372 }\r
373 /*-----------------------------------------------------------*/\r
374 \r
375 void vApplicationStackOverflowHook( xTaskHandle pxTask, char *pcTaskName )\r
376 {\r
377         /* This function will get called if a task overflows its stack. */\r
378 \r
379         ( void ) pxTask;\r
380         ( void ) pcTaskName;\r
381 \r
382         for( ;; );\r
383 }\r
384 /*-----------------------------------------------------------*/\r
385 \r
386 void vConfigureTimerForRunTimeStats( void )\r
387 {\r
388 const unsigned long TCR_COUNT_RESET = 2, CTCR_CTM_TIMER = 0x00, TCR_COUNT_ENABLE = 0x01;\r
389 \r
390         /* This function configures a timer that is used as the time base when\r
391         collecting run time statistical information - basically the percentage\r
392         of CPU time that each task is utilising.  It is called automatically when\r
393         the scheduler is started (assuming configGENERATE_RUN_TIME_STATS is set\r
394         to 1). */\r
395 \r
396         /* Power up and feed the timer. */\r
397         SC->PCONP |= 0x02UL;\r
398         SC->PCLKSEL0 = (SC->PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2);\r
399 \r
400         /* Reset Timer 0 */\r
401         TIM0->TCR = TCR_COUNT_RESET;\r
402 \r
403         /* Just count up. */\r
404         TIM0->CTCR = CTCR_CTM_TIMER;\r
405 \r
406         /* Prescale to a frequency that is good enough to get a decent resolution,\r
407         but not too fast so as to overflow all the time. */\r
408         TIM0->PR =  ( configCPU_CLOCK_HZ / 10000UL ) - 1UL;\r
409 \r
410         /* Start the counter. */\r
411         TIM0->TCR = TCR_COUNT_ENABLE;\r
412 }\r
413 /*-----------------------------------------------------------*/\r
414 \r