]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/RX600_RX62N-RDK_Renesas/RTOSDemo/uIP_Task.c
Update to MIT licensed FreeRTOS V10.0.0 - see https://www.freertos.org/History.txt
[freertos] / FreeRTOS / Demo / RX600_RX62N-RDK_Renesas / RTOSDemo / 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 "timers.h"\r
36 #include "queue.h"\r
37 \r
38 /* uip includes. */\r
39 #include "net/uip.h"\r
40 #include "net/uip_arp.h"\r
41 #include "apps/httpd/httpd.h"\r
42 #include "sys/timer.h"\r
43 #include "net/clock-arch.h"\r
44 #include "r_ether.h"\r
45 \r
46 /* Demo includes. */\r
47 #include "ParTest.h"\r
48 \r
49 /*-----------------------------------------------------------*/\r
50 \r
51 /* How long to wait before attempting to connect the MAC again. */\r
52 #define uipINIT_WAIT    ( 100 / portTICK_PERIOD_MS )\r
53 \r
54 /* Shortcut to the header within the Rx buffer. */\r
55 #define xHeader ((struct uip_eth_hdr *) &uip_buf[ 0 ])\r
56 \r
57 /* Standard constant. */\r
58 #define uipTOTAL_FRAME_HEADER_SIZE      54\r
59 \r
60 /* The ARP timer and the periodic timer share a callback function, so the\r
61 respective timer IDs are used to determine which timer actually expired.  These\r
62 constants are assigned to the timer IDs. */\r
63 #define uipARP_TIMER                            0\r
64 #define uipPERIODIC_TIMER                       1\r
65 \r
66 /* A block time of zero ticks simply means, "don't block". */\r
67 #define uipDONT_BLOCK                           0UL\r
68 \r
69 /*-----------------------------------------------------------*/\r
70 \r
71 /*\r
72  * Setup the MAC address in the MAC itself, and in the uIP stack.\r
73  */\r
74 static void prvSetMACAddress( void );\r
75 \r
76 /*\r
77  * Perform any uIP initialisation necessary.\r
78  */\r
79 static void prvInitialise_uIP( void );\r
80 \r
81 /*\r
82  * The callback function that is assigned to both the periodic timer and the\r
83  * ARP timer.\r
84  */\r
85 static void prvUIPTimerCallback( TimerHandle_t xTimer );\r
86 \r
87 /*\r
88  * Port functions required by the uIP stack.\r
89  */\r
90 clock_time_t clock_time( void );\r
91 \r
92 /*-----------------------------------------------------------*/\r
93 \r
94 /* The queue used to send TCP/IP events to the uIP stack. */\r
95 QueueHandle_t xEMACEventQueue = NULL;\r
96 \r
97 /*-----------------------------------------------------------*/\r
98 \r
99 clock_time_t clock_time( void )\r
100 {\r
101         return xTaskGetTickCount();\r
102 }\r
103 /*-----------------------------------------------------------*/\r
104 \r
105 void vuIP_Task( void *pvParameters )\r
106 {\r
107 portBASE_TYPE i;\r
108 unsigned long ulNewEvent = 0UL;\r
109 unsigned long ulUIP_Events = 0UL;\r
110 \r
111         ( void ) pvParameters;\r
112 \r
113         /* Initialise the uIP stack. */\r
114         prvInitialise_uIP();\r
115 \r
116         /* Initialise the MAC. */\r
117         vInitEmac();\r
118 \r
119         while( lEMACWaitForLink() != pdPASS )\r
120     {\r
121         vTaskDelay( uipINIT_WAIT );\r
122     }\r
123 \r
124         for( ;; )\r
125         {\r
126                 if( ( ulUIP_Events & uipETHERNET_RX_EVENT ) != 0UL )\r
127                 {\r
128                         /* Is there received data ready to be processed? */\r
129                         uip_len = ( unsigned short ) ulEMACRead();\r
130 \r
131                         if( ( uip_len > 0 ) && ( uip_buf != NULL ) )\r
132                         {\r
133                                 /* Standard uIP loop taken from the uIP manual. */\r
134                                 if( xHeader->type == htons( UIP_ETHTYPE_IP ) )\r
135                                 {\r
136                                         uip_arp_ipin();\r
137                                         uip_input();\r
138 \r
139                                         /* If the above function invocation resulted in data that\r
140                                         should be sent out on the network, the global variable\r
141                                         uip_len is set to a value > 0. */\r
142                                         if( uip_len > 0 )\r
143                                         {\r
144                                                 uip_arp_out();\r
145                                                 vEMACWrite();\r
146                                         }\r
147                                 }\r
148                                 else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )\r
149                                 {\r
150                                         uip_arp_arpin();\r
151 \r
152                                         /* If the above function invocation resulted in data that\r
153                                         should be sent out on the network, the global variable\r
154                                         uip_len is set to a value > 0. */\r
155                                         if( uip_len > 0 )\r
156                                         {\r
157                                                 vEMACWrite();\r
158                                         }\r
159                                 }\r
160                         }\r
161                         else\r
162                         {\r
163                                 ulUIP_Events &= ~uipETHERNET_RX_EVENT;\r
164                         }\r
165                 }\r
166 \r
167                 if( ( ulUIP_Events & uipPERIODIC_TIMER_EVENT ) != 0UL )\r
168                 {\r
169                         ulUIP_Events &= ~uipPERIODIC_TIMER_EVENT;\r
170 \r
171                         for( i = 0; i < UIP_CONNS; i++ )\r
172                         {\r
173                                 uip_periodic( i );\r
174 \r
175                                 /* If the above function invocation resulted in data that\r
176                                 should be sent out on the network, the global variable\r
177                                 uip_len is set to a value > 0. */\r
178                                 if( uip_len > 0 )\r
179                                 {\r
180                                         uip_arp_out();\r
181                                         vEMACWrite();\r
182                                 }\r
183                         }\r
184                 }\r
185 \r
186                 /* Call the ARP timer function every 10 seconds. */\r
187                 if( ( ulUIP_Events & uipARP_TIMER_EVENT ) != 0 )\r
188                 {\r
189                         ulUIP_Events &= ~uipARP_TIMER_EVENT;\r
190                         uip_arp_timer();\r
191                 }\r
192 \r
193                 if( ulUIP_Events == pdFALSE )\r
194                 {\r
195                         xQueueReceive( xEMACEventQueue, &ulNewEvent, portMAX_DELAY );\r
196                         ulUIP_Events |= ulNewEvent;\r
197                 }\r
198         }\r
199 }\r
200 /*-----------------------------------------------------------*/\r
201 \r
202 static void prvInitialise_uIP( void )\r
203 {\r
204 TimerHandle_t xARPTimer, xPeriodicTimer;\r
205 uip_ipaddr_t xIPAddr;\r
206 const unsigned long ul_uIPEventQueueLength = 10UL;\r
207 \r
208         /* Initialise the uIP stack. */\r
209         uip_init();\r
210         uip_ipaddr( &xIPAddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );\r
211         uip_sethostaddr( &xIPAddr );\r
212         uip_ipaddr( &xIPAddr, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 );\r
213         uip_setnetmask( &xIPAddr );\r
214         prvSetMACAddress();\r
215         httpd_init();\r
216 \r
217         /* Create the queue used to sent TCP/IP events to the uIP stack. */\r
218         xEMACEventQueue = xQueueCreate( ul_uIPEventQueueLength, sizeof( unsigned long ) );\r
219 \r
220         /* Create and start the uIP timers. */\r
221         xARPTimer = xTimerCreate(       "ARPTimer", /* Just a name that is helpful for debugging, not used by the kernel. */\r
222                                                                 ( 10000UL / portTICK_PERIOD_MS ), /* Timer period. */\r
223                                                                 pdTRUE, /* Autor-reload. */\r
224                                                                 ( void * ) uipARP_TIMER,\r
225                                                                 prvUIPTimerCallback\r
226                                                         );\r
227 \r
228         xPeriodicTimer = xTimerCreate(  "PeriodicTimer",\r
229                                                                         ( 50 / portTICK_PERIOD_MS ),\r
230                                                                         pdTRUE, /* Autor-reload. */\r
231                                                                         ( void * ) uipPERIODIC_TIMER,\r
232                                                                         prvUIPTimerCallback\r
233                                                                 );\r
234 \r
235         configASSERT( xARPTimer );\r
236         configASSERT( xPeriodicTimer );\r
237 \r
238         xTimerStart( xARPTimer, portMAX_DELAY );\r
239         xTimerStart( xPeriodicTimer, portMAX_DELAY );\r
240 }\r
241 /*-----------------------------------------------------------*/\r
242 \r
243 static void prvUIPTimerCallback( TimerHandle_t xTimer )\r
244 {\r
245 static const unsigned long ulARPTimerExpired = uipARP_TIMER_EVENT;\r
246 static const unsigned long ulPeriodicTimerExpired = uipPERIODIC_TIMER_EVENT;\r
247 \r
248         /* This is a time callback, so calls to xQueueSend() must not attempt to\r
249         block. */\r
250         switch( ( int ) pvTimerGetTimerID( xTimer ) )\r
251         {\r
252                 case uipARP_TIMER               :       xQueueSend( xEMACEventQueue, &ulARPTimerExpired, uipDONT_BLOCK );\r
253                                                                         break;\r
254 \r
255                 case uipPERIODIC_TIMER  :       xQueueSend( xEMACEventQueue, &ulPeriodicTimerExpired, uipDONT_BLOCK );\r
256                                                                         break;\r
257 \r
258                 default                                 :       /* Should not get here. */\r
259                                                                         break;\r
260         }\r
261 }\r
262 /*-----------------------------------------------------------*/\r
263 \r
264 static void prvSetMACAddress( void )\r
265 {\r
266 struct uip_eth_addr xAddr;\r
267 \r
268         /* Configure the MAC address in the uIP stack. */\r
269         xAddr.addr[ 0 ] = configMAC_ADDR0;\r
270         xAddr.addr[ 1 ] = configMAC_ADDR1;\r
271         xAddr.addr[ 2 ] = configMAC_ADDR2;\r
272         xAddr.addr[ 3 ] = configMAC_ADDR3;\r
273         xAddr.addr[ 4 ] = configMAC_ADDR4;\r
274         xAddr.addr[ 5 ] = configMAC_ADDR5;\r
275         uip_setethaddr( xAddr );\r
276 }\r
277 /*-----------------------------------------------------------*/\r
278 \r
279 void vApplicationProcessFormInput( char *pcInputString )\r
280 {\r
281 char *c;\r
282 \r
283         /* Only interested in processing form input if this is the IO page. */\r
284         c = strstr( pcInputString, "io.shtml" );\r
285 \r
286         if( c )\r
287         {\r
288                 /* Is there a command in the string? */\r
289                 c = strstr( pcInputString, "?" );\r
290             if( c )\r
291             {\r
292                         /* Turn the LED's on or off in accordance with the check box status. */\r
293                         if( strstr( c, "LED0=1" ) != NULL )\r
294                         {\r
295                                 /* Turn the LEDs on. */\r
296                                 vParTestSetLED( 7, 1 );\r
297                                 vParTestSetLED( 8, 1 );\r
298                                 vParTestSetLED( 9, 1 );\r
299                                 vParTestSetLED( 10, 1 );\r
300                         }\r
301                         else\r
302                         {\r
303                                 /* Turn the LEDs off. */\r
304                                 vParTestSetLED( 7, 0 );\r
305                                 vParTestSetLED( 8, 0 );\r
306                                 vParTestSetLED( 9, 0 );\r
307                                 vParTestSetLED( 10, 0 );\r
308                         }\r
309             }\r
310                 else\r
311                 {\r
312                         /* Commands to turn LEDs off are not always explicit. */\r
313                         vParTestSetLED( 7, 0 );\r
314                         vParTestSetLED( 8, 0 );\r
315                         vParTestSetLED( 9, 0 );\r
316                         vParTestSetLED( 10, 0 );\r
317                 }\r
318         }\r
319 }\r
320 \r