use tcpip_init_done_callback to initialize lwip stack.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1668 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
bernard.xiong 2011-08-11 10:05:37 +00:00
parent 922b40f614
commit 5a825fd81a
4 changed files with 138 additions and 108 deletions

View File

@ -1,6 +1,8 @@
#ifndef __LWIP_SYS_INIT_H__ #ifndef __LWIP_SYS_INIT_H__
#define __LWIP_SYS_INIT_H__ #define __LWIP_SYS_INIT_H__
void lwip_sys_init(); void lwip_sys_init(void);
void lwip_system_init(void);
#endif #endif

View File

@ -1,7 +1,4 @@
#include <rtthread.h> #include <rtthread.h>
#ifdef RT_USING_FINSH
#include <finsh.h>
#endif
#include "lwip/debug.h" #include "lwip/debug.h"
#include "lwip/mem.h" #include "lwip/mem.h"
@ -14,55 +11,136 @@
#include "netif/ethernetif.h" #include "netif/ethernetif.h"
#include "netif/etharp.h" #include "netif/etharp.h"
/* /* introduce from kservice.c */
* lwip system initial entry #define rt_list_entry(node, type, member) \
*/ ((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))
void lwip_sys_init()
{
struct ip_addr ipaddr, netmask, gw;
#if LWIP_DHCP static err_t netif_device_init(struct netif *netif)
rt_uint32_t mscnt = 0; {
struct eth_device *ethif;
ethif = (struct eth_device*)netif->state;
if (ethif != RT_NULL)
{
rt_device_t device;
/* get device object */
device = (rt_device_t) ethif;
if (rt_device_init(device) != RT_EOK)
{
return ERR_IF;
}
return ERR_OK;
}
return ERR_IF;
}
static void tcpip_init_done_callback(void *arg)
{
rt_device_t device;
struct eth_device *ethif;
struct ip_addr ipaddr, netmask, gw;
struct rt_list_node* node;
struct rt_object* object;
struct rt_object_information *information;
extern struct rt_object_information rt_object_container[];
LWIP_ASSERT("invalid arg.\n",arg);
IP4_ADDR(&gw, 0,0,0,0); IP4_ADDR(&gw, 0,0,0,0);
IP4_ADDR(&ipaddr, 0,0,0,0); IP4_ADDR(&ipaddr, 0,0,0,0);
IP4_ADDR(&netmask, 0,0,0,0); IP4_ADDR(&netmask, 0,0,0,0);
/* enter critical */
rt_enter_critical();
/* for each network interfaces */
information = &rt_object_container[RT_Object_Class_Device];
for (node = information->object_list.next; node != &(information->object_list); node = node->next)
{
object = rt_list_entry(node, struct rt_object, list);
device = (rt_device_t) object;
if (device->type == RT_Device_Class_NetIf)
{
ethif = (struct eth_device*)device;
/* leave critical */
rt_exit_critical();
netif_add(ethif->netif, &ipaddr, &netmask, &gw,
ethif, netif_device_init, tcpip_input);
if (netif_default == RT_NULL)
netif_set_default(ethif->netif);
#if LWIP_DHCP
dhcp_start(ethif->netif);
#else #else
netif_set_up(ethif->netif);
#endif
#ifdef LWIP_NETIF_LINK_CALLBACK
netif_set_link_up(ethif->netif);
#endif
/* enter critical */
rt_enter_critical();
}
}
/* leave critical */
rt_exit_critical();
rt_sem_release((rt_sem_t)arg);
}
/**
* LwIP system initialization
*/
void lwip_system_init(void)
{
rt_err_t rc;
struct rt_semaphore done_sem;
rc = rt_sem_init(&done_sem, "done", 0, RT_IPC_FLAG_FIFO);
if(rc != RT_EOK)
{
LWIP_ASSERT("Failed to create semaphore", 0);
return;
}
tcpip_init(tcpip_init_done_callback,(void *)&done_sem);
/* waiting for initialization done */
if (rt_sem_take(&done_sem, RT_WAITING_FOREVER) != RT_EOK)
{
rt_sem_detach(&done_sem);
return;
}
rt_sem_detach(&done_sem);
/* set default ip address */
#if !LWIP_DHCP
{
struct ip_addr ipaddr, netmask, gw;
IP4_ADDR(&ipaddr, RT_LWIP_IPADDR0, RT_LWIP_IPADDR1, RT_LWIP_IPADDR2, RT_LWIP_IPADDR3); IP4_ADDR(&ipaddr, RT_LWIP_IPADDR0, RT_LWIP_IPADDR1, RT_LWIP_IPADDR2, RT_LWIP_IPADDR3);
IP4_ADDR(&gw, RT_LWIP_GWADDR0, RT_LWIP_GWADDR1, RT_LWIP_GWADDR2, RT_LWIP_GWADDR3); IP4_ADDR(&gw, RT_LWIP_GWADDR0, RT_LWIP_GWADDR1, RT_LWIP_GWADDR2, RT_LWIP_GWADDR3);
IP4_ADDR(&netmask, RT_LWIP_MSKADDR0, RT_LWIP_MSKADDR1, RT_LWIP_MSKADDR2, RT_LWIP_MSKADDR3); IP4_ADDR(&netmask, RT_LWIP_MSKADDR0, RT_LWIP_MSKADDR1, RT_LWIP_MSKADDR2, RT_LWIP_MSKADDR3);
netifapi_netif_set_addr(netif_default, &ipaddr, &netmask, &gw);
}
#endif #endif
}
tcpip_init(RT_NULL, RT_NULL); /**
* Compatible with RT-Thread 0.2.x/0.3.x
netif_set_addr(netif_default, &ipaddr, &netmask, &gw); */
netif_set_up(netif_default); void lwip_sys_init(void)
#if LWIP_DHCP
/* use DHCP client */
dhcp_start(netif_default);
while (netif_default->ip_addr.addr == 0)
{ {
rt_thread_delay(DHCP_FINE_TIMER_MSECS * RT_TICK_PER_SECOND / 1000); lwip_system_init();
dhcp_fine_tmr();
mscnt += DHCP_FINE_TIMER_MSECS;
if (mscnt >= DHCP_COARSE_TIMER_SECS*1000)
{
dhcp_coarse_tmr();
mscnt = 0;
}
} }
rt_kprintf("Acquired IP address from DHCP server:");
rt_kprintf("%d.%d.%d.%d\n", netif_default->ip_addr.addr & 0xff,
(netif_default->ip_addr.addr>>8) & 0xff,
(netif_default->ip_addr.addr>>16) & 0xff,
(netif_default->ip_addr.addr>>24) & 0xff);
#endif
#if defined(RT_USING_FINSH) && (LWIP_STATS_DISPLAY)
finsh_syscall_append("lwip_info", (syscall_func)stats_display);
#endif
}

View File

@ -326,5 +326,6 @@
/* no read/write/close for socket */ /* no read/write/close for socket */
#define LWIP_POSIX_SOCKETS_IO_NAMES 0 #define LWIP_POSIX_SOCKETS_IO_NAMES 0
#define LWIP_NETIF_API 1
#endif /* __LWIPOPTS_H__ */ #endif /* __LWIPOPTS_H__ */

View File

@ -87,55 +87,6 @@ static char eth_tx_thread_mb_pool[RT_LWIP_ETHTHREAD_MBOX_SIZE * 4];
static char eth_tx_thread_stack[RT_LWIP_ETHTHREAD_STACKSIZE]; static char eth_tx_thread_stack[RT_LWIP_ETHTHREAD_STACKSIZE];
#endif #endif
/* the interface provided to LwIP */
err_t eth_init(struct netif *netif)
{
return ERR_OK;
}
err_t eth_input(struct pbuf *p, struct netif *inp)
{
struct eth_hdr *ethhdr;
if(p != RT_NULL)
{
#ifdef LINK_STATS
LINK_STATS_INC(link.recv);
#endif /* LINK_STATS */
ethhdr = p->payload;
switch(htons(ethhdr->type))
{
case ETHTYPE_IP:
etharp_ip_input(inp, p);
pbuf_header(p, -((rt_int16_t)sizeof(struct eth_hdr)));
if (tcpip_input(p, inp) != ERR_OK)
{
/* discard packet */
pbuf_free(p);
}
break;
case ETHTYPE_ARP:
etharp_arp_input(inp, (struct eth_addr *)inp->hwaddr, p);
break;
default:
pbuf_free(p);
p = RT_NULL;
break;
}
}
return ERR_OK;
}
err_t ethernetif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
{
return etharp_output(netif, p, ipaddr);
}
err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p) err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p)
{ {
struct eth_tx_msg msg; struct eth_tx_msg msg;
@ -184,27 +135,15 @@ rt_err_t eth_device_init(struct eth_device* dev, const char* name)
/* maximum transfer unit */ /* maximum transfer unit */
netif->mtu = ETHERNET_MTU; netif->mtu = ETHERNET_MTU;
/* broadcast capability */ /* broadcast capability */
netif->flags = NETIF_FLAG_BROADCAST; netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
/* get hardware address */ /* get hardware address */
rt_device_control(&(dev->parent), NIOCTL_GADDR, netif->hwaddr); rt_device_control(&(dev->parent), NIOCTL_GADDR, netif->hwaddr);
/* set output */ /* set output */
netif->output = ethernetif_output; netif->output = etharp_output;
netif->linkoutput = ethernetif_linkoutput; netif->linkoutput = ethernetif_linkoutput;
/* add netif to lwip */
if (netif_add(netif, IP_ADDR_ANY, IP_ADDR_BROADCAST, IP_ADDR_ANY, dev,
eth_init, eth_input) == RT_NULL)
{
/* failed, unregister device and free netif */
rt_device_unregister(&(dev->parent));
rt_free(netif);
return -RT_ERROR;
}
netif_set_default(netif);
return RT_EOK; return RT_EOK;
} }
@ -256,7 +195,12 @@ void eth_rx_thread_entry(void* parameter)
if (p != RT_NULL) if (p != RT_NULL)
{ {
/* notify to upper layer */ /* notify to upper layer */
eth_input(p, device->netif); if( device->netif->input(p, device->netif) != ERR_OK )
{
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: Input error\n"));
pbuf_free(p);
p = NULL;
}
} }
else break; else break;
} }
@ -264,12 +208,17 @@ void eth_rx_thread_entry(void* parameter)
} }
} }
rt_err_t eth_device_ready(struct eth_device* dev) rt_err_t eth_rx_ready(struct eth_device* dev)
{ {
/* post message to ethernet thread */ /* post message to ethernet thread */
return rt_mb_send(&eth_rx_thread_mb, (rt_uint32_t)dev); return rt_mb_send(&eth_rx_thread_mb, (rt_uint32_t)dev);
} }
rt_err_t eth_device_ready(struct eth_device* dev)
{
return eth_rx_ready(dev);
}
rt_err_t eth_system_device_init() rt_err_t eth_system_device_init()
{ {
rt_err_t result = RT_EOK; rt_err_t result = RT_EOK;