From 12b5decaa9cf7c4b7c45f20f72a1220dbc4c8348 Mon Sep 17 00:00:00 2001 From: "bernard.xiong@gmail.com" Date: Fri, 13 Apr 2012 15:11:02 +0000 Subject: [PATCH] keep more compatible with RT-Thread driver. git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2039 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- components/net/lwip/src/arch/sys_arch.c | 308 +++++------ .../net/lwip/src/include/netif/ethernetif.h | 14 +- components/net/lwip/src/lwipopts.h | 42 +- components/net/lwip/src/netif/ethernetif.c | 500 +++++++++++------- 4 files changed, 483 insertions(+), 381 deletions(-) diff --git a/components/net/lwip/src/arch/sys_arch.c b/components/net/lwip/src/arch/sys_arch.c index 18ab84e46f..21d4103a44 100644 --- a/components/net/lwip/src/arch/sys_arch.c +++ b/components/net/lwip/src/arch/sys_arch.c @@ -6,20 +6,156 @@ #include "lwip/err.h" #include "arch/sys_arch.h" #include "lwip/debug.h" +#include "lwip/netif.h" +#include "lwip/tcpip.h" +#include "netif/ethernetif.h" #include -#define LWIP_THREAD_MAGIC 0x1919 +/* introduce from kservice.c */ +#define rt_list_entry(node, type, member) \ + ((type *)((char *)(node) - (unsigned long)(&((type *)0)->member))) +static err_t netif_device_init(struct netif *netif) +{ + struct eth_device *ethif; -void sys_init(void) + 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; + } + + /* copy device flags to netif flags */ + netif->flags = ethif->flags; + + return ERR_OK; + } + + return ERR_IF; +} + +static void tcpip_init_done_callback(void *arg) { - /* nothing to do in RT-Thread */ + 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; - return; + extern struct rt_object_information rt_object_container[]; + + LWIP_ASSERT("invalid arg.\n",arg); + + IP4_ADDR(&gw, 0,0,0,0); + IP4_ADDR(&ipaddr, 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 + if (ethif->flags & NETIF_FLAG_DHCP) + { + /* if this interface uses DHCP, start the DHCP client */ + dhcp_start(ethif->netif); + } + else +#endif + { + /* set interface up */ + netif_set_up(ethif->netif); + } + +#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); } -/* ====================== Semaphore ====================== */ +/** + * 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(&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); + + netifapi_netif_set_addr(netif_default, &ipaddr, &netmask, &gw); + } +#endif +} + +void sys_init(void) +{ + /* nothing on RT-Thread porting */ +} + +void lwip_sys_init(void) +{ + lwip_system_init(); +} err_t sys_sem_new(sys_sem_t *sem, u8_t count) { @@ -30,16 +166,6 @@ err_t sys_sem_new(sys_sem_t *sem, u8_t count) RT_DEBUG_NOT_IN_INTERRUPT; rt_snprintf(tname, RT_NAME_MAX, "%s%d", SYS_LWIP_SEM_NAME, counter); - -#if SYS_DEBUG - { - struct rt_thread *thread; - - thread = rt_thread_self(); - LWIP_DEBUGF(SYS_DEBUG, ("%s, Create sem: %s \n",thread->name, tname)); - } -#endif - counter++; tmpsem = rt_sem_create(tname, count, RT_IPC_FLAG_FIFO); @@ -56,36 +182,13 @@ err_t sys_sem_new(sys_sem_t *sem, u8_t count) void sys_sem_free(sys_sem_t *sem) { RT_DEBUG_NOT_IN_INTERRUPT; - -#if SYS_DEBUG - { - struct rt_thread *thread; - thread = rt_thread_self(); - - LWIP_DEBUGF(SYS_DEBUG, ("%s, Delete sem: %s \n",thread->name, - (*sem)->parent.parent.name)); - } -#endif - rt_sem_delete(*sem); - } void sys_sem_signal(sys_sem_t *sem) { -#if SYS_DEBUG - { - struct rt_thread *thread; - thread = rt_thread_self(); - - LWIP_DEBUGF(SYS_DEBUG, ("%s, Release signal: %s , %d\n",thread->name, - (*sem)->parent.parent.name, (*sem)->value)); - } -#endif - rt_sem_release(*sem); - } u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) @@ -98,21 +201,10 @@ u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) /* get the begin tick */ tick = rt_tick_get(); -#if SYS_DEBUG - { - struct rt_thread *thread; - thread = rt_thread_self(); - - LWIP_DEBUGF(SYS_DEBUG, ("%s, Wait sem: %s , %d\n",thread->name, - (*sem)->parent.parent.name, (*sem)->value)); - } -#endif - - if(timeout == 0) - t = RT_WAITING_FOREVER; + if(timeout == 0) t = RT_WAITING_FOREVER; else { - /* convirt msecond to os tick */ + /* convert msecond to os tick */ if (timeout < (1000/RT_TICK_PER_SECOND)) t = 1; else @@ -141,7 +233,7 @@ u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) } #ifndef sys_sem_valid -/** Check if a sempahore is valid/allocated: return 1 for valid, 0 for invalid */ +/** Check if a semaphore is valid/allocated: return 1 for valid, 0 for invalid */ int sys_sem_valid(sys_sem_t *sem) { return (int)(*sem); @@ -170,16 +262,6 @@ err_t sys_mutex_new(sys_mutex_t *mutex) RT_DEBUG_NOT_IN_INTERRUPT; rt_snprintf(tname, RT_NAME_MAX, "%s%d", SYS_LWIP_MUTEX_NAME, counter); - -#if SYS_DEBUG - { - struct rt_thread *thread; - - thread = rt_thread_self(); - LWIP_DEBUGF(SYS_DEBUG, ("%s, Create mutex: %s \n",thread->name, tname)); - } -#endif - counter++; tmpmutex = rt_mutex_create(tname, RT_IPC_FLAG_FIFO); @@ -196,19 +278,7 @@ err_t sys_mutex_new(sys_mutex_t *mutex) * @param mutex the mutex to lock */ void sys_mutex_lock(sys_mutex_t *mutex) { - RT_DEBUG_NOT_IN_INTERRUPT; - -#if SYS_DEBUG - { - struct rt_thread *thread; - thread = rt_thread_self(); - - LWIP_DEBUGF(SYS_DEBUG, ("%s, Wait mutex: %s , %d\n",thread->name, - (*mutex)->parent.parent.name, (*mutex)->value)); - } -#endif - rt_mutex_take(*mutex, RT_WAITING_FOREVER); return; @@ -219,16 +289,6 @@ void sys_mutex_lock(sys_mutex_t *mutex) * @param mutex the mutex to unlock */ void sys_mutex_unlock(sys_mutex_t *mutex) { -#if SYS_DEBUG - { - struct rt_thread *thread; - thread = rt_thread_self(); - - LWIP_DEBUGF(SYS_DEBUG, ("%s, Release signal: %s , %d\n",thread->name, - (*mutex)->parent.parent.name, (*mutex)->value)); - } -#endif - rt_mutex_release(*mutex); } @@ -238,16 +298,6 @@ void sys_mutex_free(sys_mutex_t *mutex) { RT_DEBUG_NOT_IN_INTERRUPT; -#if SYS_DEBUG - { - struct rt_thread *thread; - thread = rt_thread_self(); - - LWIP_DEBUGF(SYS_DEBUG, ("%s, Delete sem: %s \n",thread->name, - (*mutex)->parent.parent.name)); - } -#endif - rt_mutex_delete(*mutex); } @@ -278,15 +328,6 @@ err_t sys_mbox_new(sys_mbox_t *mbox, int size) RT_DEBUG_NOT_IN_INTERRUPT; rt_snprintf(tname, RT_NAME_MAX, "%s%d", SYS_LWIP_MBOX_NAME, counter); - -#if SYS_DEBUG - { - struct rt_thread *thread; - thread = rt_thread_self(); - LWIP_DEBUGF(SYS_DEBUG, ("%s, Create mbox: %s \n",thread->name, tname)); - } -#endif - counter++; tmpmbox = rt_mb_create(tname, size, RT_IPC_FLAG_FIFO); @@ -295,25 +336,14 @@ err_t sys_mbox_new(sys_mbox_t *mbox, int size) *mbox = tmpmbox; return ERR_OK; } - else - return ERR_MEM; + return ERR_MEM; } void sys_mbox_free(sys_mbox_t *mbox) { RT_DEBUG_NOT_IN_INTERRUPT; -#if SYS_DEBUG - { - struct rt_thread *thread; - thread = rt_thread_self(); - - LWIP_DEBUGF(SYS_DEBUG, ("%s, Delete mbox: %s\n",thread->name, - (*mbox)->parent.parent.name)); - } -#endif - rt_mb_delete(*mbox); return; @@ -327,16 +357,6 @@ void sys_mbox_post(sys_mbox_t *mbox, void *msg) { RT_DEBUG_NOT_IN_INTERRUPT; -#if SYS_DEBUG - { - struct rt_thread *thread; - thread = rt_thread_self(); - - LWIP_DEBUGF(SYS_DEBUG, ("%s, Post mail: %s ,0x%x\n",thread->name, - (*mbox)->parent.parent.name, (rt_uint32_t)msg)); - } -#endif - rt_mb_send_wait(*mbox, (rt_uint32_t)msg,RT_WAITING_FOREVER); return; @@ -344,16 +364,6 @@ void sys_mbox_post(sys_mbox_t *mbox, void *msg) err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) { -#if SYS_DEBUG - { - struct rt_thread *thread; - thread = rt_thread_self(); - - LWIP_DEBUGF(SYS_DEBUG, ("%s, Post mail: %s ,0x%x\n",thread->name, - (*mbox)->parent.parent.name, (rt_uint32_t)msg)); - } -#endif - if (rt_mb_send(*mbox, (rt_uint32_t)msg) == RT_EOK) return ERR_OK; @@ -398,16 +408,6 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) LWIP_ASSERT("rt_mb_recv returned with error!", ret == RT_EOK); } -#if SYS_DEBUG - { - struct rt_thread *thread; - thread = rt_thread_self(); - - LWIP_DEBUGF(SYS_DEBUG, ("%s, Fetch mail: %s , 0x%x\n",thread->name, - (*mbox)->parent.parent.name, *(rt_uint32_t **)msg)); - } -#endif - /* get elapse msecond */ tick = rt_tick_get() - tick; @@ -439,16 +439,6 @@ u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) ret = 1; } -#if SYS_DEBUG - { - struct rt_thread *thread; - thread = rt_thread_self(); - - LWIP_DEBUGF(SYS_DEBUG, ("%s, Fetch mail: %s , 0x%x\n",thread->name, - (*mbox)->parent.parent.name, *(rt_uint32_t **)msg)); - } -#endif - return ret; } @@ -494,18 +484,11 @@ sys_prot_t sys_arch_protect(void) /* disable interrupt */ level = rt_hw_interrupt_disable(); - - /* must also lock scheduler */ - rt_enter_critical(); - return level; } void sys_arch_unprotect(sys_prot_t pval) { - /* unlock scheduler */ - rt_exit_critical(); - /* enable interrupt */ rt_hw_interrupt_enable(pval); @@ -518,4 +501,3 @@ void sys_arch_assert(const char* file, int line) rt_thread_self()->name); RT_ASSERT(0); } - diff --git a/components/net/lwip/src/include/netif/ethernetif.h b/components/net/lwip/src/include/netif/ethernetif.h index 60a5de681a..4aa4525ce2 100644 --- a/components/net/lwip/src/include/netif/ethernetif.h +++ b/components/net/lwip/src/include/netif/ethernetif.h @@ -7,21 +7,29 @@ #define NIOCTL_GADDR 0x01 #define ETHERNET_MTU 1500 - struct eth_device { /* inherit from rt_device */ struct rt_device parent; + /* network interface for lwip */ struct netif *netif; + struct rt_semaphore tx_ack; + + rt_uint8_t flags; + rt_uint8_t link_changed; + rt_uint16_t link_status; /* eth device interface */ struct pbuf* (*eth_rx)(rt_device_t dev); - rt_err_t (*eth_tx)(rt_device_t dev, struct pbuf* p); }; -rt_err_t eth_rx_ready(struct eth_device *dev); +rt_err_t eth_device_ready(struct eth_device* dev); +rt_err_t eth_device_init(struct eth_device * dev, char *name); +rt_err_t eth_device_init_with_flag(struct eth_device *dev, char *name, rt_uint8_t flag); +rt_err_t eth_device_linkchange(struct eth_device* dev, rt_bool_t up); +void eth_system_device_init(void); #endif /* __NETIF_ETHERNETIF_H__ */ diff --git a/components/net/lwip/src/lwipopts.h b/components/net/lwip/src/lwipopts.h index bea23d3a9e..01a14a8fbf 100644 --- a/components/net/lwip/src/lwipopts.h +++ b/components/net/lwip/src/lwipopts.h @@ -3,9 +3,7 @@ #include -#if defined(RT_USING_NEWLIB) || defined(RT_USING_MINILIBC) -#define ERRNO 1 -#endif +#define ERRNO 1 #define NO_SYS 0 #define LWIP_SOCKET 1 @@ -32,16 +30,16 @@ #ifdef RT_LWIP_DNS #define LWIP_DNS 1 #else -#define LWIP_DNS 0 +#define LWIP_DNS 0 #endif -#define LWIP_HAVE_LOOPIF 1 +#define LWIP_HAVE_LOOPIF 0 #define LWIP_PLATFORM_BYTESWAP 0 #define BYTE_ORDER LITTLE_ENDIAN /* Enable SO_RCVTIMEO processing. */ -#define LWIP_SO_RCVTIMEO 1 +#define LWIP_SO_RCVTIMEO 1 /* #define RT_LWIP_DEBUG */ @@ -52,7 +50,7 @@ /* ---------- Debug options ---------- */ #ifdef LWIP_DEBUG #define SYS_DEBUG LWIP_DBG_OFF -#define ETHARP_DEBUG LWIP_DBG_OFF +#define ETHARP_DEBUG LWIP_DBG_OFF #define PPP_DEBUG LWIP_DBG_OFF #define MEM_DEBUG LWIP_DBG_OFF #define MEMP_DEBUG LWIP_DBG_OFF @@ -92,15 +90,15 @@ #define mem_calloc rt_calloc #ifdef RT_LWIP_USING_RT_MEM -#define MEMP_MEM_MALLOC 1 +#define MEMP_MEM_MALLOC 1 #else -#define MEMP_MEM_MALLOC 0 +#define MEMP_MEM_MALLOC 0 #endif /* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application sends a lot of data out of ROM (or other static memory), this should be set high. */ -#define MEMP_NUM_PBUF 32 +#define MEMP_NUM_PBUF 16 /* the number of UDP protocol control blocks. One per active RAW "connection". */ #ifdef RT_LWIP_RAW_PCB_NUM @@ -124,14 +122,14 @@ /* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. */ -#define MEMP_NUM_SYS_TIMEOUT 8 +#define MEMP_NUM_SYS_TIMEOUT 3 /* The following four are used only with the sequential API and can be set to 0 if the application only will use the raw API. */ /* MEMP_NUM_NETBUF: the number of struct netbufs. */ #define MEMP_NUM_NETBUF 2 /* MEMP_NUM_NETCONN: the number of struct netconns. */ -#define MEMP_NUM_NETCONN 10 +#define MEMP_NUM_NETCONN 4 /* MEMP_NUM_TCPIP_MSG_*: the number of struct tcpip_msg, which is used for sequential API communication and incoming packets. Used in src/api/tcpip.c. */ @@ -152,7 +150,7 @@ #define PBUF_LINK_HLEN 16 #ifdef RT_LWIP_ETH_PAD_SIZE -#define ETH_PAD_SIZE RT_LWIP_ETH_PAD_SIZE +#define ETH_PAD_SIZE RT_LWIP_ETH_PAD_SIZE #endif /** SYS_LIGHTWEIGHT_PROT @@ -176,13 +174,13 @@ #define TCP_QUEUE_OOSEQ 1 /* TCP Maximum segment size. */ -#define TCP_MSS 1024 +#define TCP_MSS 1460 /* TCP sender buffer space (bytes). */ #ifdef RT_LWIP_TCP_SND_BUF #define TCP_SND_BUF RT_LWIP_TCP_SND_BUF #else -#define TCP_SND_BUF 2048 +#define TCP_SND_BUF (TCP_MSS * 2) #endif /* TCP sender buffer space (pbufs). This must be at least = 2 * @@ -196,9 +194,9 @@ /* TCP receive window. */ #ifdef RT_LWIP_TCP_WND -#define TCP_WND RT_LWIP_TCP_WND +#define TCP_WND RT_LWIP_TCP_WND #else -#define TCP_WND 1500 +#define TCP_WND (TCP_MSS * 2) #endif /* Maximum number of retransmissions of data segments. */ @@ -233,10 +231,10 @@ /* IP reassembly and segmentation.These are orthogonal even * if they both deal with IP fragments */ -#define IP_REASSEMBLY 1 +#define IP_REASSEMBLY 0 #define IP_REASS_MAX_PBUFS 10 #define MEMP_NUM_REASSDATA 10 -#define IP_FRAG 1 +#define IP_FRAG 0 /* ---------- ICMP options ---------- */ #define ICMP_TTL 255 @@ -265,7 +263,7 @@ #define LWIP_UDP 0 #endif -#define LWIP_UDPLITE 1 +#define LWIP_UDPLITE 0 #define UDP_TTL 255 #define DEFAULT_UDP_RECVMBOX_SIZE 1 @@ -323,7 +321,7 @@ #endif /* PPP_SUPPORT */ /* 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__ */ diff --git a/components/net/lwip/src/netif/ethernetif.c b/components/net/lwip/src/netif/ethernetif.c index 0dcf637e34..a4fb54a081 100644 --- a/components/net/lwip/src/netif/ethernetif.c +++ b/components/net/lwip/src/netif/ethernetif.c @@ -10,6 +10,8 @@ * Change Logs: * Date Author Notes * 2010-07-07 Bernard fix send mail to mailbox issue. + * 2011-07-30 mbbill port lwIP 1.4.0 to RT-Thread + * 2012-04-10 Bernard add more compatible with RT-Thread. */ /* @@ -59,60 +61,172 @@ #include "netif/etharp.h" #include "netif/ethernetif.h" -/* configurations */ -#ifndef RT_LWIP_ETHTHREAD_PRIORITY -#define RT_LWIP_ETHTHREAD_PRIORITY 0x90 -#endif +#define netifapi_netif_set_link_up(n) netifapi_netif_common(n, netif_set_link_up, NULL) +#define netifapi_netif_set_link_down(n) netifapi_netif_common(n, netif_set_link_down, NULL) -#ifndef RT_LWIP_ETHTHREAD_MBOX_SIZE -#define RT_LWIP_ETHTHREAD_MBOX_SIZE 48 -#endif +/** + * Tx message structure for Ethernet interface + */ +struct eth_tx_msg +{ + struct netif *netif; + struct pbuf *buf; +}; -#ifndef RT_LWIP_ETHTHREAD_STACKSIZE -#define RT_LWIP_ETHTHREAD_STACKSIZE 1024 +static struct rt_mailbox eth_tx_thread_mb; +static struct rt_thread eth_tx_thread; +#ifndef RT_LWIP_ETHTHREAD_PRIORITY +static char eth_tx_thread_mb_pool[32 * 4]; +static char eth_tx_thread_stack[512]; +#else +static char eth_tx_thread_mb_pool[RT_LWIP_ETHTHREAD_MBOX_SIZE * 4]; +static char eth_tx_thread_stack[RT_LWIP_ETHTHREAD_STACKSIZE]; #endif - -/* eth rx thread */ static struct rt_mailbox eth_rx_thread_mb; static struct rt_thread eth_rx_thread; - +#ifndef RT_LWIP_ETHTHREAD_PRIORITY +#define RT_ETHERNETIF_THREAD_PREORITY 0x90 +static char eth_rx_thread_mb_pool[48 * 4]; +static char eth_rx_thread_stack[1024]; +#else +#define RT_ETHERNETIF_THREAD_PREORITY RT_LWIP_ETHTHREAD_PRIORITY static char eth_rx_thread_mb_pool[RT_LWIP_ETHTHREAD_MBOX_SIZE * 4]; static char eth_rx_thread_stack[RT_LWIP_ETHTHREAD_STACKSIZE]; +#endif - -/* Ugly hacks for old drivers compatible */ -/* ===================================== */ -#if 1 -static struct eth_device * ptmpdev; -struct eth_device * get_eth_dev(void) +static err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p) { - return ptmpdev; + struct eth_tx_msg msg; + struct eth_device* enetif; + + enetif = (struct eth_device*)netif->state; + + /* send a message to eth tx thread */ + msg.netif = netif; + msg.buf = p; + if (rt_mb_send(ð_tx_thread_mb, (rt_uint32_t) &msg) == RT_EOK) + { + /* waiting for ack */ + rt_sem_take(&(enetif->tx_ack), RT_WAITING_FOREVER); + } + + return ERR_OK; } -int eth_device_init(struct eth_device * dev, char *name) + +/* Keep old drivers compatible in RT-Thread */ +rt_err_t eth_device_init_with_flag(struct eth_device *dev, char *name, rt_uint8_t flags) { - ptmpdev = dev; + struct netif* netif; + + netif = (struct netif*) rt_malloc (sizeof(struct netif)); + if (netif == RT_NULL) + { + rt_kprintf("malloc netif failed\n"); + return -RT_ERROR; + } + rt_memset(netif, 0, sizeof(struct netif)); + + /* set netif */ + dev->netif = netif; + /* device flags, which will be set to netif flags when initializing */ + dev->flags = flags; + /* link changed status of device */ + dev->link_changed = 0x00; dev->parent.type = RT_Device_Class_NetIf; - rt_device_register(&(dev->parent), "eth0", RT_DEVICE_FLAG_RDWR); - return 0; + /* register to RT-Thread device manager */ + rt_device_register(&(dev->parent), name, RT_DEVICE_FLAG_RDWR); + rt_sem_init(&(dev->tx_ack), name, 0, RT_IPC_FLAG_FIFO); + + /* set name */ + netif->name[0] = name[0]; + netif->name[1] = name[1]; + + /* set hw address to 6 */ + netif->hwaddr_len = 6; + /* maximum transfer unit */ + netif->mtu = ETHERNET_MTU; + + /* get hardware MAC address */ + rt_device_control(&(dev->parent), NIOCTL_GADDR, netif->hwaddr); + + /* set output */ + netif->output = etharp_output; + netif->linkoutput = ethernetif_linkoutput; + + return RT_EOK; } -void lwip_sys_init(void) + +rt_err_t eth_device_init(struct eth_device * dev, char *name) { - lwip_enetif_init(); + rt_uint8_t flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; + +#if LWIP_IGMP + /* IGMP support */ + flags |= NETIF_FLAG_IGMP; +#endif + + return eth_device_init_with_flag(dev, name, flags); } -void eth_system_device_init() + +rt_err_t eth_device_ready(struct eth_device* dev) { + if (dev->netif) + /* post message to Ethernet thread */ + return rt_mb_send(ð_rx_thread_mb, (rt_uint32_t)dev); + else + return ERR_OK; /* netif is not initialized yet, just return. */ } -rt_err_t eth_device_ready(struct eth_device* dev) + +rt_err_t eth_device_linkchange(struct eth_device* dev, rt_bool_t up) { - return eth_rx_ready(dev); + rt_uint32_t level; + + RT_ASSERT(dev != RT_NULL); + + level = rt_hw_interrupt_disable(); + dev->link_changed = 0x01; + if (up == RT_TRUE) + dev->link_status = 0x01; + else + dev->link_status = 0x00; + rt_hw_interrupt_enable(level); + + /* post message to ethernet thread */ + return rt_mb_send(ð_rx_thread_mb, (rt_uint32_t)dev); } -#endif -/* ===================================== */ +/* Ethernet Tx Thread */ +static void eth_tx_thread_entry(void* parameter) +{ + struct eth_tx_msg* msg; + + while (1) + { + if (rt_mb_recv(ð_tx_thread_mb, (rt_uint32_t*)&msg, RT_WAITING_FOREVER) == RT_EOK) + { + struct eth_device* enetif; + + RT_ASSERT(msg->netif != RT_NULL); + RT_ASSERT(msg->buf != RT_NULL); + enetif = (struct eth_device*)msg->netif->state; + if (enetif != RT_NULL) + { + /* call driver's interface */ + if (enetif->eth_tx(&(enetif->parent), msg->buf) != RT_EOK) + { + rt_kprintf("transmit eth packet failed\n"); + } + } + + /* send ACK */ + rt_sem_release(&(enetif->tx_ack)); + } + } +} -/* ethernet buffer */ +/* Ethernet Rx Thread */ static void eth_rx_thread_entry(void* parameter) { struct eth_device* device; @@ -123,6 +237,23 @@ static void eth_rx_thread_entry(void* parameter) { struct pbuf *p; + /* check link status */ + if (device->link_changed) + { + int status; + rt_uint32_t level; + + level = rt_hw_interrupt_disable(); + status = device->link_status; + device->link_changed = 0x00; + rt_hw_interrupt_enable(level); + + if (status) + netifapi_netif_set_link_up(device->netif); + else + netifapi_netif_set_link_down(device->netif); + } + /* receive all of buffer */ while (1) { @@ -147,25 +278,12 @@ static void eth_rx_thread_entry(void* parameter) } } - - -static err_t enetif_linkoutput(struct netif *pnetif, struct pbuf *p) -{ - struct eth_device *dev; - - dev = (struct eth_device *)(pnetif->state); - return dev->eth_tx(&(dev->parent), p); -} - - -static err_t enetif_init(struct netif *pnetif) +void eth_system_device_init() { rt_err_t result = RT_EOK; - struct eth_device *dev; - rt_uint32_t level; - /* init rx thread. - * init mailbox and create ethernet thread */ + /* initialize Rx thread. + * initialize mailbox and create Ethernet Rx thread */ result = rt_mb_init(ð_rx_thread_mb, "erxmb", ð_rx_thread_mb_pool[0], sizeof(eth_rx_thread_mb_pool)/4, RT_IPC_FLAG_FIFO); @@ -175,147 +293,71 @@ static err_t enetif_init(struct netif *pnetif) ð_rx_thread_stack[0], sizeof(eth_rx_thread_stack), RT_LWIP_ETHTHREAD_PRIORITY, 16); RT_ASSERT(result == RT_EOK); - result = rt_thread_startup(ð_rx_thread); RT_ASSERT(result == RT_EOK); + /* initialize Tx thread */ + /* initialize mailbox and create Ethernet Tx thread */ + result = rt_mb_init(ð_tx_thread_mb, "etxmb", + ð_tx_thread_mb_pool[0], sizeof(eth_tx_thread_mb_pool)/4, + RT_IPC_FLAG_FIFO); + RT_ASSERT(result == RT_EOK); - dev = (struct eth_device *)(pnetif->state); - - pnetif->name[0] = dev->parent.parent.name[0]; - pnetif->name[1] = dev->parent.parent.name[1]; - - pnetif->hwaddr_len = 6; - pnetif->mtu = ETHERNET_MTU; - pnetif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; - -#ifdef LWIP_IGMP - pnetif->flags |= NETIF_FLAG_IGMP; -#endif - -#ifdef LWIP_DHCP - pnetif->flags |= NETIF_FLAG_DHCP; -#endif - - /* get hardware address */ - rt_device_control(&(dev->parent), NIOCTL_GADDR, pnetif->hwaddr); - - /* set output */ - pnetif->output = etharp_output; - pnetif->linkoutput = enetif_linkoutput; - - /* finally, we connect netif and device together. - * We initialized eth_device first, but ethernetif is still not ready. - * Although we checked if dev->netif is null but we still must avoid - * concurrency problem here.*/ - level = rt_hw_interrupt_disable(); - dev->netif = pnetif; - rt_hw_interrupt_enable(level); - - return ERR_OK; -} - -rt_err_t eth_rx_ready(struct eth_device* dev) -{ - if (dev->netif) - /* post message to ethernet thread */ - return rt_mb_send(ð_rx_thread_mb, (rt_uint32_t)dev); - else - return ERR_OK; /* netif is not initialized yet, just return. */ -} - -/* Functions below shouldn't be here because they are application or usage related. - * I just give an example of a right power-on procedure here. */ -static struct netif ethernetif; -extern struct eth_device * get_eth_dev(void); - -/* This function is called-back in tcpip thread, so we don't need to use msg api - * to call those netif_xxx functions. But if we use these anywhere else, we must - * use msg api to avoid concurrent problem. - */ -static void tcpip_init_done_callback(void *arg) -{ - ip_addr_t ipaddr, netmask, gw; - - LWIP_ASSERT("invalid arg.\n",arg); - -#if LWIP_DHCP - IP4_ADDR(&gw, 0,0,0,0); - IP4_ADDR(&ipaddr, 0,0,0,0); - IP4_ADDR(&netmask, 0,0,0,0); -#else - 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(&netmask, RT_LWIP_MSKADDR0, RT_LWIP_MSKADDR1, RT_LWIP_MSKADDR2, RT_LWIP_MSKADDR3); -#endif - - netif_add(ðernetif, &ipaddr, &netmask, &gw, - get_eth_dev(), enetif_init, tcpip_input); - - netif_set_default(ðernetif); - -#if LWIP_DHCP - dhcp_start(ðernetif); -#else - netif_set_up(ðernetif); -#endif - - netif_set_link_up(ðernetif); - - sys_sem_signal((sys_sem_t*)(&arg)); -} - - -/* Make sure the 'dev' has already been initialized before calling this function. - * This function will initialize the lwip tcpip stack as well as the ethernetif. - * It will assign the dev->netif and netif->state field to make a connection between - * eth driver and ethnetif. - */ -void lwip_enetif_init(void) -{ - sys_sem_t init_done_sem; - - if(sys_sem_new(&init_done_sem, 0) != ERR_OK) - { - LWIP_ASSERT("Failed to create semaphore", 0); - return; - } - tcpip_init(tcpip_init_done_callback,(void *)init_done_sem); - - sys_sem_wait(&init_done_sem); - rt_kprintf("TCP/IP initialized.\n"); + result = rt_thread_init(ð_tx_thread, "etx", eth_tx_thread_entry, RT_NULL, + ð_tx_thread_stack[0], sizeof(eth_tx_thread_stack), + RT_ETHERNETIF_THREAD_PREORITY, 16); + RT_ASSERT(result == RT_EOK); - sys_sem_free(&init_done_sem); + result = rt_thread_startup(ð_tx_thread); + RT_ASSERT(result == RT_EOK); } -#if 0 #ifdef RT_USING_FINSH #include -#include "ipv4/lwip/inet.h" -void set_if(char* ip_addr, char* gw_addr, char* nm_addr) +void set_if(char* netif_name, char* ip_addr, char* gw_addr, char* nm_addr) { - struct ip_addr *ip; - struct in_addr addr; - - ip = (struct ip_addr *)&addr; - - /* set ip address */ - if ((ip_addr != RT_NULL) && inet_aton(ip_addr, &addr)) - { - netif_set_ipaddr(netif_default, ip); - } - - /* set gateway address */ - if ((gw_addr != RT_NULL) && inet_aton(gw_addr, &addr)) - { - netif_set_gw(netif_default, ip); - } - - /* set netmask address */ - if ((nm_addr != RT_NULL) && inet_aton(nm_addr, &addr)) - { - netif_set_netmask(netif_default, ip); - } + struct ip_addr *ip; + struct ip_addr addr; + struct netif * netif = netif_list; + + if(strlen(netif_name) > sizeof(netif->name)) + { + rt_kprintf("network interface name too long!\r\n"); + return; + } + + while(netif != RT_NULL) + { + if(strncmp(netif_name, netif->name, sizeof(netif->name)) == 0) + break; + + netif = netif->next; + if( netif == RT_NULL ) + { + rt_kprintf("network interface: %s not found!\r\n", netif_name); + return; + } + } + + ip = (struct ip_addr *)&addr; + + /* set ip address */ + if ((ip_addr != RT_NULL) && ipaddr_aton(ip_addr, &addr)) + { + netif_set_ipaddr(netif, ip); + } + + /* set gateway address */ + if ((gw_addr != RT_NULL) && ipaddr_aton(gw_addr, &addr)) + { + netif_set_gw(netif, ip); + } + + /* set netmask address */ + if ((nm_addr != RT_NULL) && ipaddr_aton(nm_addr, &addr)) + { + netif_set_netmask(netif, ip); + } } FINSH_FUNCTION_EXPORT(set_if, set network interface address); @@ -323,32 +365,104 @@ FINSH_FUNCTION_EXPORT(set_if, set network interface address); #include void set_dns(char* dns_server) { - struct in_addr addr; + struct ip_addr addr; - if ((dns_server != RT_NULL) && inet_aton(dns_server, &addr)) + if ((dns_server != RT_NULL) && ipaddr_aton(dns_server, &addr)) { - dns_setserver(0, (struct ip_addr *)&addr); + dns_setserver(0, &addr); } } FINSH_FUNCTION_EXPORT(set_dns, set DNS server address); #endif -void list_if() +void list_if(void) { - rt_kprintf("Default network interface: %c%c\n", netif_default->name[0], netif_default->name[1]); - rt_kprintf("ip address: %s\n", inet_ntoa(*((struct in_addr*)&(netif_default->ip_addr)))); - rt_kprintf("gw address: %s\n", inet_ntoa(*((struct in_addr*)&(netif_default->gw)))); - rt_kprintf("net mask : %s\n", inet_ntoa(*((struct in_addr*)&(netif_default->netmask)))); + rt_ubase_t index; + struct netif * netif; + + netif = netif_list; + + while( netif != RT_NULL ) + { + rt_kprintf("network interface: %c%c%s\n", netif->name[0], netif->name[1], (netif == netif_default)?" (Default)":""); + rt_kprintf("MTU: %d\n", netif->mtu); + rt_kprintf("MAC: "); + for (index = 0; index < netif->hwaddr_len; index ++) + rt_kprintf("%02x ", netif->hwaddr[index]); + rt_kprintf("\nFLAGS:"); + if (netif->flags & NETIF_FLAG_UP) rt_kprintf(" UP"); + else rt_kprintf(" DOWN"); + if (netif->flags & NETIF_FLAG_LINK_UP) rt_kprintf(" LINK_UP"); + else rt_kprintf(" LINK_DOWN"); + if (netif->flags & NETIF_FLAG_DHCP) rt_kprintf(" DHCP"); + if (netif->flags & NETIF_FLAG_POINTTOPOINT) rt_kprintf(" PPP"); + if (netif->flags & NETIF_FLAG_ETHARP) rt_kprintf(" ETHARP"); + if (netif->flags & NETIF_FLAG_IGMP) rt_kprintf(" IGMP"); + rt_kprintf("\n"); + rt_kprintf("ip address: %s\n", ipaddr_ntoa(&(netif->ip_addr))); + rt_kprintf("gw address: %s\n", ipaddr_ntoa(&(netif->gw))); + rt_kprintf("net mask : %s\n", ipaddr_ntoa(&(netif->netmask))); + rt_kprintf("\r\n"); + + netif = netif->next; + } #if LWIP_DNS - { - struct ip_addr ip_addr; - - ip_addr = dns_getserver(0); - rt_kprintf("dns server: %s\n", inet_ntoa(*((struct in_addr*)&(ip_addr)))); - } -#endif + { + struct ip_addr ip_addr; + + for(index=0; index +#include + +void list_tcps() +{ + struct tcp_pcb *pcb; + extern struct tcp_pcb *tcp_active_pcbs; + extern union tcp_listen_pcbs_t tcp_listen_pcbs; + extern struct tcp_pcb *tcp_tw_pcbs; + extern const char *tcp_state_str[]; + + rt_enter_critical(); + rt_kprintf("Active PCB states:\n"); + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) + { + rt_kprintf("%s:%d <==> %s:%d snd_nxt %d rcv_nxt %d ", + ipaddr_ntoa(&(pcb->local_ip)), pcb->local_port, + ipaddr_ntoa(&(pcb->remote_ip)), pcb->remote_port, + pcb->snd_nxt, pcb->rcv_nxt); + rt_kprintf("state: %s\n", tcp_state_str[pcb->state]); + } + + rt_kprintf("Listen PCB states:\n"); + for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) + { + rt_kprintf("local port %d ", pcb->local_port); + rt_kprintf("state: %s\n", tcp_state_str[pcb->state]); + } + + rt_kprintf("TIME-WAIT PCB states:\n"); + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) + { + rt_kprintf("%s:%d <==> %s:%d snd_nxt %d rcv_nxt %d ", + ipaddr_ntoa(&(pcb->local_ip)), pcb->local_port, + ipaddr_ntoa(&(pcb->remote_ip)), pcb->remote_port, + pcb->snd_nxt, pcb->rcv_nxt); + rt_kprintf("state: %s\n", tcp_state_str[pcb->state]); + } + rt_exit_critical(); +} +FINSH_FUNCTION_EXPORT(list_tcps, list all of tcp connections); #endif + #endif -- GitLab