/*本人在以前开发过程中移植uIP到RT-Thread实时线程系统,在附带例子中实现了1个客户端连接和服务端连接,但还有待更多完善
有需要应用uip到项目中的朋友可以参考一下。
附件是源码包,在以太网驱动采用DM9000,驱动程序和移植文件uipif.c在源码包下(rt-thread下). */
rt-thread 嵌入式系统适合为040,或者034版本。
主要移植文件代码:
======================================= /* * File : uipif.c * * uIP tcp/ip stack demo, runing on the RT-Thread system * with 1 client connection and 1 server connection * * Change Logs: * Date Author Notes * 2011-04-20 itspy.wei */ #include <rtthread.h> #include <rtdef.h> #include "uip_rtt.h" #include "uip-conf.h" #include "uip.h" #include "uip_arp.h" #include "uipif.h" #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) struct rt_timer uip_timer; /* eth rx/tx thread */ static struct rt_mailbox eth_rx_thread_mb; static struct rt_thread eth_rx_thread; #ifndef RT_UIP_ETHTHREAD_PRIORITY #define RT_ETHERNETIF_THREAD_PREORITY 0x90 static char eth_rx_thread_mb_pool[10 * 4]; static char eth_rx_thread_stack[512]; #else #define RT_ETHERNETIF_THREAD_PREORITY RT_UIP_ETHTHREAD_PRIORITY static char eth_rx_thread_mb_pool[RT_UIP_ETHTHREAD_MBOX_SIZE * 4]; static char eth_rx_thread_stack[RT_UIP_ETHTHREAD_STACKSIZE]; #endif 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_UIP_ETHTHREAD_MBOX_SIZE * 4]; static char eth_tx_thread_stack[RT_UIP_ETHTHREAD_STACKSIZE]; #endif rt_err_t eth_device_init(struct eth_device* dev, const char* name) { uip_ipaddr_t ipaddr; rt_device_register(&(dev->fops), name, RT_DEVICE_FLAG_RDWR); dev->fops.type = RT_Device_Class_NetIf; rt_sem_init(&dev->tx_msg.tx_ack,"tx_msg",1,RT_IPC_FLAG_FIFO); uip_ipaddr(ipaddr, RT_UIP_IPADDR0,RT_UIP_IPADDR1,RT_UIP_IPADDR2,RT_UIP_IPADDR3); uip_sethostaddr(ipaddr); uip_ipaddr(ipaddr, RT_UIP_GWADDR0,RT_UIP_GWADDR1,RT_UIP_GWADDR2,RT_UIP_GWADDR3); uip_setdraddr(ipaddr); uip_ipaddr(ipaddr, RT_UIP_MSKADDR0,RT_UIP_MSKADDR1,RT_UIP_MSKADDR2,RT_UIP_MSKADDR3); uip_setnetmask(ipaddr); return RT_EOK; } rt_err_t eth_device_ready(struct eth_device* dev) { /* post message to rx thread */ return rt_mb_send(ð_rx_thread_mb, (rt_uint32_t)dev); } void eth_send_tx_msg(struct eth_device *dev) { /* post message to tx thread */ if ((rt_sem_take(&(dev->tx_msg.tx_ack), 0)) == RT_EOK) { rt_mb_send(ð_tx_thread_mb, (rt_uint32_t)dev); } } void eth_send_arp(struct eth_device *dev) { dev->tx_msg.buf = uip_buf; dev->tx_msg.len = uip_len; eth_send_tx_msg(dev); return; } void uip_timeout_process(void * parameter) { static rt_uint8_t arp_flag; rt_uint8_t i = 0; for (i = 0; i < UIP_CONNS; i++) { uip_periodic(i); if (uip_len > 0) { uip_arp_out(); eth_send_arp((struct eth_device*)parameter); } } #if UIP_UDP for (i = 0; i < UIP_UDP_CONNS; i++) { uip_udp_periodic(i); if (uip_len > 0) { uip_arp_out(); eth_send_arp((struct eth_device*)parameter); } } #endif if (++arp_flag >= 2) /* ARP timer call per 10 seconds*/ { uip_arp_timer(); arp_flag = 0; } return; } void uip_sys_init(void) { struct rt_device *eth_dev; uip_ipaddr_t ipaddr; uip_init(); #if HELLO_WORLD hello_world_init(); #elif TELNETD telnetd_init(); #elif WEBSERVER httpd_init(); #elif WEBCLIENT webclient_init(); resolv_init(); uip_ipaddr(ipaddr, 202,96,128,166); /* set DNS server */ resolv_conf(ipaddr); resolv_query("www.rt-thread.org"); #else uip_listen(HTONS(1234)); uip_ipaddr(ipaddr, 192,168,2,244); uip_connect(&ipaddr, HTONS(5678)); #endif eth_dev = rt_device_find("e0"); RT_ASSERT(eth_dev != RT_NULL); rt_timer_init(&uip_timer, "utimer", uip_timeout_process, eth_dev, RT_TICK_PER_SECOND*5, RT_TIMER_FLAG_PERIODIC); rt_timer_start(&uip_timer); return; } rt_err_t eth_input(struct pbuf *p, struct eth_device *dev) { rt_uint16_t type; rt_memcpy(uip_buf,p->payload,p->len); uip_len = p->len; type = (BUF->type << 8 | BUF->type >> 8); switch(type) { case UIP_ETHTYPE_IP: uip_arp_ipin(); uip_input(); if (!uip_len) break; uip_arp_out(); eth_send_arp(dev); break; case UIP_ETHTYPE_ARP:/* out packet: min-length: uip->len = 60 */ uip_arp_arpin(); if (!uip_len) break; eth_send_arp(dev); break; default: break; } rt_free(p); rt_free(p->payload); return 0; } void eth_tx_thread_entry(void* parameter) { struct eth_device *dev; while (1) { if (rt_mb_recv(ð_tx_thread_mb, (rt_uint32_t*)&dev, RT_WAITING_FOREVER) == RT_EOK) { dev->eth_tx(dev->tx_msg.buf, dev->tx_msg.len); /* eth tx process */ rt_sem_release(&(dev->tx_msg.tx_ack)); } } } void eth_rx_thread_entry(void* parameter) { struct eth_device* dev; struct pbuf *p; while (1) { if (rt_mb_recv(ð_rx_thread_mb, (rt_uint32_t*)&dev, RT_WAITING_FOREVER) == RT_EOK) { while(1) { p = dev->eth_rx();/* eth rx process */ if (p != RT_NULL) { eth_input(p, dev); } else break; } } } } rt_err_t eth_system_device_init(void) { rt_err_t res = RT_EOK; res = rt_mb_init(ð_rx_thread_mb, "erxmb", ð_rx_thread_mb_pool[0], sizeof(eth_rx_thread_mb_pool)/4, RT_IPC_FLAG_FIFO); RT_ASSERT(res == RT_EOK); res = rt_thread_init(ð_rx_thread, "erx", eth_rx_thread_entry, RT_NULL, ð_rx_thread_stack[0], sizeof(eth_rx_thread_stack), RT_ETHERNETIF_THREAD_PREORITY, 16); RT_ASSERT(res == RT_EOK); res = rt_thread_startup(ð_rx_thread); RT_ASSERT(res == RT_EOK); res = 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(res == RT_EOK); res = 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(res == RT_EOK); res = rt_thread_startup(ð_tx_thread); RT_ASSERT(res == RT_EOK); return res; } void myapp_call(void) { static rt_uint16_t index1,index2; rt_uint8_t i,*ptr; struct app_state *s; char str[10]; char *str1 = "TCP/IP stack: uIP\nRTOS: RT-thread 040 beta\nPlatform: RT-Radio\nClient: port,1234\n"; char *str2 = "TCP/IP stack: uIP\nRTOS: RT-thread 040 beta\nPlatform: RT-Radio\nServer: port,5678\n"; for (i=0; i<10; i++) str[i] = 0; s = &uip_conn->appstate; if (uip_conn->lport == HTONS(1234)) { if (uip_connected()) { rt_kprintf("%s",str1); uip_send(str1,rt_strlen(str1)); s->state = CONNECTED; } if (uip_newdata() && s->state == SEND_ACKED) { rt_snprintf(str,sizeof(str), "index:%d", ++index1); for (ptr=uip_appdata,i=0; i<10; i++) { if (str[i] == 0) break; ptr[uip_len]= str[i]; uip_len++; } uip_send((const void *)uip_appdata, uip_datalen()); } if (uip_acked() && s->state == CONNECTED) { s->state = SEND_ACKED; } if (uip_acked() && s->state == CONNECTION_CLOSED) { uip_close(); } } else if (uip_conn->rport == HTONS(5678)) { if (uip_connected()) { rt_kprintf("%s",str2); uip_send(str2,rt_strlen(str2)); s->state = CONNECTED; } if (uip_newdata() && s->state == SEND_ACKED) { rt_snprintf(str,sizeof(str), "index:%d", ++index2); for (ptr=uip_appdata,i=0; i<10; i++) { if (str[i] == 0) break; ptr[uip_len]= str[i]; uip_len++; } uip_send((const void *)uip_appdata, uip_datalen()); } if (uip_acked() && s->state == CONNECTED) { s->state = SEND_ACKED; } if (uip_acked() && s->state == CONNECTION_CLOSED) { uip_close(); } } return; } void uip_log(char *m) { rt_kprintf("uIP log message: %s\r\n", m); }/* END OF FILE */