当前位置:文档之家› uip移植笔记

uip移植笔记

本笔记适用于uIP1.0。

移植平台介绍:MSP430F149+cs8900a+IAR1、阅读The uIP Embedded TCP/IP Stack The uIP 1.0 Reference Manual.2、建立一个文件夹,起名myport,将uip-1.0下的uIP和lib两个文件夹拷贝过去,然后再在myport下建立app文件夹。

3、将unix子文件夹下的clock-arch.c、clock-arch.h拷贝到myport下,这个文件实现协议栈所用的时钟,由430的定时器完成,有三个函数:clock_time_t clock_time(void){return ticks;}void clock_init(void){定时器的初始化工作}__interrupt void timer_interrupt(void)/*定时器中断函数*/{++ticks;}。

4、将unix子文件夹下的uip-conf.h拷贝到myport下,这个文件实现协议栈所用的配置,按照需要修改之。

5、写cs8900a的驱动函数,这里采用8位、查询模式,替换tapdev.c 或slipdev.c。

6、将unix子文件夹下的main.c函数拷贝到myport下,这个是主调度流程,按照需要修改。

7、建立自己的工程,将以上文件包含。

8、调试,改错。

其中,uip的缓冲区是以字节数组的形式产生,为了保证它的起始地址是偶数,必须指定地址。

UDP的初始化如下void myudp_init(void){uip_ipaddr_t ipaddr;//定义IP类型变量uip_ipaddr(ipaddr, 210,29,104,88); //远程IP为210.29.104.88if(myudp_conn != NULL){uip_udp_remove(myudp_conn);//如果连接已经建立,则删除之}myudp_conn = uip_udp_new(&ipaddr, HTONS(1000));//建立到远程ipaddr,端口为1000的连接if(myudp_conn != NULL){uip_udp_bind(myudp_conn, HTONS(2000));//绑定本地端口为2000,也就是2000-->1000 发数据}}void myudp_send(char *str,short n){char *nptr;nptr = (char *)uip_appdata;memcpy(nptr, str, n);uip_udp_send(n); //发送n个数据}void newdata(){char *nptr;short len;len = uip_datalen();//读取数据长度nptr = (char *)uip_appdata; //取得数据起始指针if(len<4)myudp_send("Please check the command!\n",26);else if(strncmp(nptr,"getname",7)==0)myudp_send("My name is xiaomu.",19);else myudp_send("Unkown command!\n",16);}/*---------------------------------------------------------------------------*//** \internal* The main UDP function.*//*---------------------------------------------------------------------------*/voidmyudp_appcall(void){if(uip_udp_conn->rport == HTONS(1000)){if(uip_poll()) {myudp_send("hello\n",6);//定时时间到,发hello}if(uip_newdata()) //如果指定IP的指定端口发来数据{newdata();}}}TCP的和这个差不多,初始化时就监听端口uip_listen(HTONS(23));myudp_conn = uip_udp_new(&ipaddr, HTONS(0));//如果远程ipaddr为0,端口也为0,则可以接收来自任何ip任何端口的信息,但必须指定本地端口,即要绑定。

我修改了uip.c文件中关于UDP接收的部分,使它总是可以接收来自任何ip的信息,接收的数据的ip和端口信息保存在当前连接的结构体里面,可以用来回复信息。

如果想要主动发送信息,必须在每次发送前给当前连接的结构体赋值,因为我将UDP部分的代码修改为每次打好包以后将结构体的远端信息清零!详见我的移植代码。

UIP的主流程结构uip_init();// init MAC addressuip_ethaddr.addr[0] = EMAC_ADDR0;uip_ethaddr.addr[1] = EMAC_ADDR1;uip_ethaddr.addr[2] = EMAC_ADDR2;uip_ethaddr.addr[3] = EMAC_ADDR3;uip_ethaddr.addr[4] = EMAC_ADDR4;uip_ethaddr.addr[5] = EMAC_ADDR5;uip_setethaddr(uip_ethaddr);//设定以太网MAC地址uip_ipaddr(ipaddr, 192,168,0,100);sprintf(_db, "Set own IP address: %d.%d.%d.%d \n\r", \((uint8_t *)ipaddr)[0], ((uint8_t *)ipaddr)[1], \((uint8_t *)ipaddr)[2], ((uint8_t *)ipaddr)[3]);DB;uip_sethostaddr(ipaddr);//设置主机IP地址uip_ipaddr(ipaddr, 192,168,0,1);sprintf(_db, "Set Router IP address: %d.%d.%d.%d \n\r", \((uint8_t *)ipaddr)[0], ((uint8_t *)ipaddr)[1], \((uint8_t *)ipaddr)[2], ((uint8_t *)ipaddr)[3]);DB;uip_setdraddr(ipaddr);//设定的是默认路由器地址uip_ipaddr(ipaddr, 255,255,255,0);sprintf(_db, "Set Subnet mask: %d.%d.%d.%d \n\r", \((uint8_t *)ipaddr)[0], ((uint8_t *)ipaddr)[1], \((uint8_t *)ipaddr)[2], ((uint8_t *)ipaddr)[3]);DB;uip_setnetmask(ipaddr);//设定子网掩码//udpuip_ipaddr(ripaddr,192,168,0,101);uip_udp_conn = uip_udp_new(&ripaddr,HTONS(1000));//建立远端端口if( uip_udp_conn != NULL){uip_udp_bind(uip_udp_conn,HTONS(3022));//绑定本地端口}while(1){uip_len = tapdev_read(uip_buf);if(uip_len > 0){//收到的是IP数据,调用uip_input()处理if(BUF->type == htons(UIP_ETHTYPE_IP)){uip_arp_ipin();//ARP地址检验uip_input();/* If the above function invocation resulted in data thatshould be sent out on the network, the global variableuip_len is set to a value > 0. *///处理完成后,如果uip_buf中有数据,则调用etherdev_send发送出去if(uip_len > 0){uip_arp_out();//以太网帧头封装tapdev_send(uip_buf,uip_len);}}//收到的是ARP数据,调用uip_arp_arpin()处理else if(BUF->type == htons(UIP_ETHTYPE_ARP)){uip_arp_arpin();/* If the above function invocation resulted in data thatshould be sent out on the network, the global variableuip_len is set to a value > 0. */if(uip_len > 0){tapdev_send(uip_buf,uip_len);}}}//查看0.5S是否到了,到了则调用uip_periodic处理TCP超时程序else if(timer_expired(&periodic_timer)){timer_reset(&periodic_timer);for(i = 0; i < UIP_CONNS; i++){uip_periodic(i);/* If the above function invocation resulted in data thatshould be sent out on the network, the global variableuip_len is set to a value > 0. */if(uip_len > 0){uip_arp_out();tapdev_send(uip_buf,uip_len);}}#if UIP_UDPfor(i = 0; i < UIP_UDP_CONNS; i++) {uip_udp_periodic(i);/* If the above function invocation resulted in data thatshould be sent out on the network, the global variableuip_len is set to a value > 0. */if(uip_len > 0) {uip_arp_out();tapdev_send(uip_buf,uip_len);}}#endif /* UIP_UDP *//* Call the ARP timer function every 10 seconds. */if(timer_expired(&arp_timer)){timer_reset(&arp_timer);uip_arp_timer();}}}Uip.c中添加:/*-----------------------------------------------------------------------------*/ void myudp_send(char *str,short n){char *nptr;nptr = (char*)uip_appdata;memcpy(nptr,str,n);uip_udp_send(n);//发送n个数据}/*-----------------------------------------------------------------------------*/ void newdata(){char *nptr;short len;len = uip_datalen();//读取数据长度nptr = (char*)uip_appdata;//取得数据起始指针if(len<4)myudp_send("Please check the command!\n",26);else if(strncmp(nptr,"getname",7)== 0)myudp_send("My name is xiaoxu.",19);else// uip_send("Unkown command!\n",16);myudp_send("Unkown command!\n",16);}/*-----------------------------------------------------------------------------*/ void udp_appcall( void ){if(uip_udp_conn->rport == HTONS(1000)){if(uip_poll()){myudp_send("hello\n",6);}if(uip_newdata()){newdata();}}}有颜色的部分为,需要修改或添加的代码。

相关主题