2 * FreeRTOS Kernel V10.2.1
\r
3 * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
\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
12 * The above copyright notice and this permission notice shall be included in all
\r
13 * copies or substantial portions of the Software.
\r
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
\r
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
\r
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
\r
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
22 * http://www.FreeRTOS.org
\r
23 * http://aws.amazon.com/freertos
\r
25 * 1 tab == 4 spaces!
\r
28 /* Standard includes. */
\r
31 /* Scheduler includes. */
\r
32 #include "FreeRTOS.h"
\r
38 #include "net/uip.h"
\r
39 #include "net/uip_arp.h"
\r
40 #include "apps/httpd/httpd.h"
\r
41 #include "sys/timer.h"
\r
42 #include "net/clock-arch.h"
\r
45 /* Demo includes. */
\r
46 #include "ParTest.h"
\r
48 /* The buffer used by the uIP stack to both receive and send. In this case,
\r
49 because the Ethernet driver is implemented to be zero copy - the uip_buf
\r
50 variable is just a pointer to an Ethernet buffer, and not a buffer in its own
\r
52 extern unsigned char *uip_buf;
\r
54 /* The ARP timer and the periodic timer share a callback function, so the
\r
55 respective timer IDs are used to determine which timer actually expired. These
\r
56 constants are assigned to the timer IDs. */
\r
57 #define uipARP_TIMER 0
\r
58 #define uipPERIODIC_TIMER 1
\r
60 /* The length of the queue used to send events from timers or the Ethernet
\r
61 driver to the uIP stack. */
\r
62 #define uipEVENT_QUEUE_LENGTH 10
\r
64 /* A block time of zero simply means "don't block". */
\r
65 #define uipDONT_BLOCK 0UL
\r
67 /* Shortcut to the header within the Rx buffer. */
\r
68 #define xHeader ((struct uip_eth_hdr *) &uip_buf[ 0 ])
\r
70 /*-----------------------------------------------------------*/
\r
73 * Setup the MAC address in the MAC itself, and in the uIP stack.
\r
75 static void prvSetMACAddress( void );
\r
78 * Perform any uIP initialisation required to ready the stack for http
\r
81 static void prvInitialise_uIP( void );
\r
84 * The callback function that is assigned to both the periodic timer and the
\r
87 static void prvUIPTimerCallback( TimerHandle_t xTimer );
\r
90 * Port functions required by the uIP stack.
\r
92 clock_time_t clock_time( void );
\r
94 /*-----------------------------------------------------------*/
\r
96 /* The queue used to send TCP/IP events to the uIP stack. */
\r
97 QueueHandle_t xEMACEventQueue = NULL;
\r
99 /*-----------------------------------------------------------*/
\r
101 clock_time_t clock_time( void )
\r
103 return xTaskGetTickCount();
\r
105 /*-----------------------------------------------------------*/
\r
107 void vuIP_Task( void *pvParameters )
\r
110 unsigned long ulNewEvent = 0UL, ulUIP_Events = 0UL;
\r
111 unsigned short usPacketLength;
\r
113 /* Just to prevent compiler warnings about the unused parameter. */
\r
114 ( void ) pvParameters;
\r
116 /* Initialise the uIP stack, configuring for web server usage. */
\r
117 prvInitialise_uIP();
\r
119 /* Initialise the MAC and PHY. */
\r
124 /* Is there received data ready to be processed? */
\r
125 usPacketLength = usEMACRead();
\r
127 /* Statements to be executed if data has been received on the Ethernet. */
\r
128 if( ( usPacketLength > 0U ) && ( uip_buf != NULL ) )
\r
130 uip_len = usPacketLength;
\r
132 if( xHeader->type == htons( UIP_ETHTYPE_IP ) )
\r
137 /* If the above function invocation resulted in data that
\r
138 should be sent out on the network, the global variable
\r
139 uip_len is set to a value > 0. */
\r
146 else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )
\r
150 /* If the above function invocation resulted in data that
\r
151 should be sent out on the network, the global variable
\r
152 uip_len is set to a value > 0. */
\r
161 /* Clear the RX event latched in ulUIP_Events - if one was latched. */
\r
162 ulUIP_Events &= ~uipETHERNET_RX_EVENT;
\r
165 /* Statements to be executed if the TCP/IP period timer has expired. */
\r
166 if( ( ulUIP_Events & uipPERIODIC_TIMER_EVENT ) != 0UL )
\r
168 ulUIP_Events &= ~uipPERIODIC_TIMER_EVENT;
\r
170 if( uip_buf != NULL )
\r
172 for( i = 0; i < UIP_CONNS; i++ )
\r
176 /* If the above function invocation resulted in data that
\r
177 should be sent out on the network, the global variable
\r
178 uip_len is set to a value > 0. */
\r
188 /* Statements to be executed if the ARP timer has expired. */
\r
189 if( ( ulUIP_Events & uipARP_TIMER_EVENT ) != 0 )
\r
191 ulUIP_Events &= ~uipARP_TIMER_EVENT;
\r
195 /* If all latched events have been cleared - block until another event
\r
197 if( ulUIP_Events == pdFALSE )
\r
199 xQueueReceive( xEMACEventQueue, &ulNewEvent, portMAX_DELAY );
\r
200 ulUIP_Events |= ulNewEvent;
\r
204 /*-----------------------------------------------------------*/
\r
206 static void prvSetMACAddress( void )
\r
208 struct uip_eth_addr xAddr;
\r
210 /* Configure the MAC address in the uIP stack. */
\r
211 xAddr.addr[ 0 ] = configMAC_ADDR0;
\r
212 xAddr.addr[ 1 ] = configMAC_ADDR1;
\r
213 xAddr.addr[ 2 ] = configMAC_ADDR2;
\r
214 xAddr.addr[ 3 ] = configMAC_ADDR3;
\r
215 xAddr.addr[ 4 ] = configMAC_ADDR4;
\r
216 xAddr.addr[ 5 ] = configMAC_ADDR5;
\r
217 uip_setethaddr( xAddr );
\r
219 /*-----------------------------------------------------------*/
\r
221 static void prvInitialise_uIP( void )
\r
223 uip_ipaddr_t xIPAddr;
\r
224 TimerHandle_t xARPTimer, xPeriodicTimer;
\r
227 uip_ipaddr( &xIPAddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );
\r
228 uip_sethostaddr( &xIPAddr );
\r
229 uip_ipaddr( &xIPAddr, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 );
\r
230 uip_setnetmask( &xIPAddr );
\r
231 prvSetMACAddress();
\r
234 /* Create the queue used to sent TCP/IP events to the uIP stack. */
\r
235 xEMACEventQueue = xQueueCreate( uipEVENT_QUEUE_LENGTH, sizeof( unsigned long ) );
\r
237 /* Create and start the uIP timers. */
\r
238 xARPTimer = xTimerCreate( "ARPTimer", /* Just a name that is helpful for debugging, not used by the kernel. */
\r
239 ( 10000UL / portTICK_PERIOD_MS ), /* Timer period. */
\r
240 pdTRUE, /* Autor-reload. */
\r
241 ( void * ) uipARP_TIMER,
\r
242 prvUIPTimerCallback
\r
245 xPeriodicTimer = xTimerCreate( "PeriodicTimer",
\r
246 ( 500UL / portTICK_PERIOD_MS ),
\r
247 pdTRUE, /* Autor-reload. */
\r
248 ( void * ) uipPERIODIC_TIMER,
\r
249 prvUIPTimerCallback
\r
252 /* Sanity check that the timers were indeed created. */
\r
253 configASSERT( xARPTimer );
\r
254 configASSERT( xPeriodicTimer );
\r
255 configASSERT( xEMACEventQueue );
\r
257 /* These commands will block indefinitely until they succeed, so there is
\r
258 no point in checking their return values. */
\r
259 xTimerStart( xARPTimer, portMAX_DELAY );
\r
260 xTimerStart( xPeriodicTimer, portMAX_DELAY );
\r
262 /*-----------------------------------------------------------*/
\r
264 static void prvUIPTimerCallback( TimerHandle_t xTimer )
\r
266 static const unsigned long ulARPTimerExpired = uipARP_TIMER_EVENT;
\r
267 static const unsigned long ulPeriodicTimerExpired = uipPERIODIC_TIMER_EVENT;
\r
269 /* This is a time callback, so calls to xQueueSend() must not attempt to
\r
270 block. As this callback is assigned to both the ARP and Periodic timers, the
\r
271 first thing to do is ascertain which timer it was that actually expired. */
\r
272 switch( ( int ) pvTimerGetTimerID( xTimer ) )
\r
274 case uipARP_TIMER : xQueueSend( xEMACEventQueue, &ulARPTimerExpired, uipDONT_BLOCK );
\r
277 case uipPERIODIC_TIMER : xQueueSend( xEMACEventQueue, &ulPeriodicTimerExpired, uipDONT_BLOCK );
\r
280 default : /* Should not get here. */
\r
284 /*-----------------------------------------------------------*/
\r
286 void vApplicationProcessFormInput( char *pcInputString )
\r
289 const unsigned long ulYellowLED = 2UL;
\r
291 /* Only interested in processing form input if this is the IO page. */
\r
292 c = strstr( pcInputString, "io.shtml" );
\r
296 /* Is there a command in the string? */
\r
297 c = strstr( pcInputString, "?" );
\r
300 /* Turn the LEDs on or off in accordance with the check box status. */
\r
301 if( strstr( c, "LED0=1" ) != NULL )
\r
303 /* Turn the LEDs on. */
\r
304 vParTestSetLED( ulYellowLED, pdTRUE );
\r
308 /* Turn the LEDs off. */
\r
309 vParTestSetLED( ulYellowLED, pdFALSE );
\r
314 /* Some browsers will only imply that a check box is off. */
\r
315 vParTestSetLED( ulYellowLED, pdFALSE );
\r
319 /*-----------------------------------------------------------*/
\r