uIP + mcu51-63K仿真器实现TCP/IP协议栈

单片机控制RTL8019网卡芯片实现TCP/IP协议栈是一件非常有
意思的实验。我尝试使用专门针对8位单片机设计的uIP6.0在版主
的mcu51-63K仿真器移植成功,下面介绍一下移植过程。
   
   在KELI中创建一个uip的工程,将相关的文件加入。参考
slipdev.c,我编写RTL8019的驱动接口,在文件ethrdev.c中提
供三个函数接口:

   a:void  ethrdev_init() 初始化网卡芯片,使网卡进入服务状态;
   b:u16_t ethrdev_read() 读新的以太数据包,如果没有新数据返回0;
   c:void  ethrdev_send() 发送以太数据包到网络中。


   修改main.c的main()函数

/*------------------------------------------------------------------------------
-----*/
void
main(void)
{
  u8_t i;
  u16_t start;

  uip_init();
  httpd_init();

  ethrdev_init();
  putstr("8051 TCP/IP stack and web server running/n");
  init_int();
  start = 0;

  while(1)
  {
    /* Let the tapdev network device driver read an entire IP packet
       into the uip_buf. If it must wait for more than 0.5 seconds, it
       will return with the return value 0. If so, we know that it is
       time to call upon the uip_periodic(). Otherwise, the tapdev has
       received an IP packet that is to be processed by uIP. */
    uip_len = ethrdev_read();
    if(uip_len == 0)
    {
      for(i = 0; i < UIP_CONNS; i++)
      {
       uip_periodic(i);
      /* If the above function invocation resulted in data that
 should be sent out on the network, the global
variable
 uip_len is set to a value > 0. */
  if(uip_len > 0)
          {
         uip_arp_out();
         ethrdev_send();
      }
       }

       /* Call the ARP timer function every 10 seconds. */
       if(++numClicks == 20)
       {
         uip_arp_timer();
       numClicks = 0;
       }
    }else
    {
      if(BUF->type == htons(UIP_ETHTYPE_IP))
      {
      uip_arp_ipin();
      uip_len -= sizeof(struct uip_eth_hdr);
      uip_input();
      /* If the above function invocation resulted in data that
        should be sent out on the network, the global variable
        uip_len is set to a value > 0. */
     if(uip_len > 0)
         {
         uip_arp_out();
         slipdev_send();
         }
      } else if(BUF->type == htons(UIP_ETHTYPE_ARP))
      {
       uip_arp_arpin();
/* If the above function invocation resulted in
data that
   should be sent out on the network, the
global variable
   uip_len is set to a value > 0. */
if(uip_len > 0)
{
   ethrdev_send();
}
      }
    }
  }

}

   由于RTL8019网卡的读入数据包前4个字节不是真正的以太包数据,
在ethrdev_read()函数中要特别注意,可以先读出前18个字节,校验
成功后再将剩余的数据读出。

需要修改文件uipopt.h中UIP_LLH_LEN为14

/* UIP_LLH_LEN: The link level header length; this is the offset into
   the uip_buf where the IP header can be found. For Ethernet, this
   should be set to 14. For SLIP, this should be set to 0. */
#define UIP_LLH_LEN     14


同时定义字节序为BIG_ENDIAN方式
#ifndef BYTE_ORDER
#define BYTE_ORDER     BIG_ENDIAN
#endif /* BYTE_ORDER */

   在函数ethrdev_init()初始化RTL8019的物理地址
需要使用uIP定义的物理地址。也可以使用从网卡读出的
物理地址,但要更新uIP的结构ethaddr,否则物理地址
会判断不一致。

  
   上述修改完毕,编译并下载到mcu51-63K仿真器中,在PC上运行
ping 192.168.0.1 -t
   
   你会看到有回应,说明ICMP OK。然后在你的IE中输入
http://192.168.0.1/ 你可看到web网页。简直不敢令人相信,
你只需花不到几个小时就实现了在单片机上移植运行一个Web Server。

TODo:
   为了方便没有RTL8019网卡的环境也能实现TCP/IP协议栈,我正
在移植SLIP部分的代码。通过SLIP协议,可以在串口线上承载IP包,
从而不需要网卡也可以实现TCP/IP协议栈。现在我需要先实现通
过I/O线模拟一个串口(mcu51-63K仿真器的串口需要用作下载),
如果那位大侠已经在实现了模拟串口功能,希望共享一份,这样可以
大大加快移植进度。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值