]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/ARM9_STR91X_IAR/main.c
Update version numbers to V7.4.1.
[freertos] / FreeRTOS / Demo / ARM9_STR91X_IAR / main.c
1 /*\r
2     FreeRTOS V7.4.1 - Copyright (C) 2013 Real Time Engineers Ltd.\r
3 \r
4     FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME.  PLEASE VISIT\r
5     http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
6 \r
7     ***************************************************************************\r
8      *                                                                       *\r
9      *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
10      *    Complete, revised, and edited pdf reference manuals are also       *\r
11      *    available.                                                         *\r
12      *                                                                       *\r
13      *    Purchasing FreeRTOS documentation will not only help you, by       *\r
14      *    ensuring you get running as quickly as possible and with an        *\r
15      *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
16      *    the FreeRTOS project to continue with its mission of providing     *\r
17      *    professional grade, cross platform, de facto standard solutions    *\r
18      *    for microcontrollers - completely free of charge!                  *\r
19      *                                                                       *\r
20      *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
21      *                                                                       *\r
22      *    Thank you for using FreeRTOS, and thank you for your support!      *\r
23      *                                                                       *\r
24     ***************************************************************************\r
25 \r
26 \r
27     This file is part of the FreeRTOS distribution.\r
28 \r
29     FreeRTOS is free software; you can redistribute it and/or modify it under\r
30     the terms of the GNU General Public License (version 2) as published by the\r
31     Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
32 \r
33     >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to\r
34     distribute a combined work that includes FreeRTOS without being obliged to\r
35     provide the source code for proprietary components outside of the FreeRTOS\r
36     kernel.\r
37 \r
38     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
39     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
40     FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more\r
41     details. You should have received a copy of the GNU General Public License\r
42     and the FreeRTOS license exception along with FreeRTOS; if not it can be\r
43     viewed here: http://www.freertos.org/a00114.html and also obtained by\r
44     writing to Real Time Engineers Ltd., contact details for whom are available\r
45     on the FreeRTOS WEB site.\r
46 \r
47     1 tab == 4 spaces!\r
48 \r
49     ***************************************************************************\r
50      *                                                                       *\r
51      *    Having a problem?  Start by reading the FAQ "My application does   *\r
52      *    not run, what could be wrong?"                                     *\r
53      *                                                                       *\r
54      *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
55      *                                                                       *\r
56     ***************************************************************************\r
57 \r
58 \r
59     http://www.FreeRTOS.org - Documentation, books, training, latest versions, \r
60     license and Real Time Engineers Ltd. contact details.\r
61 \r
62     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
63     including FreeRTOS+Trace - an indispensable productivity tool, and our new\r
64     fully thread aware and reentrant UDP/IP stack.\r
65 \r
66     http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High \r
67     Integrity Systems, who sell the code with commercial support, \r
68     indemnification and middleware, under the OpenRTOS brand.\r
69     \r
70     http://www.SafeRTOS.com - High Integrity Systems also provide a safety \r
71     engineered and independently SIL3 certified version for use in safety and \r
72     mission critical applications that require provable dependability.\r
73 */\r
74 \r
75 /*\r
76         NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.\r
77         The processor MUST be in supervisor mode when vTaskStartScheduler is\r
78         called.  The demo applications included in the FreeRTOS.org download switch\r
79         to supervisor mode prior to main being called.  If you are not using one of\r
80         these demo application projects then ensure Supervisor mode is used.\r
81 */\r
82 \r
83 /*\r
84  * Creates all the demo application tasks, then starts the scheduler.  The WEB\r
85  * documentation provides more details of the demo application tasks.\r
86  *\r
87  * A few tasks are created that are not part of the standard demo.  These are\r
88  * the 'LCD' task, the 'LCD Message' task, a WEB server task and the 'Check'\r
89  * task.\r
90  *\r
91  * The LCD task is the only task that accesses the LCD directly, so mutual\r
92  * exclusion is ensured.  Any task wishing to display text sends the LCD task\r
93  * a message containing a pointer to the string that should be displayed.\r
94  * The LCD task itself just blocks on a queue waiting for such a message to\r
95  * arrive - processing each in turn.\r
96  *\r
97  * The LCD Message task does nothing other than periodically send messages to\r
98  * the LCD task.  The messages originating from the LCD Message task are\r
99  * displayed on the top row of the LCD.\r
100  *\r
101  * The Check task only executes every three seconds but has the highest\r
102  * priority so is guaranteed to get processor time.  Its main function is to\r
103  * check that all the other tasks are still operational. Most tasks maintain\r
104  * a unique count that is incremented each time the task successfully completes\r
105  * a cycle of its function.  Should any error occur within such a task the\r
106  * count is permanently halted.  The check task sets a bit in an error status\r
107  * flag should it find any counter variable at a value that indicates an\r
108  * error has occurred.  The error flag value is converted to a string and sent\r
109  * to the LCD task for display on the bottom row on the LCD.\r
110  */\r
111 \r
112 /* Standard includes. */\r
113 #include <stdio.h>\r
114 \r
115 /* Library includes. */\r
116 #include "91x_lib.h"\r
117 \r
118 /* Scheduler includes. */\r
119 #include "FreeRTOS.h"\r
120 #include "task.h"\r
121 #include "queue.h"\r
122 \r
123 /* Demo application includes. */\r
124 #include "lcd.h"\r
125 #include "flash.h"\r
126 #include "integer.h"\r
127 #include "PollQ.h"\r
128 #include "BlockQ.h"\r
129 #include "semtest.h"\r
130 #include "dynamic.h"\r
131 #include "partest.h"\r
132 #include "flop.h"\r
133 #include "comtest2.h"\r
134 #include "serial.h"\r
135 #include "GenQTest.h"\r
136 #include "QPeek.h"\r
137 \r
138 #ifdef STACK_LWIP\r
139         #include "BasicWEB.h"\r
140         #include "sys.h"\r
141 #endif\r
142 \r
143 /* Priorities for the demo application tasks. */\r
144 #define mainLED_TASK_PRIORITY           ( tskIDLE_PRIORITY + 1 )\r
145 #define mainQUEUE_POLL_PRIORITY         ( tskIDLE_PRIORITY + 2 )\r
146 #define mainCHECK_TASK_PRIORITY         ( tskIDLE_PRIORITY + 4 )\r
147 #define mainSEM_TEST_PRIORITY           ( tskIDLE_PRIORITY + 1 )\r
148 #define mainBLOCK_Q_PRIORITY            ( tskIDLE_PRIORITY + 2 )\r
149 #define mainCOM_TEST_PRIORITY           ( tskIDLE_PRIORITY + 3 )\r
150 #define mainLCD_TASK_PRIORITY           ( tskIDLE_PRIORITY + 1 )\r
151 #define mainMSG_TASK_PRIORITY           ( tskIDLE_PRIORITY + 1 )\r
152 #define mainGENERIC_QUEUE_PRIORITY      ( tskIDLE_PRIORITY )\r
153 \r
154 /* Delays used by the various tasks defined in this file. */\r
155 #define mainCHECK_PERIOD                        ( ( portTickType ) 3000 / portTICK_RATE_MS  )\r
156 #define mainSTRING_WRITE_DELAY          ( 500 / portTICK_RATE_MS )\r
157 #define mainLCD_DELAY                           ( 20 / portTICK_RATE_MS )\r
158 \r
159 /* Constants for the ComTest tasks. */\r
160 #define mainCOM_TEST_BAUD_RATE          ( ( unsigned long ) 115200 )\r
161 #define mainCOM_TEST_LED                        ( 3 )\r
162 \r
163 /* The maximum number of messages that can be pending to be written to the LCD. */\r
164 #define mainLCD_QUEUE_LEN                       ( 6 )\r
165 \r
166 /* Dimension the buffer used to write the error flag string. */\r
167 #define mainMAX_FLAG_STRING_LEN         ( 32 )\r
168 \r
169 /* The structure that is passed on the LCD message queue. */\r
170 typedef struct\r
171 {\r
172         char **ppcMessageToDisplay; /*<< Points to a char* pointing to the message to display. */\r
173         portBASE_TYPE xRow;                             /*<< The row on which the message should be displayed. */\r
174 } xLCDMessage;\r
175 /*-----------------------------------------------------------*/\r
176 \r
177 /*\r
178  * The task that executes at the highest priority and calls\r
179  * prvCheckOtherTasksAreStillRunning().  See the description at the top\r
180  * of the file.\r
181  */\r
182 static void vErrorChecks( void *pvParameters );\r
183 \r
184 /*\r
185  * Configure the processor clock and ports.\r
186  */\r
187 static void prvSetupHardware( void );\r
188 \r
189 /*\r
190  * Checks that all the demo application tasks are still executing without error\r
191  * - as described at the top of the file.  Called by vErrorChecks().\r
192  */\r
193 static void prvCheckOtherTasksAreStillRunning( void );\r
194 \r
195 #ifdef STACK_UIP\r
196         /*\r
197          * The WEB server task prototype.  The task is created in this file but defined\r
198          * elsewhere.  STACK_UIP is defined when the uIP stack is used in preference\r
199          * to the lwIP stack.\r
200          */\r
201         extern void vuIP_Task(void *pvParameters);\r
202 #endif\r
203 \r
204 /*\r
205  * The task that displays text on the LCD.\r
206  */\r
207 static void prvLCDTask( void * pvParameters );\r
208 \r
209 /*\r
210  * The task that sends messages to be displayed on the top row of the LCD.\r
211  */\r
212 static void prvLCDMessageTask( void * pvParameters );\r
213 \r
214 /*-----------------------------------------------------------*/\r
215 \r
216 /* The queue used to pass messages to the LCD task. */\r
217 static xQueueHandle xLCDQueue;\r
218 \r
219 /* Error status flag. */\r
220 static unsigned long ulErrorFlags = 0;\r
221 \r
222 /*-----------------------------------------------------------*/\r
223 \r
224 /*\r
225  * Starts all the other tasks, then starts the scheduler.\r
226  */\r
227 void main( void )\r
228 {\r
229         #ifdef DEBUG\r
230                 debug();\r
231         #endif\r
232         \r
233         /* Setup any hardware that has not already been configured by the low\r
234         level init routines. */\r
235         prvSetupHardware();\r
236         /* Create the queue used to send data to the LCD task. */\r
237         xLCDQueue = xQueueCreate( mainLCD_QUEUE_LEN, sizeof( xLCDMessage ) );\r
238         \r
239         /* Start all the standard demo application tasks. */\r
240         vStartIntegerMathTasks( tskIDLE_PRIORITY );\r
241         vStartLEDFlashTasks( mainLED_TASK_PRIORITY );\r
242         vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );\r
243         vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );\r
244         vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );\r
245         vStartDynamicPriorityTasks();\r
246         vStartMathTasks( tskIDLE_PRIORITY );\r
247         vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );\r
248         vStartGenericQueueTasks( mainGENERIC_QUEUE_PRIORITY );\r
249         vStartQueuePeekTasks(); \r
250 \r
251         /* Start the tasks which are defined in this file. */\r
252         xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );\r
253         xTaskCreate( prvLCDTask, "LCD", configMINIMAL_STACK_SIZE, ( void * ) &xLCDQueue, mainLCD_TASK_PRIORITY, NULL );\r
254         xTaskCreate( prvLCDMessageTask, "MSG", configMINIMAL_STACK_SIZE, ( void * ) &xLCDQueue, mainMSG_TASK_PRIORITY, NULL );\r
255 \r
256         /* Start either the uIP TCP/IP stack or the lwIP TCP/IP stack. */\r
257         #ifdef STACK_UIP\r
258                 /* Finally, create the WEB server task. */\r
259                 xTaskCreate( vuIP_Task, "uIP", configMINIMAL_STACK_SIZE * 3, NULL, mainCHECK_TASK_PRIORITY - 1, NULL );\r
260         #endif\r
261 \r
262         #ifdef STACK_LWIP       \r
263                 /* Create the lwIP task.  This uses the lwIP RTOS abstraction layer.*/\r
264                 vlwIPInit();\r
265                 sys_set_state(  ( signed char * ) "httpd", lwipBASIC_SERVER_STACK_SIZE );\r
266                 sys_thread_new( vBasicWEBServer, ( void * ) NULL, basicwebWEBSERVER_PRIORITY );\r
267                 sys_set_default_state();\r
268         #endif\r
269 \r
270         /* Start the scheduler.\r
271 \r
272         NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.\r
273         The processor MUST be in supervisor mode when vTaskStartScheduler is\r
274         called.  The demo applications included in the FreeRTOS.org download switch\r
275         to supervisor mode prior to main being called.  If you are not using one of\r
276         these demo application projects then ensure Supervisor mode is used here. */\r
277 \r
278         vTaskStartScheduler();\r
279 \r
280         /* We should never get here as control is now taken by the scheduler. */\r
281         for( ;; );\r
282 }\r
283 /*-----------------------------------------------------------*/\r
284 \r
285 static void prvSetupHardware( void )\r
286 {\r
287         /* Configuration taken from the ST code.\r
288 \r
289         Set Flash banks size & address */\r
290         FMI_BankRemapConfig( 4, 2, 0, 0x80000 );\r
291 \r
292         /* FMI Waite States */\r
293         FMI_Config( FMI_READ_WAIT_STATE_2, FMI_WRITE_WAIT_STATE_0, FMI_PWD_ENABLE, FMI_LVD_ENABLE, FMI_FREQ_HIGH );\r
294 \r
295         /* Configure the FPLL = 96MHz, and APB to 48MHz. */\r
296         SCU_PCLKDivisorConfig( SCU_PCLK_Div2 );\r
297         SCU_PLLFactorsConfig( 192, 25, 2 );\r
298         SCU_PLLCmd( ENABLE );\r
299         SCU_MCLKSourceConfig( SCU_MCLK_PLL );\r
300 \r
301         WDG_Cmd( DISABLE );\r
302         VIC_DeInit();\r
303 \r
304         /* GPIO8 clock source enable, used by the LCD. */\r
305         SCU_APBPeriphClockConfig(__GPIO8, ENABLE);\r
306         GPIO_DeInit(GPIO8);\r
307 \r
308         /* GPIO 9 clock source enable, used by the LCD. */\r
309         SCU_APBPeriphClockConfig(__GPIO9, ENABLE);\r
310         GPIO_DeInit(GPIO9);\r
311 \r
312         /* Enable VIC clock */\r
313         SCU_AHBPeriphClockConfig(__VIC, ENABLE);\r
314         SCU_AHBPeriphReset(__VIC, DISABLE);\r
315 \r
316         /* Peripheral initialisation. */\r
317         vParTestInitialise();\r
318 }\r
319 /*-----------------------------------------------------------*/\r
320 \r
321 static void vErrorChecks( void *pvParameters )\r
322 {\r
323 static char cCheckVal[ mainMAX_FLAG_STRING_LEN ];\r
324 char *pcFlagString;\r
325 xLCDMessage xMessageToSend;\r
326 portTickType xLastWakeTime;\r
327 char *pcStringsToDisplay[] = {                                                                          \r
328                                                                         "Check status flag"\r
329                                                                  };\r
330 \r
331         /* The parameters are not used in this task. */\r
332         ( void ) pvParameters;\r
333         \r
334         pcFlagString = &cCheckVal[ 0 ]; \r
335 \r
336         /* Initialise xLastWakeTime to ensure the first call to vTaskDelayUntil()\r
337         functions correctly. */\r
338         xLastWakeTime = xTaskGetTickCount();\r
339 \r
340         /* Cycle for ever, delaying then checking all the other tasks are still\r
341         operating without error. */\r
342         for( ;; )\r
343         {\r
344                 /* Delay until it is time to execute again. */\r
345                 vTaskDelayUntil( &xLastWakeTime, mainCHECK_PERIOD );\r
346         \r
347                 /* Check all the other tasks to see if the error flag needs updating. */\r
348                 prvCheckOtherTasksAreStillRunning();\r
349                 \r
350                 /* Create a string indicating the error flag status. */\r
351                 sprintf( cCheckVal, "equals 0x%x       ", ulErrorFlags );\r
352                 xMessageToSend.xRow = Line2;\r
353 \r
354                 /* Send the first part of the message to the LCD task. */\r
355                 xMessageToSend.ppcMessageToDisplay = &pcStringsToDisplay[ 0 ];\r
356                 xQueueSend( xLCDQueue, ( void * ) &xMessageToSend, 0 );\r
357                 vTaskDelay( mainSTRING_WRITE_DELAY );\r
358 \r
359                 /* Send the second part of the message to the LCD task. */\r
360                 xMessageToSend.ppcMessageToDisplay = &pcFlagString;\r
361                 xQueueSend( xLCDQueue, ( void * ) &xMessageToSend, 0 );\r
362         }\r
363 }\r
364 /*-----------------------------------------------------------*/\r
365 \r
366 static void prvCheckOtherTasksAreStillRunning( void )\r
367 {\r
368         if( xAreIntegerMathsTaskStillRunning() != pdTRUE )\r
369         {\r
370                 ulErrorFlags |= 0x01;\r
371         }\r
372 \r
373         if( xArePollingQueuesStillRunning() != pdTRUE )\r
374         {\r
375                 ulErrorFlags |=  0x02;\r
376         }\r
377 \r
378         if( xAreSemaphoreTasksStillRunning() != pdTRUE )\r
379         {\r
380                 ulErrorFlags |= 0x04;\r
381         }\r
382 \r
383         if( xAreBlockingQueuesStillRunning() != pdTRUE )\r
384         {\r
385                 ulErrorFlags |= 0x08;\r
386         }\r
387 \r
388         if( xAreComTestTasksStillRunning() != pdTRUE )\r
389         {\r
390                 ulErrorFlags |= 0x10;\r
391         }\r
392 \r
393         if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )\r
394         {\r
395                 ulErrorFlags |= 0x20;\r
396         }\r
397 \r
398         if( xAreMathsTaskStillRunning() != pdTRUE )\r
399         {\r
400                 ulErrorFlags |= 0x40;\r
401         }\r
402         \r
403         if( xAreGenericQueueTasksStillRunning() != pdTRUE )\r
404         {\r
405                 ulErrorFlags |= 0x80;\r
406         }\r
407 \r
408         if( xAreQueuePeekTasksStillRunning() != pdTRUE )\r
409         {\r
410                 ulErrorFlags |= 0x100;\r
411         }\r
412         \r
413 }\r
414 /*-----------------------------------------------------------*/\r
415 \r
416 static void prvLCDMessageTask( void * pvParameters )\r
417 {\r
418 xQueueHandle *pxLCDQueue;       \r
419 xLCDMessage xMessageToSend;\r
420 portBASE_TYPE xIndex = 0;\r
421 \r
422 /* The strings that are written to the LCD. */\r
423 char *pcStringsToDisplay[] = {                                                                          \r
424                                                                         "IAR             ",\r
425                                                                         "STR912          ",\r
426                                                                         "Demo            ",\r
427                                                                         "www.FreeRTOS.org",\r
428                                                                         ""\r
429                                                                 };\r
430 \r
431 \r
432         /* To test the parameter passing mechanism, the queue on which messages are\r
433         posted is passed in as a parameter even though it is available as a file\r
434         scope variable anyway. */\r
435         pxLCDQueue = ( xQueueHandle * ) pvParameters;\r
436 \r
437         for( ;; )\r
438         {\r
439                 /* Wait until it is time to move onto the next string. */\r
440                 vTaskDelay( mainSTRING_WRITE_DELAY );           \r
441                 \r
442                 /* Configure the message object to send to the LCD task. */\r
443                 xMessageToSend.ppcMessageToDisplay = &pcStringsToDisplay[ xIndex ];\r
444                 xMessageToSend.xRow = Line1;\r
445                 \r
446                 /* Post the message to be displayed. */\r
447                 xQueueSend( *pxLCDQueue, ( void * ) &xMessageToSend, 0 );\r
448                 \r
449                 /* Move onto the next message, wrapping when necessary. */\r
450                 xIndex++;               \r
451                 if( *( pcStringsToDisplay[ xIndex ] ) == 0x00 )\r
452                 {\r
453                         xIndex = 0;\r
454 \r
455                         /* Delay longer before going back to the start of the messages. */\r
456                         vTaskDelay( mainSTRING_WRITE_DELAY * 2 );\r
457                 }\r
458         }\r
459 }\r
460 /*-----------------------------------------------------------*/\r
461 \r
462 void prvLCDTask( void * pvParameters )\r
463 {\r
464 xQueueHandle *pxLCDQueue;\r
465 xLCDMessage xReceivedMessage;\r
466 char *pcString;\r
467 \r
468         /* To test the parameter passing mechanism, the queue on which messages are\r
469         received is passed in as a parameter even though it is available as a file\r
470         scope variable anyway. */\r
471         pxLCDQueue = ( xQueueHandle * ) pvParameters;\r
472 \r
473         LCD_Init();\r
474 \r
475         for( ;; )\r
476         {\r
477                 /* Wait for a message to arrive. */\r
478                 if( xQueueReceive( *pxLCDQueue, &xReceivedMessage, portMAX_DELAY ) )\r
479                 {\r
480                         /* Where is the string we are going to display? */\r
481                         pcString = *xReceivedMessage.ppcMessageToDisplay;\r
482                         LCD_DisplayString(xReceivedMessage.xRow, pcString, BlackText);\r
483 \r
484                         /* The delay here is just to ensure the LCD task does not starve\r
485                         out lower priority tasks as writing to the LCD can take a long\r
486                         time. */\r
487                         vTaskDelay( mainLCD_DELAY );\r
488                 }\r
489         }\r
490 }\r
491 /*-----------------------------------------------------------*/\r