]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/RX600_RX63N-RSK_Renesas/RTOSDemo/uIP_Task.c
Add FreeRTOS-Plus directory.
[freertos] / FreeRTOS / Demo / RX600_RX63N-RSK_Renesas / RTOSDemo / uIP_Task.c
1 /*\r
2     FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
3         \r
4 \r
5     ***************************************************************************\r
6      *                                                                       *\r
7      *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
8      *    Complete, revised, and edited pdf reference manuals are also       *\r
9      *    available.                                                         *\r
10      *                                                                       *\r
11      *    Purchasing FreeRTOS documentation will not only help you, by       *\r
12      *    ensuring you get running as quickly as possible and with an        *\r
13      *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
14      *    the FreeRTOS project to continue with its mission of providing     *\r
15      *    professional grade, cross platform, de facto standard solutions    *\r
16      *    for microcontrollers - completely free of charge!                  *\r
17      *                                                                       *\r
18      *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
19      *                                                                       *\r
20      *    Thank you for using FreeRTOS, and thank you for your support!      *\r
21      *                                                                       *\r
22     ***************************************************************************\r
23 \r
24 \r
25     This file is part of the FreeRTOS distribution.\r
26 \r
27     FreeRTOS is free software; you can redistribute it and/or modify it under\r
28     the terms of the GNU General Public License (version 2) as published by the\r
29     Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
30     >>>NOTE<<< The modification to the GPL is included to allow you to\r
31     distribute a combined work that includes FreeRTOS without being obliged to\r
32     provide the source code for proprietary components outside of the FreeRTOS\r
33     kernel.  FreeRTOS is distributed in the hope that it will be useful, but\r
34     WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
35     or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\r
36     more details. You should have received a copy of the GNU General Public\r
37     License and the FreeRTOS license exception along with FreeRTOS; if not it\r
38     can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
39     by writing to Richard Barry, contact details for whom are available on the\r
40     FreeRTOS WEB site.\r
41 \r
42     1 tab == 4 spaces!\r
43 \r
44     http://www.FreeRTOS.org - Documentation, latest information, license and\r
45     contact details.\r
46 \r
47     http://www.SafeRTOS.com - A version that is certified for use in safety\r
48     critical systems.\r
49 \r
50     http://www.OpenRTOS.com - Commercial support, development, porting,\r
51     licensing and training services.\r
52 */\r
53 \r
54 /* Standard includes. */\r
55 #include <string.h>\r
56 \r
57 /* Scheduler includes. */\r
58 #include "FreeRTOS.h"\r
59 #include "task.h"\r
60 #include "timers.h"\r
61 #include "queue.h"\r
62 \r
63 /* uip includes. */\r
64 #include "net/uip.h"\r
65 #include "net/uip_arp.h"\r
66 #include "apps/httpd/httpd.h"\r
67 #include "sys/timer.h"\r
68 #include "net/clock-arch.h"\r
69 #include "r_ether.h"\r
70 \r
71 /* Demo includes. */\r
72 #include "ParTest.h"\r
73 \r
74 /*-----------------------------------------------------------*/\r
75 \r
76 /* How long to wait before attempting to connect the MAC again. */\r
77 #define uipINIT_WAIT    ( 100 / portTICK_RATE_MS )\r
78 \r
79 /* Shortcut to the header within the Rx buffer. */\r
80 #define xHeader ((struct uip_eth_hdr *) &uip_buf[ 0 ])\r
81 \r
82 /* Standard constant. */\r
83 #define uipTOTAL_FRAME_HEADER_SIZE      54\r
84 \r
85 /* The ARP timer and the periodic timer share a callback function, so the\r
86 respective timer IDs are used to determine which timer actually expired.  These\r
87 constants are assigned to the timer IDs. */\r
88 #define uipARP_TIMER                            0\r
89 #define uipPERIODIC_TIMER                       1\r
90 \r
91 /* A block time of zero ticks simply means, "don't block". */\r
92 #define uipDONT_BLOCK                           0UL\r
93 \r
94 /*-----------------------------------------------------------*/\r
95 \r
96 /*\r
97  * Setup the MAC address in the MAC itself, and in the uIP stack.\r
98  */\r
99 static void prvSetMACAddress( void );\r
100 \r
101 /*\r
102  * Perform any uIP initialisation necessary. \r
103  */\r
104 static void prvInitialise_uIP( void );\r
105 \r
106 /*\r
107  * The callback function that is assigned to both the periodic timer and the\r
108  * ARP timer.\r
109  */\r
110 static void prvUIPTimerCallback( xTimerHandle xTimer );\r
111 \r
112 /*\r
113  * Port functions required by the uIP stack.\r
114  */\r
115 clock_time_t clock_time( void );\r
116 \r
117 /*-----------------------------------------------------------*/\r
118 \r
119 /* The queue used to send TCP/IP events to the uIP stack. */\r
120 xQueueHandle xEMACEventQueue = NULL;\r
121 \r
122 /*-----------------------------------------------------------*/\r
123 \r
124 clock_time_t clock_time( void )\r
125 {\r
126         return xTaskGetTickCount();\r
127 }\r
128 /*-----------------------------------------------------------*/\r
129 \r
130 void vuIP_Task( void *pvParameters )\r
131 {\r
132 portBASE_TYPE i;\r
133 unsigned long ulNewEvent = 0UL;\r
134 unsigned long ulUIP_Events = 0UL;\r
135 \r
136         ( void ) pvParameters;\r
137         \r
138         /* Initialise the uIP stack. */\r
139         prvInitialise_uIP();\r
140 \r
141         /* Initialise the MAC. */\r
142         vInitEmac();\r
143 \r
144         while( lEMACWaitForLink() != pdPASS )\r
145     {\r
146         vTaskDelay( uipINIT_WAIT );\r
147     }\r
148 \r
149         for( ;; )\r
150         {\r
151                 if( ( ulUIP_Events & uipETHERNET_RX_EVENT ) != 0UL )\r
152                 {               \r
153                         /* Is there received data ready to be processed? */\r
154                         uip_len = ( unsigned short ) ulEMACRead();\r
155                         \r
156                         if( ( uip_len > 0 ) && ( uip_buf != NULL ) )\r
157                         {\r
158                                 /* Standard uIP loop taken from the uIP manual. */\r
159                                 if( xHeader->type == htons( UIP_ETHTYPE_IP ) )\r
160                                 {\r
161                                         uip_arp_ipin();\r
162                                         uip_input();\r
163 \r
164                                         /* If the above function invocation resulted in data that\r
165                                         should be sent out on the network, the global variable\r
166                                         uip_len is set to a value > 0. */\r
167                                         if( uip_len > 0 )\r
168                                         {\r
169                                                 uip_arp_out();\r
170                                                 vEMACWrite();\r
171                                         }\r
172                                 }\r
173                                 else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )\r
174                                 {\r
175                                         uip_arp_arpin();\r
176 \r
177                                         /* If the above function invocation resulted in data that\r
178                                         should be sent out on the network, the global variable\r
179                                         uip_len is set to a value > 0. */\r
180                                         if( uip_len > 0 )\r
181                                         {\r
182                                                 vEMACWrite();\r
183                                         }\r
184                                 }\r
185                         }\r
186                         else\r
187                         {\r
188                                 ulUIP_Events &= ~uipETHERNET_RX_EVENT;\r
189                         }\r
190                 }\r
191                 \r
192                 if( ( ulUIP_Events & uipPERIODIC_TIMER_EVENT ) != 0UL )\r
193                 {\r
194                         ulUIP_Events &= ~uipPERIODIC_TIMER_EVENT;\r
195                                         \r
196                         for( i = 0; i < UIP_CONNS; i++ )\r
197                         {\r
198                                 uip_periodic( i );\r
199 \r
200                                 /* If the above function invocation resulted in data that\r
201                                 should be sent out on the network, the global variable\r
202                                 uip_len is set to a value > 0. */\r
203                                 if( uip_len > 0 )\r
204                                 {\r
205                                         uip_arp_out();\r
206                                         vEMACWrite();\r
207                                 }\r
208                         }\r
209                 }\r
210                 \r
211                 /* Call the ARP timer function every 10 seconds. */\r
212                 if( ( ulUIP_Events & uipARP_TIMER_EVENT ) != 0 )\r
213                 {\r
214                         ulUIP_Events &= ~uipARP_TIMER_EVENT;\r
215                         uip_arp_timer();\r
216                 }\r
217                         \r
218                 if( ulUIP_Events == pdFALSE )\r
219                 {\r
220                         xQueueReceive( xEMACEventQueue, &ulNewEvent, portMAX_DELAY );\r
221                         ulUIP_Events |= ulNewEvent;\r
222                 }\r
223         }\r
224 }\r
225 /*-----------------------------------------------------------*/\r
226 \r
227 static void prvInitialise_uIP( void )\r
228 {\r
229 xTimerHandle xARPTimer, xPeriodicTimer;\r
230 uip_ipaddr_t xIPAddr;\r
231 const unsigned long ul_uIPEventQueueLength = 10UL;\r
232 \r
233         /* Initialise the uIP stack. */\r
234         uip_init();\r
235         uip_ipaddr( &xIPAddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );\r
236         uip_sethostaddr( &xIPAddr );\r
237         uip_ipaddr( &xIPAddr, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 );\r
238         uip_setnetmask( &xIPAddr );\r
239         prvSetMACAddress();\r
240         httpd_init();\r
241 \r
242         /* Create the queue used to sent TCP/IP events to the uIP stack. */\r
243         xEMACEventQueue = xQueueCreate( ul_uIPEventQueueLength, sizeof( unsigned long ) );\r
244 \r
245         /* Create and start the uIP timers. */\r
246         xARPTimer = xTimerCreate(       ( const signed char * const ) "ARPTimer", /* Just a name that is helpful for debugging, not used by the kernel. */\r
247                                                                 ( 10000UL / portTICK_RATE_MS ), /* Timer period. */\r
248                                                                 pdTRUE, /* Autor-reload. */\r
249                                                                 ( void * ) uipARP_TIMER,\r
250                                                                 prvUIPTimerCallback\r
251                                                         );\r
252 \r
253         xPeriodicTimer = xTimerCreate(  ( const signed char * const ) "PeriodicTimer",\r
254                                                                         ( 50 / portTICK_RATE_MS ),\r
255                                                                         pdTRUE, /* Autor-reload. */\r
256                                                                         ( void * ) uipPERIODIC_TIMER,\r
257                                                                         prvUIPTimerCallback\r
258                                                                 );\r
259 \r
260         configASSERT( xARPTimer );\r
261         configASSERT( xPeriodicTimer );\r
262 \r
263         xTimerStart( xARPTimer, portMAX_DELAY );\r
264         xTimerStart( xPeriodicTimer, portMAX_DELAY );\r
265 }\r
266 /*-----------------------------------------------------------*/\r
267 \r
268 static void prvUIPTimerCallback( xTimerHandle xTimer )\r
269 {\r
270 static const unsigned long ulARPTimerExpired = uipARP_TIMER_EVENT;\r
271 static const unsigned long ulPeriodicTimerExpired = uipPERIODIC_TIMER_EVENT;\r
272 \r
273         /* This is a time callback, so calls to xQueueSend() must not attempt to\r
274         block. */\r
275         switch( ( int ) pvTimerGetTimerID( xTimer ) )\r
276         {\r
277                 case uipARP_TIMER               :       xQueueSend( xEMACEventQueue, &ulARPTimerExpired, uipDONT_BLOCK );\r
278                                                                         break;\r
279 \r
280                 case uipPERIODIC_TIMER  :       xQueueSend( xEMACEventQueue, &ulPeriodicTimerExpired, uipDONT_BLOCK );\r
281                                                                         break;\r
282 \r
283                 default                                 :       /* Should not get here. */\r
284                                                                         break;\r
285         }\r
286 }\r
287 /*-----------------------------------------------------------*/\r
288 \r
289 static void prvSetMACAddress( void )\r
290 {\r
291 struct uip_eth_addr xAddr;\r
292 \r
293         /* Configure the MAC address in the uIP stack. */\r
294         xAddr.addr[ 0 ] = configMAC_ADDR0;\r
295         xAddr.addr[ 1 ] = configMAC_ADDR1;\r
296         xAddr.addr[ 2 ] = configMAC_ADDR2;\r
297         xAddr.addr[ 3 ] = configMAC_ADDR3;\r
298         xAddr.addr[ 4 ] = configMAC_ADDR4;\r
299         xAddr.addr[ 5 ] = configMAC_ADDR5;\r
300         uip_setethaddr( xAddr );\r
301 }\r
302 /*-----------------------------------------------------------*/\r
303 \r
304 void vApplicationProcessFormInput( char *pcInputString )\r
305 {\r
306 char *c;\r
307 \r
308         /* Only interested in processing form input if this is the IO page. */\r
309         c = strstr( pcInputString, "io.shtml" );\r
310         \r
311         if( c )\r
312         {\r
313                 /* Is there a command in the string? */\r
314                 c = strstr( pcInputString, "?" );\r
315             if( c )\r
316             {\r
317                         /* Turn the LED's on or off in accordance with the check box status. */\r
318                         if( strstr( c, "LED0=1" ) != NULL )\r
319                         {\r
320                                 /* Turn the LEDs on. */\r
321                                 vParTestSetLED( 7, 1 );\r
322                                 vParTestSetLED( 8, 1 );\r
323                                 vParTestSetLED( 9, 1 );\r
324                                 vParTestSetLED( 10, 1 );\r
325                         }\r
326                         else\r
327                         {\r
328                                 /* Turn the LEDs off. */\r
329                                 vParTestSetLED( 7, 0 );\r
330                                 vParTestSetLED( 8, 0 );\r
331                                 vParTestSetLED( 9, 0 );\r
332                                 vParTestSetLED( 10, 0 );\r
333                         }\r
334             }\r
335                 else\r
336                 {\r
337                         /* Commands to turn LEDs off are not always explicit. */\r
338                         vParTestSetLED( 7, 0 );\r
339                         vParTestSetLED( 8, 0 );\r
340                         vParTestSetLED( 9, 0 );\r
341                         vParTestSetLED( 10, 0 );\r
342                 }\r
343         }\r
344 }\r
345 \r