]> begriffs open source - cmsis-freertos/blob - Demo/WizNET_DEMO_GCC_ARM7/main.c
osEventFlagsWait: Fix flag comparison
[cmsis-freertos] / Demo / WizNET_DEMO_GCC_ARM7 / main.c
1 /*
2  * FreeRTOS Kernel V10.2.1
3  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of
6  * this software and associated documentation files (the "Software"), to deal in
7  * the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * http://www.FreeRTOS.org
23  * http://aws.amazon.com/freertos
24  *
25  * 1 tab == 4 spaces!
26  */
27
28 /*
29         NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
30         The processor MUST be in supervisor mode when vTaskStartScheduler is
31         called.  The demo applications included in the FreeRTOS.org download switch
32         to supervisor mode prior to main being called.  If you are not using one of
33         these demo application projects then ensure Supervisor mode is used.
34 */
35
36
37 /*
38  * Program entry point.
39  *
40  * main() is responsible for setting up the microcontroller peripherals, then
41  * starting the demo application tasks.  Once the tasks have been created the
42  * scheduler is started and main() should never complete.
43  *
44  * The demo creates the three standard 'flash' tasks to provide some visual
45  * feedback that the system and scheduler are still operating correctly.
46  *
47  * The HTTP server task operates at the highest priority so will always preempt
48  * the flash or idle task on TCP/IP events.
49  */
50
51 /* Standard includes. */
52 #include <stdlib.h>
53
54 /* Scheduler include files. */
55 #include "FreeRTOS.h"
56 #include "semphr.h"
57 #include "task.h"
58
59 /* Application includes. */
60 #include "i2c.h"
61 #include "HTTP_Serv.h"
62 #include "flash.h"
63 #include "partest.h"
64 #include "dynamic.h"
65 #include "semtest.h"
66 #include "PollQ.h"
67 #include "BlockQ.h"
68 #include "integer.h"
69
70 /*-----------------------------------------------------------*/
71
72 /* Constants to setup the PLL. */
73 #define mainPLL_MUL_4           ( ( unsigned char ) 0x0003 )
74 #define mainPLL_DIV_1           ( ( unsigned char ) 0x0000 )
75 #define mainPLL_ENABLE          ( ( unsigned char ) 0x0001 )
76 #define mainPLL_CONNECT         ( ( unsigned char ) 0x0003 )
77 #define mainPLL_FEED_BYTE1      ( ( unsigned char ) 0xaa )
78 #define mainPLL_FEED_BYTE2      ( ( unsigned char ) 0x55 )
79 #define mainPLL_LOCK            ( ( unsigned long ) 0x0400 )
80
81 /* Constants to setup the MAM. */
82 #define mainMAM_TIM_3           ( ( unsigned char ) 0x03 )
83 #define mainMAM_MODE_FULL       ( ( unsigned char ) 0x02 )
84
85 /* Constants to setup the peripheral bus. */
86 #define mainBUS_CLK_FULL        ( ( unsigned char ) 0x01 )
87
88 /* Constants to setup I/O and processor. */
89 #define mainBUS_CLK_FULL        ( ( unsigned char ) 0x01 )
90 #define mainLED_TO_OUTPUT       ( ( unsigned long ) 0xff0000 )
91 #define mainJTAG_PORT           ( ( unsigned long ) 0x3E0000UL )
92
93 /* Priorities for the demo application tasks. */
94 #define mainLED_TASK_PRIORITY           ( tskIDLE_PRIORITY + 1 )
95 #define mainHTTP_TASK_PRIORITY          ( tskIDLE_PRIORITY + 2 )
96 #define mainBLOCK_Q_PRIORITY            ( tskIDLE_PRIORITY + 2 )
97 #define mainQUEUE_POLL_PRIORITY         ( tskIDLE_PRIORITY + 2 )
98 #define mainERROR_CHECK_PRIORITY        ( tskIDLE_PRIORITY + 1 )
99
100 /* Flash rates of the on board LED to indicate the health of the system. */
101 #define mainNO_ERROR_DELAY                      ( 3000 )
102 #define mainERROR_DELAY                         ( 500 )
103 #define mainON_BOARD_LED_BIT            ( ( unsigned long ) 0x80 )
104
105 /*-----------------------------------------------------------*/
106
107 /*
108  * The Olimex demo board has a single built in LED.  This function simply
109  * toggles its state.
110  */
111 void prvToggleOnBoardLED( void );
112
113 /*
114  * Configure the processor for use with the Olimex demo board.
115  */
116 static void prvSetupHardware( void );
117
118 /*
119  * Simply check for errors and toggle the onboard LED.
120  */
121 static void prvErrorChecks( void *pvParameters );
122
123 /*
124  * Return true if the demo tasks are executing without error - otherwise
125  * return false.
126  */
127 static void prvMainCheckOtherTasksAreStillRunning( void );
128 /*-----------------------------------------------------------*/
129
130 /* Flag set by prvMainCheckOtherTasksAreStillExecuting(). */
131 long lErrorInTask = pdFALSE;
132
133 /*
134  * Application entry point:
135  * Starts all the other tasks, then starts the scheduler.
136  */
137 int main( void )
138 {
139         /* Setup the hardware for use with the Olimex demo board. */
140         prvSetupHardware();
141
142         /* Start the standard flash tasks so the WEB server is not the only thing
143         running. */
144         vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
145         vStartSemaphoreTasks( tskIDLE_PRIORITY );
146         vStartDynamicPriorityTasks();
147         vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
148         vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
149         vStartIntegerMathTasks( tskIDLE_PRIORITY );
150
151         /* Start the WEB server task and the error check task. */
152         xTaskCreate( vHTTPServerTask, "HTTP", configMINIMAL_STACK_SIZE, NULL, mainHTTP_TASK_PRIORITY, NULL );
153         xTaskCreate( prvErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainERROR_CHECK_PRIORITY, NULL );
154
155         /* Now all the tasks have been started - start the scheduler.
156
157         NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
158         The processor MUST be in supervisor mode when vTaskStartScheduler is
159         called.  The demo applications included in the FreeRTOS.org download switch
160         to supervisor mode prior to main being called.  If you are not using one of
161         these demo application projects then ensure Supervisor mode is used. */
162         vTaskStartScheduler();
163
164         /* Should never reach here! */
165         return 0;
166 }
167 /*-----------------------------------------------------------*/
168
169 static void prvSetupHardware( void )
170 {
171         #ifdef RUN_FROM_RAM
172                 /* Remap the interrupt vectors to RAM if we are are running from RAM. */
173                 SCB_MEMMAP = 2;
174         #endif
175
176         /* Set all GPIO to output other than the P0.14 (BSL), and the JTAG pins.
177         The JTAG pins are left as input as I'm not sure what will happen if the
178         Wiggler is connected after powerup - not that it would be a good idea to
179         do that anyway. */
180         GPIO_IODIR = ~( mainJTAG_PORT );
181
182         /* Setup the PLL to multiply the XTAL input by 4. */
183         SCB_PLLCFG = ( mainPLL_MUL_4 | mainPLL_DIV_1 );
184
185         /* Activate the PLL by turning it on then feeding the correct sequence of
186         bytes. */
187         SCB_PLLCON = mainPLL_ENABLE;
188         SCB_PLLFEED = mainPLL_FEED_BYTE1;
189         SCB_PLLFEED = mainPLL_FEED_BYTE2;
190
191         /* Wait for the PLL to lock... */
192         while( !( SCB_PLLSTAT & mainPLL_LOCK ) );
193
194         /* ...before connecting it using the feed sequence again. */
195         SCB_PLLCON = mainPLL_CONNECT;
196         SCB_PLLFEED = mainPLL_FEED_BYTE1;
197         SCB_PLLFEED = mainPLL_FEED_BYTE2;
198
199         /* Setup and turn on the MAM.  Three cycle access is used due to the fast
200         PLL used.  It is possible faster overall performance could be obtained by
201         tuning the MAM and PLL settings. */
202         MAM_TIM = mainMAM_TIM_3;
203         MAM_CR = mainMAM_MODE_FULL;
204
205         /* Setup the peripheral bus to be the same as the PLL output. */
206         SCB_VPBDIV = mainBUS_CLK_FULL;
207
208         /* Initialise the i2c peripheral. */
209         i2cInit();
210
211         /* Initialise the LED's used by the flash tasks. */
212         vParTestInitialise();
213 }
214 /*-----------------------------------------------------------*/
215
216 static void prvMainCheckOtherTasksAreStillRunning( void )
217 {
218         /* Check all the demo tasks (other than the flash tasks) to ensure
219         that they are all still running, and that none of them have detected
220         an error. */
221
222         /* This function is called from more than one task. */
223         if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
224         {
225                 lErrorInTask = pdTRUE;
226         }
227
228         if( xArePollingQueuesStillRunning() != pdTRUE )
229         {
230                 lErrorInTask = pdTRUE;
231         }
232
233         if( xAreSemaphoreTasksStillRunning() != pdTRUE )
234         {
235                 lErrorInTask = pdTRUE;
236         }
237
238         if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
239         {
240                 lErrorInTask = pdTRUE;
241         }
242
243         if( xAreBlockingQueuesStillRunning() != pdTRUE )
244         {
245                 lErrorInTask = pdTRUE;
246         }
247 }
248 /*-----------------------------------------------------------*/
249
250 void prvToggleOnBoardLED( void )
251 {
252 unsigned long ulState;
253
254         ulState = GPIO0_IOPIN;
255         if( ulState & mainON_BOARD_LED_BIT )
256         {
257                 GPIO_IOCLR = mainON_BOARD_LED_BIT;
258         }
259         else
260         {
261                 GPIO_IOSET = mainON_BOARD_LED_BIT;
262         }
263 }
264 /*-----------------------------------------------------------*/
265
266 static void prvErrorChecks( void *pvParameters )
267 {
268 TickType_t xDelay = mainNO_ERROR_DELAY;
269
270         /* The parameters are not used. */
271         ( void ) pvParameters;
272
273         for( ;; )
274         {
275                 /* How long we delay depends on whether an error has been detected
276                 or not.  Therefore the flash rate of the on board LED indicates
277                 whether or not an error has occurred. */
278                 vTaskDelay( xDelay );
279
280                 /* Update the lErrorInTask flag. */
281                 prvMainCheckOtherTasksAreStillRunning();
282
283                 if( lErrorInTask )
284                 {
285                         /* An error has been found so reduce the delay period and in so
286                         doing speed up the flash rate of the on board LED. */
287                         xDelay = mainERROR_DELAY;
288                 }
289
290                 prvToggleOnBoardLED();
291         }
292 }
293