LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dualcore_webserver.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 "arch/lpc18xx_43xx_emac.h"
61 #include "arch/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 extern void http_server_netconn_init(void);
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 
119 /*****************************************************************************
120  * Private types/enumerations/variables
121  ****************************************************************************/
122 
123 /* LWIP Network interface object structure */
124 static struct netif lpc_netif;
125 
126 /*****************************************************************************
127  * Private functions
128  ****************************************************************************/
129 
130 static void ip_addr_changed(const struct netif *nwif)
131 {
132  char tmp_buff[16];
133  extern void EVENT_lwip_addr_changed(uint32_t);
134 
135  if (!nwif->ip_addr.addr) return;
136 
137  DEBUGOUT("IP_ADDR : %s\r\n", ipaddr_ntoa_r((const ip_addr_t *) &nwif->ip_addr, tmp_buff, 16));
138  DEBUGOUT("NET_MASK : %s\r\n", ipaddr_ntoa_r((const ip_addr_t *) &nwif->netmask, tmp_buff, 16));
139  DEBUGOUT("GATEWAY_IP : %s\r\n", ipaddr_ntoa_r((const ip_addr_t *) &nwif->gw, tmp_buff, 16));
140  EVENT_lwip_addr_changed(nwif->ip_addr.addr);
141 }
142 
143 #if (defined(OS_FREE_RTOS) || defined(OS_UCOS_III))
144 
149 static void tcpip_init_done_signal(void *arg)
150 {
151  /* Tell main thread TCP/IP init is done */
152  *(s32_t *) arg = 1;
153 }
154 
159 #ifdef OS_FREE_RTOS
160 static portTASK_FUNCTION(vSetupIFTask, pvParameters)
161 #elif OS_UCOS_III
162 static void lwip_app_task(void *arg)
163 #endif
164 {
165  ip_addr_t ipaddr, netmask, gw;
166  volatile s32_t tcpipdone = 0;
168  static int prt_ip = 0;
169 
170  /* Wait until the TCP/IP thread is finished before
171  continuing or wierd things may happen */
172  DEBUGSTR("Waiting for TCPIP thread to initialize...\r\n");
173  tcpip_init(tcpip_init_done_signal, (void *) &tcpipdone);
174  while (!tcpipdone) ;
175 
176  DEBUGSTR("Starting LWIP HTTP server...\r\n");
177 
178  /* Static IP assignment */
179 #if LWIP_DHCP
180  IP4_ADDR(&gw, 0, 0, 0, 0);
181  IP4_ADDR(&ipaddr, 0, 0, 0, 0);
182  IP4_ADDR(&netmask, 0, 0, 0, 0);
183 #else
184  IP4_ADDR(&gw, 10, 1, 10, 1);
185  IP4_ADDR(&ipaddr, 10, 1, 10, 234);
186  IP4_ADDR(&netmask, 255, 255, 255, 0);
187 #endif
188 
189  /* Add netif interface for lpc17xx_8x */
190  memset(&lpc_netif, 0, sizeof(lpc_netif));
191  if (!netif_add(&lpc_netif, &ipaddr, &netmask, &gw, NULL, lpc_enetif_init,
192  tcpip_input)) {
193  DEBUGSTR("Net interface failed to initialize ..\r\n");
194  while (1) ;
195  }
196 
197  netif_set_default(&lpc_netif);
198  netif_set_up(&lpc_netif);
199 
200  /* Enable MAC interrupts only after LWIP is ready */
201  NVIC_SetPriority(ETHERNET_IRQn, IRQ_PRIO_ETHERNET);
202  NVIC_EnableIRQ(ETHERNET_IRQn);
203 
204 #if LWIP_DHCP
205  dhcp_start(&lpc_netif);
206 #endif
207 
208  /* Initialize and start application */
209  http_server_netconn_init();
210 
211  /* This loop monitors the PHY link and will handle cable events
212  via the PHY driver. */
213  while (1) {
214  /* Call the PHY status update state machine once in a while
215  to keep the link status up-to-date */
216  physts = lpcPHYStsPoll();
217 
218  /* Only check for connection state when the PHY status has changed */
219  if (physts & PHY_LINK_CHANGED) {
220  if (physts & PHY_LINK_CONNECTED) {
221  /* Set interface speed and duplex */
222  if (physts & PHY_LINK_SPEED100) {
223  NETIF_INIT_SNMP(&lpc_netif, snmp_ifType_ethernet_csmacd, 100000000);
224  }
225  else {
226  NETIF_INIT_SNMP(&lpc_netif, snmp_ifType_ethernet_csmacd, 10000000);
227  }
228  if (physts & PHY_LINK_FULLDUPLX) {
230  }
231  else {
233  }
234 
235  tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_up,
236  (void *) &lpc_netif, 1);
237  }
238  else {
239  tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_down,
240  (void *) &lpc_netif, 1);
241  }
242  }
243 
244  // DEBUGOUT("Link connect status: %d\n", ((physts & PHY_LINK_CONNECTED) != 0));
245 
246  /* Delay for link detection */
247  msDelay(250);
248 
249  if (!prt_ip && lpc_netif.ip_addr.addr) {
250  prt_ip = 1;
252  }
253  }
254 }
255 
256 #endif
257 
258 /*****************************************************************************
259  * Public functions
260  ****************************************************************************/
261 
262 extern void lcd_update_hostip(uint32_t host_ip);
263 
264 #ifdef OS_FREE_RTOS
265 
271 /*********************************************************************/
277 void msDelay(uint32_t ms)
278 {
279  vTaskDelay((configTICK_RATE_HZ * ms) / 1000);
280 }
281 
282 #endif
283 
284 /* lwIP initialization function */
285 void LWIP_Init(void)
286 {
287  #ifdef OS_FREE_RTOS
288  return;
289  #elif defined(OS_UCOS_III)
290  return;
291  #else
292  extern void lwip_init(void);
293 
294  ip_addr_t ipaddr, netmask, gw;
295 
296  /* Setup a 1mS sysTick for the primary time base */
297  SysTick_Enable(1);
298 
299  /* Initialize LWIP */
300  DEBUGSTR("Starting lwip_init...\r\n");
301  lwip_init();
302 
303  DEBUGSTR("Starting LWIP HTTP server...\r\n");
304 
305  /* Static IP assignment */
306 #if LWIP_DHCP
307  IP4_ADDR(&gw, 0, 0, 0, 0);
308  IP4_ADDR(&ipaddr, 0, 0, 0, 0);
309  IP4_ADDR(&netmask, 0, 0, 0, 0);
310 #else
311  IP4_ADDR(&gw, 10, 1, 10, 1);
312  IP4_ADDR(&ipaddr, 10, 1, 10, 234);
313  IP4_ADDR(&netmask, 255, 255, 255, 0);
314 #endif
315 
316  /* Add netif interface for lpc17xx_8x */
317  netif_add(&lpc_netif, &ipaddr, &netmask, &gw, NULL, lpc_enetif_init,
318  ethernet_input);
319  netif_set_default(&lpc_netif);
320  netif_set_up(&lpc_netif);
321 
322 #if LWIP_DHCP
323  dhcp_start(&lpc_netif);
324 #endif
325 
326  /* Initialize and start application */
327  httpd_init();
328 
329  return;
330 #endif
331 }
332 
333 #if (defined(OS_FREE_RTOS) || defined(OS_UCOS_III))
334 
342 void lwip_tasks(void)
343 {
344 #ifdef OS_FREE_RTOS
345  xTaskCreate(vSetupIFTask, (signed char *) "SetupIFx",
346  256, NULL, (tskIDLE_PRIORITY + 1UL),
347  (xTaskHandle *) NULL);
348 #elif OS_UCOS_III
349  OS_ERR os_err;
350  static OS_TCB lwip_app_taskTCB;
351  static CPU_STK lwip_app_taskSTK[UCOS_MIN_STACK_SZ];
352 
353  OSTaskCreate((OS_TCB *) &lwip_app_taskTCB, /* Create the start task */
354  (CPU_CHAR *) "Start",
355  (OS_TASK_PTR) lwip_app_task,
356  (void *) 0,
358  (CPU_STK *) &lwip_app_taskSTK[0],
359  (CPU_STK_SIZE) 32,
361  (OS_MSG_QTY) 0u,
362  (OS_TICK) 0u,
363  (void *) 0,
365  (OS_ERR *) &os_err);
366 #endif
367 }
368 
369 #else
370 
371 /* lwIP Tasks */
372 void lwip_tasks(void)
373 {
375  static int prt_ip = 0;
376 
377  do {
378  /* Handle packets as part of this loop, not in the IRQ handler */
380 
381  /* Free TX buffers that are done sending */
383 
384  /* LWIP timers - ARP, DHCP, TCP, etc. */
385  sys_check_timeouts();
386 
387  /* Call the PHY status update state machine once in a while
388  to keep the link status up-to-date */
389  physts = lpcPHYStsPoll();
390 
391  /* Only check for connection state when the PHY status has changed */
392  if (physts & PHY_LINK_CHANGED) {
393  if (physts & PHY_LINK_CONNECTED) {
394  /* Set interface speed and duplex */
395  if (physts & PHY_LINK_SPEED100) {
396  NETIF_INIT_SNMP(&lpc_netif, snmp_ifType_ethernet_csmacd, 100000000);
397  }
398  else {
399  NETIF_INIT_SNMP(&lpc_netif, snmp_ifType_ethernet_csmacd, 10000000);
400  }
401  if (physts & PHY_LINK_FULLDUPLX) {
403  }
404  else {
406  }
407 
408  netif_set_link_up(&lpc_netif);
409  }
410  else {
411  netif_set_link_down(&lpc_netif);
412  }
413  }
414 
415  /* DEBUGOUT("Link connect status: %d\r\n", ((physts & PHY_LINK_CONNECTED) != 0)); */
416 
417  if (!prt_ip && lpc_netif.ip_addr.addr) {
418  prt_ip = 1;
420  }
421  } while (0);
422 }
423 
424 #endif
425 
426 #ifdef __IAR_SYSTEMS_ICC__
427 WEAK_SYMBOL
428 #else
429 WEAK_SYMBOL void EVENT_lwip_addr_changed(uint32_t new_addr);
430 #endif
431 
439 void EVENT_lwip_addr_changed(uint32_t new_addr)
440 {
441  ipcex_msgPush(IPCEX_ID_USER1, new_addr);
442 }