]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_STM32F107_GCC_Rowley/webserver/uIP_Task.c
Update to MIT licensed FreeRTOS V10.0.0 - see https://www.freertos.org/History.txt
[freertos] / FreeRTOS / Demo / CORTEX_STM32F107_GCC_Rowley / webserver / uIP_Task.c
1 /*\r
2  * FreeRTOS Kernel V10.0.0\r
3  * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software. If you wish to use our Amazon\r
14  * FreeRTOS name, please do so in a fair use way that does not cause confusion.\r
15  *\r
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
18  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
19  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
22  *\r
23  * http://www.FreeRTOS.org\r
24  * http://aws.amazon.com/freertos\r
25  *\r
26  * 1 tab == 4 spaces!\r
27  */\r
28 \r
29 /* Standard includes. */\r
30 #include <string.h>\r
31 \r
32 /* Scheduler includes. */\r
33 #include "FreeRTOS.h"\r
34 #include "task.h"\r
35 #include "semphr.h"\r
36 \r
37 /* Demo includes. */\r
38 #include "emac.h"\r
39 #include "partest.h"\r
40 \r
41 /* uip includes. */\r
42 #include "uip.h"\r
43 #include "uip_arp.h"\r
44 #include "httpd.h"\r
45 #include "timer.h"\r
46 #include "clock-arch.h"\r
47 \r
48 /*-----------------------------------------------------------*/\r
49 \r
50 /* How long to wait before attempting to connect the MAC again. */\r
51 #define uipINIT_WAIT                            ( 100 / portTICK_PERIOD_MS )\r
52 \r
53 /* Shortcut to the header within the Rx buffer. */\r
54 #define xHeader ((struct uip_eth_hdr *) &uip_buf[ 0 ])\r
55 \r
56 /* Standard constant. */\r
57 #define uipTOTAL_FRAME_HEADER_SIZE      54\r
58 \r
59 \r
60 /*-----------------------------------------------------------*/\r
61 \r
62 /*\r
63  * Setup the MAC address in the MAC itself, and in the uIP stack.\r
64  */\r
65 static void prvSetMACAddress( void );\r
66 \r
67 /*\r
68  * Port functions required by the uIP stack.\r
69  */\r
70 void clock_init( void );\r
71 clock_time_t clock_time( void );\r
72 \r
73 /*-----------------------------------------------------------*/\r
74 \r
75 /* The semaphore used by the ISR to wake the uIP task. */\r
76 SemaphoreHandle_t xEMACSemaphore;\r
77 \r
78 /* The buffer used by the uIP stack.  In this case the pointer is used to\r
79 point to one of the Rx buffers. */\r
80 unsigned char *uip_buf = NULL;\r
81 \r
82 /*-----------------------------------------------------------*/\r
83 \r
84 void clock_init(void)\r
85 {\r
86         /* This is done when the scheduler starts. */\r
87 }\r
88 /*-----------------------------------------------------------*/\r
89 \r
90 clock_time_t clock_time( void )\r
91 {\r
92         return xTaskGetTickCount();\r
93 }\r
94 /*-----------------------------------------------------------*/\r
95 \r
96 void vuIP_Task( void *pvParameters )\r
97 {\r
98 portBASE_TYPE i;\r
99 uip_ipaddr_t xIPAddr;\r
100 struct timer periodic_timer, arp_timer;\r
101 \r
102         ( void ) pvParameters;\r
103 \r
104         /* Create the semaphore used by the ISR to wake this task. */\r
105         vSemaphoreCreateBinary( xEMACSemaphore );\r
106 \r
107         /* Initialise the uIP stack. */\r
108         timer_set( &periodic_timer, configTICK_RATE_HZ / 2 );\r
109         timer_set( &arp_timer, configTICK_RATE_HZ * 10 );\r
110         uip_init();\r
111         uip_ipaddr( xIPAddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );\r
112         uip_sethostaddr( xIPAddr );\r
113         uip_ipaddr( xIPAddr, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 );\r
114         uip_setnetmask( xIPAddr );\r
115         httpd_init();\r
116 \r
117         /* Initialise the MAC. */\r
118         while( xEthInitialise() != pdPASS )\r
119         {\r
120                 vTaskDelay( uipINIT_WAIT );\r
121         }\r
122 \r
123         prvSetMACAddress();\r
124 \r
125         for( ;; )\r
126         {\r
127                 /* Is there received data ready to be processed? */\r
128                 uip_len = usGetMACRxData();\r
129 \r
130                 if( ( uip_len > 0 ) && ( uip_buf != NULL ) )\r
131                 {\r
132                         /* Standard uIP loop taken from the uIP manual. */\r
133                         if( xHeader->type == htons( UIP_ETHTYPE_IP ) )\r
134                         {\r
135                                 uip_arp_ipin();\r
136                                 uip_input();\r
137 \r
138                                 /* If the above function invocation resulted in data that\r
139                                 should be sent out on the network, the global variable\r
140                                 uip_len is set to a value > 0. */\r
141                                 if( uip_len > 0 )\r
142                                 {\r
143                                         uip_arp_out();\r
144                                         vSendMACData( uip_len );\r
145                                 }\r
146                         }\r
147                         else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )\r
148                         {\r
149                                 uip_arp_arpin();\r
150 \r
151                                 /* If the above function invocation resulted in data that\r
152                                 should be sent out on the network, the global variable\r
153                                 uip_len is set to a value > 0. */\r
154                                 if( uip_len > 0 )\r
155                                 {\r
156                                         vSendMACData( uip_len );\r
157                                 }\r
158                         }\r
159                 }\r
160                 else\r
161                 {\r
162                         if( ( timer_expired( &periodic_timer ) ) && ( uip_buf != NULL ) )\r
163                         {\r
164                                 timer_reset( &periodic_timer );\r
165                                 for( i = 0; i < UIP_CONNS; i++ )\r
166                                 {\r
167                                         uip_periodic( i );\r
168 \r
169                                         /* If the above function invocation resulted in data that\r
170                                         should be sent out on the network, the global variable\r
171                                         uip_len is set to a value > 0. */\r
172                                         if( uip_len > 0 )\r
173                                         {\r
174                                                 uip_arp_out();\r
175                                                 vSendMACData( uip_len );\r
176                                         }\r
177                                 }\r
178 \r
179                                 /* Call the ARP timer function every 10 seconds. */\r
180                                 if( timer_expired( &arp_timer ) )\r
181                                 {\r
182                                         timer_reset( &arp_timer );\r
183                                         uip_arp_timer();\r
184                                 }\r
185                         }\r
186                         else\r
187                         {\r
188                                 /* We did not receive a packet, and there was no periodic\r
189                                 processing to perform.  Block for a fixed period.  If a packet\r
190                                 is received during this period we will be woken by the ISR\r
191                                 giving us the Semaphore. */\r
192                                 xSemaphoreTake( xEMACSemaphore, configTICK_RATE_HZ / 2 );\r
193                         }\r
194                 }\r
195         }\r
196 }\r
197 /*-----------------------------------------------------------*/\r
198 \r
199 static void prvSetMACAddress( void )\r
200 {\r
201 struct uip_eth_addr xAddr;\r
202 \r
203         /* Configure the MAC address in the uIP stack. */\r
204         xAddr.addr[ 0 ] = configMAC_ADDR0;\r
205         xAddr.addr[ 1 ] = configMAC_ADDR1;\r
206         xAddr.addr[ 2 ] = configMAC_ADDR2;\r
207         xAddr.addr[ 3 ] = configMAC_ADDR3;\r
208         xAddr.addr[ 4 ] = configMAC_ADDR4;\r
209         xAddr.addr[ 5 ] = configMAC_ADDR5;\r
210         uip_setethaddr( xAddr );\r
211 }\r
212 /*-----------------------------------------------------------*/\r
213 \r
214 void vApplicationProcessFormInput( char *pcInputString )\r
215 {\r
216 char *c, *pcText;\r
217 static char cMessageForDisplay[ 32 ];\r
218 static const char *pcMessage = cMessageForDisplay;\r
219 extern QueueHandle_t xLCDQueue;\r
220 \r
221         /* Process the form input sent by the IO page of the served HTML. */\r
222 \r
223         c = strstr( pcInputString, "?" );\r
224     if( c )\r
225     {\r
226                 /* Turn LED's on or off in accordance with the check box status. */\r
227                 if( strstr( c, "LED0=1" ) != NULL )\r
228                 {\r
229                         /* Set LED4. */\r
230                         vParTestSetLED( 3, 1 );\r
231                 }\r
232                 else\r
233                 {\r
234                         /* Clear LED4. */\r
235                         vParTestSetLED( 3, 0 );\r
236                 }\r
237 \r
238                 /* Find the start of the text to be displayed on the LCD. */\r
239         pcText = strstr( c, "LCD=" );\r
240         pcText += strlen( "LCD=" );\r
241 \r
242         /* Terminate the file name for further processing within uIP. */\r
243         *c = 0x00;\r
244 \r
245         /* Terminate the LCD string. */\r
246         c = strstr( pcText, " " );\r
247         if( c != NULL )\r
248         {\r
249             *c = 0x00;\r
250         }\r
251 \r
252         /* Add required spaces. */\r
253         while( ( c = strstr( pcText, "+" ) ) != NULL )\r
254         {\r
255             *c = ' ';\r
256         }\r
257 \r
258         /* Write the message to the LCD. */\r
259                 strcpy( cMessageForDisplay, pcText );\r
260         xQueueSend( xLCDQueue, &pcMessage, portMAX_DELAY );\r
261     }\r
262 }\r
263 \r