LPCOpen Platform
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
example_lwip_httpserver.c
Go to the documentation of this file.
1 /*
2  * @brief HTTP server dual core example using lwIP ethernet stack
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products. This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights. NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers. This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
39 /* General Includes */
40 #include <string.h>
41 #include "lpc43xx_dualcore_config.h"
42 #include "ipc_msg.h"
43 #include "ipc_example.h"
44 
45 /* lwIP include files */
46 #include "lwip/opt.h"
47 #include "lwip/sys.h"
48 #include "lwip/memp.h"
49 #include "lwip/tcpip.h"
50 #include "lwip/ip_addr.h"
51 #include "lwip/netif.h"
52 #include "lwip/timers.h"
53 
54 #include "netif/etharp.h"
55 
56 #if LWIP_DHCP
57 #include "lwip/dhcp.h"
58 #endif
59 
60 #include "lpc18xx_43xx_emac.h"
61 #include "lpc_arch.h"
62 #include "lpc_phy.h"/* For the PHY monitor support */
63 
64 #if (defined(OS_FREE_RTOS) || defined(OS_UCOS_III))
65 #include "httpserver-netconn.h"
66 #else
67 #include "httpd.h"
68 #endif
69 
70 #ifdef OS_FREE_RTOS
71 #include "FreeRTOS.h"
72 #include "task.h"
73 #endif
74 
75 #ifdef OS_UCOS_III
76 #include "os.h"
77 
78 #define UCOS_MIN_STACK_SZ 512
79 #define UCOS_BLINK_TASK_PRIORITY 12
80 #define UCOS_EVENT_TASK_PRIORITY 13
81 #endif
82 
105 /*****************************************************************************
106  * Private types/enumerations/variables
107  ****************************************************************************/
108 
109 /* LWIP Network interface object structure */
110 static struct netif lpc_netif;
111 
112 /*****************************************************************************
113  * Private functions
114  ****************************************************************************/
115 
116 #if (defined(OS_FREE_RTOS) || defined(OS_UCOS_III))
117 
122 static void tcpip_init_done_signal(void *arg)
123 {
124  /* Tell main thread TCP/IP init is done */
125  *(s32_t *) arg = 1;
126 }
127 
132 #ifdef OS_FREE_RTOS
133 static portTASK_FUNCTION(vSetupIFTask, pvParameters)
134 #elif OS_UCOS_III
135 static void lwip_app_task(void *arg)
136 #endif
137 {
138  ip_addr_t ipaddr, netmask, gw;
139  volatile s32_t tcpipdone = 0;
141  static int prt_ip = 0;
142 
143  /* Wait until the TCP/IP thread is finished before
144  continuing or wierd things may happen */
145  DEBUGSTR("Waiting for TCPIP thread to initialize...\r\n");
146  tcpip_init(tcpip_init_done_signal, (void *) &tcpipdone);
147  while (!tcpipdone) ;
148 
149  DEBUGSTR("Starting LWIP HTTP server...\r\n");
150 
151  /* Static IP assignment */
152 #if LWIP_DHCP
153  IP4_ADDR(&gw, 0, 0, 0, 0);
154  IP4_ADDR(&ipaddr, 0, 0, 0, 0);
155  IP4_ADDR(&netmask, 0, 0, 0, 0);
156 #else
157  IP4_ADDR(&gw, 10, 1, 10, 1);
158  IP4_ADDR(&ipaddr, 10, 1, 10, 234);
159  IP4_ADDR(&netmask, 255, 255, 255, 0);
160 #endif
161 
162  /* Add netif interface for lpc17xx_8x */
163  memset(&lpc_netif, 0, sizeof(lpc_netif));
164  if (!netif_add(&lpc_netif, &ipaddr, &netmask, &gw, NULL, lpc_enetif_init,
165  tcpip_input)) {
166  DEBUGSTR("Net interface failed to initialize ..\r\n");
167  while (1) ;
168  }
169 
170  netif_set_default(&lpc_netif);
171  netif_set_up(&lpc_netif);
172 
173  /* Enable MAC interrupts only after LWIP is ready */
174  NVIC_SetPriority(ETHERNET_IRQn, IRQ_PRIO_ETHERNET);
175  NVIC_EnableIRQ(ETHERNET_IRQn);
176 
177 #if LWIP_DHCP
178  dhcp_start(&lpc_netif);
179 #endif
180 
181  /* Initialize and start application */
182  http_server_netconn_init();
183 
184  /* This loop monitors the PHY link and will handle cable events
185  via the PHY driver. */
186  while (1) {
187  /* Call the PHY status update state machine once in a while
188  to keep the link status up-to-date */
189  physts = lpcPHYStsPoll();
190 
191  /* Only check for connection state when the PHY status has changed */
192  if (physts & PHY_LINK_CHANGED) {
193  if (physts & PHY_LINK_CONNECTED) {
194  /* Set interface speed and duplex */
195  if (physts & PHY_LINK_SPEED100) {
196  NETIF_INIT_SNMP(&lpc_netif, snmp_ifType_ethernet_csmacd, 100000000);
197  }
198  else {
199  NETIF_INIT_SNMP(&lpc_netif, snmp_ifType_ethernet_csmacd, 10000000);
200  }
201  if (physts & PHY_LINK_FULLDUPLX) {
202  Chip_ENET_Set_Duplex(true);
203  }
204  else {
205  Chip_ENET_Set_Duplex(false);
206  }
207 
208  tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_up,
209  (void *) &lpc_netif, 1);
210  }
211  else {
212  tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_down,
213  (void *) &lpc_netif, 1);
214  }
215  }
216 
217  // DEBUGOUT("Link connect status: %d\n", ((physts & PHY_LINK_CONNECTED) != 0));
218 
219  /* Delay for link detection */
220  msDelay(250);
221 
222  if (!prt_ip) {
223  if (lpc_netif.ip_addr.addr) {
224  char tmp_buff[16];
225  DEBUGOUT("IP_ADDR : %s\r\n", ipaddr_ntoa_r((const ip_addr_t *) &lpc_netif.ip_addr, tmp_buff, 16));
226  DEBUGOUT("NET_MASK : %s\r\n", ipaddr_ntoa_r((const ip_addr_t *) &lpc_netif.netmask, tmp_buff, 16));
227  DEBUGOUT("GATEWAY_IP : %s\r\n", ipaddr_ntoa_r((const ip_addr_t *) &lpc_netif.gw, tmp_buff, 16));
228  /* Push the remote IP address to other core */
229  ipcex_msgPush(IPCEX_ID_USER1, lpc_netif.ip_addr.addr);
230  prt_ip = 1;
231  }
232  }
233  }
234 }
235 
236 #endif
237 
238 /*****************************************************************************
239  * Public functions
240  ****************************************************************************/
241 
242 #ifdef OS_FREE_RTOS
243 
249 /*********************************************************************/
255 void msDelay(uint32_t ms)
256 {
257  vTaskDelay((configTICK_RATE_HZ * ms) / 1000);
258 }
259 
260 #endif
261 
262 /* lwIP initialization function */
263 void LWIP_Init(void)
264 {
265  #ifdef OS_FREE_RTOS
266  return;
267  #elif defined(OS_UCOS_III)
268  return;
269  #else
270  extern void lwip_init(void);
271 
272  ip_addr_t ipaddr, netmask, gw;
273 
274  /* Setup a 1mS sysTick for the primary time base */
275  SysTick_Enable(1);
276 
277  /* Initialize LWIP */
278  DEBUGSTR("Starting lwip_init...\r\n");
279  lwip_init();
280 
281  DEBUGSTR("Starting LWIP HTTP server...\r\n");
282 
283  /* Static IP assignment */
284 #if LWIP_DHCP
285  IP4_ADDR(&gw, 0, 0, 0, 0);
286  IP4_ADDR(&ipaddr, 0, 0, 0, 0);
287  IP4_ADDR(&netmask, 0, 0, 0, 0);
288 #else
289  IP4_ADDR(&gw, 10, 1, 10, 1);
290  IP4_ADDR(&ipaddr, 10, 1, 10, 234);
291  IP4_ADDR(&netmask, 255, 255, 255, 0);
292 #endif
293 
294  /* Add netif interface for lpc17xx_8x */
295  netif_add(&lpc_netif, &ipaddr, &netmask, &gw, NULL, lpc_enetif_init,
296  ethernet_input);
297  netif_set_default(&lpc_netif);
298  netif_set_up(&lpc_netif);
299 
300 #if LWIP_DHCP
301  dhcp_start(&lpc_netif);
302 #endif
303 
304  /* Initialize and start application */
305  httpd_init();
306 
307  return;
308 #endif
309 }
310 
311 #if (defined(OS_FREE_RTOS) || defined(OS_UCOS_III))
312 
320 void lwip_tasks(void)
321 {
322 #ifdef OS_FREE_RTOS
323  xTaskCreate(vSetupIFTask, (signed char *) "SetupIFx",
324  256, NULL, (tskIDLE_PRIORITY + 1UL),
325  (xTaskHandle *) NULL);
326 #elif OS_UCOS_III
327  OS_ERR os_err;
328  static OS_TCB lwip_app_taskTCB;
329  static CPU_STK lwip_app_taskSTK[UCOS_MIN_STACK_SZ];
330 
331  OSTaskCreate((OS_TCB *) &lwip_app_taskTCB, /* Create the start task */
332  (CPU_CHAR *) "Start",
333  (OS_TASK_PTR) lwip_app_task,
334  (void *) 0,
335  (OS_PRIO) (APP_CFG_TASK_START_PRIO),
336  (CPU_STK *) &lwip_app_taskSTK[0],
337  (CPU_STK_SIZE) 32,
338  (CPU_STK_SIZE) UCOS_MIN_STACK_SZ,
339  (OS_MSG_QTY) 0u,
340  (OS_TICK) 0u,
341  (void *) 0,
342  (OS_OPT) (OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
343  (OS_ERR *) &os_err);
344 #endif
345 }
346 
347 #else
348 
349 /* lwIP Tasks */
350 void lwip_tasks(void)
351 {
353  static int prt_ip = 0;
354 
355  do {
356  /* Handle packets as part of this loop, not in the IRQ handler */
358 
359  /* Free TX buffers that are done sending */
361 
362  /* LWIP timers - ARP, DHCP, TCP, etc. */
363  sys_check_timeouts();
364 
365  /* Call the PHY status update state machine once in a while
366  to keep the link status up-to-date */
367  physts = lpcPHYStsPoll();
368 
369  /* Only check for connection state when the PHY status has changed */
370  if (physts & PHY_LINK_CHANGED) {
371  if (physts & PHY_LINK_CONNECTED) {
372  /* Set interface speed and duplex */
373  if (physts & PHY_LINK_SPEED100) {
374  NETIF_INIT_SNMP(&lpc_netif, snmp_ifType_ethernet_csmacd, 100000000);
375  }
376  else {
377  NETIF_INIT_SNMP(&lpc_netif, snmp_ifType_ethernet_csmacd, 10000000);
378  }
379  if (physts & PHY_LINK_FULLDUPLX) {
380  Chip_ENET_Set_Duplex(true);
381  }
382  else {
383  Chip_ENET_Set_Duplex(false);
384  }
385 
386  netif_set_link_up(&lpc_netif);
387  }
388  else {
389  netif_set_link_down(&lpc_netif);
390  }
391  }
392 
393  /* DEBUGOUT("Link connect status: %d\r\n", ((physts & PHY_LINK_CONNECTED) != 0)); */
394 
395  if (!prt_ip) {
396  if (lpc_netif.ip_addr.addr) {
397  static char tmp_buff[16];
398  DEBUGOUT("IP_ADDR : %s\r\n", ipaddr_ntoa_r((const ip_addr_t *) &lpc_netif.ip_addr, tmp_buff, 16));
399  DEBUGOUT("NET_MASK : %s\r\n", ipaddr_ntoa_r((const ip_addr_t *) &lpc_netif.netmask, tmp_buff, 16));
400  DEBUGOUT("GATEWAY_IP : %s\r\n", ipaddr_ntoa_r((const ip_addr_t *) &lpc_netif.gw, tmp_buff, 16));
401  /* Push the remote IP address to other core */
402  ipcex_msgPush(IPCEX_ID_USER1, lpc_netif.ip_addr.addr);
403  prt_ip = 1;
404  }
405  }
406  } while (0);
407 }
408 
409 #endif
410