⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uip + mcu51-63k仿真器实现tcp-ip协议栈(lszisgood).htm

📁 单片机控制RTL8019网卡芯片实现TCP/IP协议栈是一件非常有意思的实验。我尝试使用专门针对8位单片机设计的uIP6.0在mcu51-63K仿真器移植成功
💻 HTM
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0036)http://www.daxia.com/list.asp?id=932 -->
<HTML><HEAD><TITLE>uIP + mcu51-63K仿真器实现TCP/IP协议栈(lszisgood)</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312"><LINK 
href="uIP + mcu51-63K仿真器实现TCP-IP协议栈(lszisgood).files/style.css" rel=stylesheet>
<META content="MSHTML 6.00.2800.1106" name=GENERATOR></HEAD>
<BODY>
<DIV align=center>
<CENTER></CENTER></DIV>
<DIV align=center>
<CENTER>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=0 width="97%" 
borderColorLight=#000000 border=1>
  <TBODY>
  <TR>
    <TD width="100%" bgColor=#d0d0d0>
      <P align=center>文章编号:932----加入日期:2003-12-15 </P></TD></TR>
  <TR>
    <TD width="100%">
      <P align=right><A href="javascript:self.close()">『关闭窗口』</A></P></TD></TR>
  <TR>
    <TD width="100%">
      <P align=center><B>uIP + mcu51-63K仿真器实现TCP/IP协议栈(lszisgood)</B></P></TD></TR>
  <TR>
    <TD width="100%">
      <BLOCKQUOTE><BR><BR>&nbsp;&nbsp;&nbsp;单片机控制RTL8019网卡芯片实现TCP/IP协议栈是一件非常有<BR>意思的实验。我尝试使用专门针对8位单片机设计的uIP6.0在版主<BR>的mcu51-63K仿真器移植成功,下面介绍一下移植过程。<BR><BR>&nbsp;&nbsp;uIP的介绍可以到<A 
        href="http://dunkels.com/adam/uip/" 
        target=_blank>http://dunkels.com/adam/uip/</A>下载相关<BR>的文档,源代码也可以下载。我使用的是uIP6.0版本。<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;在KELI中创建一个uip的工程,将相关的文件加入。参考<BR>slipdev.c,我编写RTL8019的驱动接口,在文件ethrdev.c中提<BR>供三个函数接口:<BR><BR>&nbsp;&nbsp;&nbsp;a:void&nbsp;&nbsp;ethrdev_init() 
        初始化网卡芯片,使网卡进入服务状态;<BR>&nbsp;&nbsp;&nbsp;b:u16_t ethrdev_read() 
        读新的以太数据包,如果没有新数据返回0;<BR>&nbsp;&nbsp;&nbsp;c:void&nbsp;&nbsp;ethrdev_send() 
        发送以太数据包到网络中。<BR><BR><BR>&nbsp;&nbsp;&nbsp;修改main.c的main()函数<BR><BR>/*------------------------------------------------------------------------------<BR>-----*/<BR>void<BR>main(void)<BR>{<BR>&nbsp;&nbsp;u8_t 
        i;<BR>&nbsp;&nbsp;u16_t 
        start;<BR><BR>&nbsp;&nbsp;uip_init();<BR>&nbsp;&nbsp;<A 
        href="http://www.daxia.com/httpd_init();" 
        target=_blank>httpd_init();</A><BR>&nbsp;&nbsp;ethrdev_init();<BR>&nbsp;&nbsp;putstr("8051 
        TCP/IP stack and web server 
        running\n");<BR>&nbsp;&nbsp;init_int();<BR>&nbsp;&nbsp;start = 
        0;<BR><BR>&nbsp;&nbsp;while(1) 
        <BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;/* Let the tapdev network 
        device driver read an entire IP 
        packet<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;into the uip_buf. If 
        it must wait for more than 0.5 seconds, 
        it<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;will return with the 
        return value 0. If so, we know that it 
        is<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time to call upon the 
        uip_periodic(). Otherwise, the tapdev 
        has<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;received an IP packet 
        that is to be processed by uIP. */<BR>&nbsp;&nbsp;&nbsp;&nbsp;uip_len = 
        ethrdev_read();<BR>&nbsp;&nbsp;&nbsp;&nbsp;if(uip_len == 0) 
        <BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(i 
        = 0; i &lt; UIP_CONNS; i++) 
        <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uip_periodic(i);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* 
        If the above function invocation resulted in data that<BR>&nbsp;should 
        be sent out on the network, the global <BR>variable<BR>&nbsp;uip_len is 
        set to a value &gt; 0. */<BR>&nbsp;&nbsp;if(uip_len &gt; 0) 
        <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uip_arp_out();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ethrdev_send();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* 
        Call the ARP timer function every 10 seconds. 
        */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(++numClicks == 20) 
        <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ 
        <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
        &nbsp;&nbsp;&nbsp;uip_arp_timer();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;numClicks 
        = 
        0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}else<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(BUF-&gt;type 
        == htons(UIP_ETHTYPE_IP)) 
        <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uip_arp_ipin();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uip_len 
        -= sizeof(struct 
        uip_eth_hdr);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uip_input();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* 
        If the above function invocation resulted in data 
        that<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;should be sent 
        out on the network, the global 
        variable<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uip_len is 
        set to a value &gt; 0. */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(uip_len 
        &gt; 0) 
        <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uip_arp_out();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;slipdev_send();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} 
        else if(BUF-&gt;type == htons(UIP_ETHTYPE_ARP)) 
        <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uip_arp_arpin();<BR>/* 
        If the above function invocation resulted in <BR>data 
        that<BR>&nbsp;&nbsp;&nbsp;should be sent out on the network, the 
        <BR>global variable<BR>&nbsp;&nbsp;&nbsp;uip_len is set to a value &gt; 
        0. */ <BR>if(uip_len &gt; 0) <BR>{ <BR>&nbsp;&nbsp; 
        ethrdev_send();<BR>}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;}<BR><BR>}<BR><BR>&nbsp;&nbsp;&nbsp;由于RTL8019网卡的读入数据包前4个字节不是真正的以太包数据,<BR>在ethrdev_read()函数中要特别注意,可以先读出前18个字节,校验<BR>成功后再将剩余的数据读出。<BR><BR>需要修改文件uipopt.h中UIP_LLH_LEN为14<BR><BR>/* 
        UIP_LLH_LEN: The link level header length; this is the offset 
        into<BR>&nbsp;&nbsp;&nbsp;the uip_buf where the IP header can be found. 
        For Ethernet, this<BR>&nbsp;&nbsp;&nbsp;should be set to 14. For SLIP, 
        this should be set to 0. */<BR>#define 
        UIP_LLH_LEN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;14<BR><BR><BR>同时定义字节序为BIG_ENDIAN方式<BR>#ifndef 
        BYTE_ORDER<BR>#define 
        BYTE_ORDER&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BIG_ENDIAN<BR>#endif /* 
        BYTE_ORDER 
        */<BR><BR>&nbsp;&nbsp;&nbsp;在函数ethrdev_init()初始化RTL8019的物理地址<BR>需要使用uIP定义的物理地址。也可以使用从网卡读出的<BR>物理地址,但要更新uIP的结构ethaddr,否则物理地址<BR>会判断不一致。<BR><BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;上述修改完毕,编译并下载到mcu51-63K仿真器中,在PC上运行<BR>ping 
        192.168.0.1 -t 
        <BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;你会看到有回应,说明ICMP 
        OK。然后在你的IE中输入<BR><A href="http://192.168.0.1/" 
        target=_blank>http://192.168.0.1/</A> 
        你可看到web网页。简直不敢令人相信,<BR>你只需花不到几个小时就实现了在单片机上移植运行一个Web 
        Server。<BR><BR>TODo:<BR>&nbsp;&nbsp;&nbsp;为了方便没有RTL8019网卡的环境也能实现TCP/IP协议栈,我正<BR>在移植SLIP部分的代码。通过SLIP协议,可以在串口线上承载IP包,<BR>从而不需要网卡也可以实现TCP/IP协议栈。现在我需要先实现通<BR>过I/O线模拟一个串口(mcu51-63K仿真器的串口需要用作下载),<BR>如果那位大侠已经在实现了模拟串口功能,希望共享一份,这样可以<BR>大大加快移植进度。<BR><BR><BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp; 
        <BR><BR>(文章推荐人:丁丁) <BR><BR></BLOCKQUOTE></TD></TR>
  <TR>
    <TD width="100%">
      <P align=center> </P></TD></TR></TBODY></TABLE><A 
href="http://www.daxia.com/bbs" target=_blank>返回大虾论坛</A> <A 
href="http://www.daxia.com/default.asp" target=_blank>返回首页</A> 
</CENTER></DIV></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -