TCPIP知识储备.docx

上传人:b****8 文档编号:12976543 上传时间:2023-06-09 格式:DOCX 页数:18 大小:163.71KB
下载 相关 举报
TCPIP知识储备.docx_第1页
第1页 / 共18页
TCPIP知识储备.docx_第2页
第2页 / 共18页
TCPIP知识储备.docx_第3页
第3页 / 共18页
TCPIP知识储备.docx_第4页
第4页 / 共18页
TCPIP知识储备.docx_第5页
第5页 / 共18页
TCPIP知识储备.docx_第6页
第6页 / 共18页
TCPIP知识储备.docx_第7页
第7页 / 共18页
TCPIP知识储备.docx_第8页
第8页 / 共18页
TCPIP知识储备.docx_第9页
第9页 / 共18页
TCPIP知识储备.docx_第10页
第10页 / 共18页
TCPIP知识储备.docx_第11页
第11页 / 共18页
TCPIP知识储备.docx_第12页
第12页 / 共18页
TCPIP知识储备.docx_第13页
第13页 / 共18页
TCPIP知识储备.docx_第14页
第14页 / 共18页
TCPIP知识储备.docx_第15页
第15页 / 共18页
TCPIP知识储备.docx_第16页
第16页 / 共18页
TCPIP知识储备.docx_第17页
第17页 / 共18页
TCPIP知识储备.docx_第18页
第18页 / 共18页
亲,该文档总共18页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

TCPIP知识储备.docx

《TCPIP知识储备.docx》由会员分享,可在线阅读,更多相关《TCPIP知识储备.docx(18页珍藏版)》请在冰点文库上搜索。

TCPIP知识储备.docx

TCPIP知识储备

#1楼主:

TCP/IP知识储备

文章发表于:

2008-07-0508:

00

我自己今天找的关于TCP/IP的一些应用资料

最好先看这个

 

 

单片机与TCP/IP网络

(一序言)(01/03/21)

(二以太网协议)(01/03/22)

(三)ISA总线(01/03/25)

(四)89C52单片机与网卡接口电路图(01/03/31)

(五)接口电路图详解

(1)(01/04/01)

(六)接口电路图详解

(2)(01/04/01)

(七)网卡上电复位(01/04/01)

(八)网卡初始化(01/04/07)

(九)读取网卡的网卡地址(01/04/07)

(十)设置网卡地址(01/05/23)

(十一)RTL8019ASISA网卡电路图(01/09/13)

(十二)RTL8019AS的跳线方式(01/09/25)

(十三)网卡地址和多点播送(组播)及广播(01/09/28)

(十四)以太网组播地址过滤寄存器MAR0-MAR7的计算(01/10/02)

(15)RTL8019AS,RTL8029AS如何接收一个数据包

(1)

(16)RTL8019AS,RTL8029AS如何读写网卡的RAM

(17)一体化电路图(03/6/15)

(18)如何使用以太网开发板中的调试代码(2006/06/06)

【添加到收藏夹】      【回复】

xieshang

  小组等级:

   E币:

495  (E币换礼)

#2

文章发表于:

2008-07-0520:

01

51单片机RTL8019AS网卡驱动程序

   我的SNMP网管板使用了RTL8019AS10MISA网卡芯片接入以太网。

选它的好处是:

NE2000兼容,软件移植性好;接口简单不用转换芯片如PCI-ISA桥;价格便宜2.1$/片(我的购入价为22元RMB/片);带宽充裕(针对51);较长一段时间内不会停产。

8019有3种配置模式:

跳线方式、即插即用P&P方式、串行Flash配置方式。

为了节省成本,我去掉了9346而使用X5045作为闪盘存储MAC地址和其他可配置信息。

P&P模式用在PC机中,这里用不上。

只剩下跳线配置模式可用,它的电路设计参考REALTEK提供的DEMO板图纸。

一天时间就可以完成,相对来说硬件设计比较简单。

   与这部分硬件相对应的软件是网卡驱动。

所谓驱动程序是指一组子程序,它们屏蔽了底层硬件处理细节,同时向上层软件提供硬件无关接口。

驱动程序可以写成子程序嵌入到应用程序里(如DOS下的I/O端口操作和ISR),也可以放在动态链接库里,用到的时候再动态调入以便节省内存。

在WIN98中,为了使V86、WIN16、WIN32三种模式的应用程序共存,提出了虚拟机的概念,在CPU的配合下,系统工作在保护模式,OS接管了I/O、中断、内存访问,应用程序不能直接访问硬件。

这样提高了系统可靠性和兼容性,也带来了软件编程复杂的问题。

任何网卡驱动都要按VXD或WDM模式编写,对于硬件一侧要处理虚拟机操作、总线协议(如ISA、PCI)、即插即用、电源管理;上层软件一侧要实现NDIS规范。

因此在WIN98下实现网卡驱动是一件相当复杂的事情。

   我这里说的驱动程序特指实模式下的一组硬件芯片驱动子程序。

从程序员的角度看,8019工作流程非常简单,驱动程序将要发送的数据包按指定格式写入芯片并启动发送命令,8019会自动把数据包转换成物理帧格式在物理信道上传输。

反之,8019收到物理信号后将其还原成数据,按指定格式存放在芯片RAM中以便主机程序取用。

简言之就是8019完成数据包和电信号之间的相互转换:

数据包<===>电信号。

以太网协议由芯片硬件自动完成,对程序员透明。

驱动程序有3种功能:

芯片初始化、收包、发包。

   以太网协议不止一种,我用的是802.3。

它的帧结构如图1所示。

物理信道上的收发操作均使用这个帧格式。

其中,前导序列、帧起始位、CRC校验由硬件自动添加/删除,与上层软件无关。

值得注意的是,收到的数据包格式并不是802.3帧的真子集,而是如图2所示。

明显地,8019自动添加了“接收状态、下一页指针、以太网帧长度(以字节为单位)”三个数据成员(共4字节)。

这些数据成员的引入方便了驱动程序的设计,体现了软硬件互相配合协同工作的设计思路。

当然,发送数据包的格式是802.3帧的真子集,如图3所示。

    

 

 

    

   有了收发包的格式,如何发送和接收数据包呢?

如图4所示,先将待发送的数据包存入芯片RAM,给出发送缓冲区首地址和数据包长度(写入TPSR、TBCR0,1),启动发送命令(CR=0x3E)即可实现8019发送功能。

8019会自动按以太网协议完成发送并将结果写入状态寄存器。

如图5所示,接收缓冲区构成一个循环FIFO队列,PSTART、PSTOP两个寄存器限定了循环队列的开始和结束页,CURR为写入指针,受芯片控制,BNRY为读出指针,由主机程序控制。

根据CURR==BNRY+1?

可以判断是否收到新的数据包,新收到的数据包按图2格式存于以CURR指出的地址为首址的RAM中。

当CURR==BNRY时芯片停止接收数据包。

如果做过FPGA设计,用过VHDL,可以想象到硬件芯片的工作原理。

此处,设计2个8bit寄存器和一个2输入比较器,当收到数据包时,接收状态机根据当前状态和比较器结果决定下一个状态,如果CURR=BNRY,进入停收状态;反之,CURR按模增1。

8019数据手册没有给出硬件状态机实现方法,说明也很简略,往往要通过作实验的方法推理出工作过程。

比如,ISR寄存器不只和中断有关,当接收缓冲溢出时,如果不清ISR(写入FFH),芯片将一直停止接收。

在流量较大时溢出经常发生,此时不清ISR,就会导致网卡芯片死机。

    

 

   明白了发送和接收数据包的原理,那么数据包又是怎样被主机写入芯片RAM和从芯片RAM读出的呢?

如图6所示,主机设置好远端DMA开始地址(RSAR0,1)和远端DMA数据字节数(RBCR0,1),并在CR中设置读/写,就可以从远端DMA口寄存器里读出芯片RAM里的数据/把数据写入芯片RAM。

   何谓本地/远端DMA呢?

如图7所示,“远端”指CPU接口侧;“本地”指8019的硬件收发电路侧。

没有更深的意思,与远近无关,仅仅为了区分主机和芯片硬件两个接口端。

这里的DMA与平时所说的DMA有点不同。

RTL8019AS的localDMA操作是由控制器本身完成的,而其remoteDMA并不是在无主处理器的参与下,数据能自动移到主处理器的内存中。

remoteDMA指主机CPU给出起址和长度就可以读写芯片RAM,每操作一次RAM地址自动加1。

而普通RAM操作每次要先发地址再处理数据,速度较慢。

   在一些高档通信控制器上自带有MAC控制器,工作原理与8019的差不多,比如:

Motorola68360/MPC860T内部的CPM带有以太网处理器,通过设置BD表,使软件和硬件协同工作,它的缓冲区更大且可灵活配置。

这些通信控制器的设计,体现了软硬件互相融合协同工作的趋势:

软件硬化(VHDL),硬件软化(DSP),希望大家关注!

    

 

   如图7所示,8019以太网控制器以存储器(16K双口RAM)为核心,本地和远端控制器并发操作。

这种体系结构满足了数据带宽的需要。

8019拥有控制、状态、数据寄存器,通过它们,51单片机可以与8019通信。

由于51资源紧张,在实现TCPIP协议栈时不要进行内存块拷贝,建议

(1)使用全局结构体变量,在内存中只保存一个数据包拷贝,其他没有来得及处理的包保存在8019的16KRAM里;

(2)使用查询方式而不用中断;(3)客户服务器模型中服务器工作于串行方式,并发模式不适合51单片机。

   芯片内部地址空间的分配如图8所示,其中0x00-0x0B(工作于8位DMA模式)用于存放本节点MAC地址,奇偶地址内容是重复放置的。

如:

MAC地址000012345678存放在0x00-0x0B中为000000001212343456567878,单地址和双地址的内容是重复的.一般使用偶数地址的内容,这主要是为了同时适应8位和16位的dma。

Prom内容是网卡在上电复位的时候从93C46里读出来的。

如果你没有使用93C46,就不要使用Prom,那么使用了93C46后如何获得网卡的地址呢?

有两种方法,一是直接读93C46,二是读Prom。

网卡MAC地址既不由93C46也不由Prom决定,而是由PAR0-PAR5寄存器决定。

Prom只保存上电时从9346中读出的MAC地址(如果有93C46的话),仅此而矣。

    

 

 

   网卡MAC地址不是随便定义的,它的组成结构如图9所示。

以太网的地址为48位,由ieee统一分配给网卡制造商,每个网卡的地址都必须是全球唯一的。

共6个字节的长度。

FF:

FF:

FF:

FF:

FF:

FF为广播地址,只能用在目的地址段,不能作为源地址段。

目的地址为广播地址的数据包,可以被一个局域网内的所有网卡接收到。

合法的以太网地址第32位组播标志必须为0。

例如:

X0:

XX:

XX:

XX:

XX:

XX

X2:

XX:

XX:

XX:

XX:

XX

X4:

XX:

XX:

XX:

XX:

XX

X6:

XX:

XX:

XX:

XX:

XX

X8:

XX:

XX:

XX:

XX:

XX

XA:

XX:

XX:

XX:

XX:

XX

XC:

XX:

XX:

XX:

XX:

XX

XE:

XX:

XX:

XX:

XX:

XX

为合法以太网地址。

上面的X代表0-F中的任一个。

地址

X1:

XX:

XX:

XX:

XX:

XX

X3:

XX:

XX:

XX:

XX:

XX

X5:

XX:

XX:

XX:

XX:

XX

X7:

XX:

XX:

XX:

XX:

XX

X9:

XX:

XX:

XX:

XX:

XX

XB:

XX:

XX:

XX:

XX:

XX

XD:

XX:

XX:

XX:

XX:

XX

XF:

XX:

XX:

XX:

XX:

XX

为组播地址,只能作为目的地址,不能作为源地址。

组播地址可以被支持该组播地址的一组网卡接收到。

组播地址主要用在视频广播,远程唤醒(通过发一个特殊的数据包使网卡产生一个中断信号,启动电脑),游戏(多个人在局域网里联机打游戏)里等。

以下是一些具体的组播地址:

地址范围

01:

00:

5E:

00:

00:

00---01:

00:

5E:

7F:

FF:

FF用于ip地址的组播,其他组播地址跟tcp/ip无关,不做介绍。

网卡可以接收以下3种地址的数据包:

第一种目的地址跟自己的网卡地址是一样的数据包;

第二种目的地址为FF:

FF:

FF:

FF:

FF:

FF广播地址的数据包;

第三种目的地址为跟自己的组播地址范围相同的数据包。

在以太网的应用当中,如果你希望你的数据包只发给一个网卡,目的地址用对方的网卡地址;

如果你想把数据包发给所有的网卡,目的地址用广播地址;

如果你想把数据包发给一组网卡,目的地址用组播地址。

其他用到的寄存器:

CR---命令寄存器      TSR---发送状态寄存器       ISR---中断状态寄存器

RSR---接收状态寄存器 RCR---接收配置寄存器       TCR---发送配置寄存器

DCR---数据配置寄存器 IMR---中断屏蔽寄存器       NCR---包发送期间碰撞次数

FIFO---环回检测后,查看FIFO内容

CNTR0---帧同步错总计数器

CNTR1---CRC错总计数器

CNTR2---丢包总计数器

PAR0-5---本节点MAC地址

MAR0-7---多播地址匹配

建议:

将图形中寄存器名称标注上页号和地址偏移(如:

BNRY0页0x03),打印出此图,看图编程,直观且不容易出错。

备注:

收缓冲区、发缓冲区、数据存储区在16K双口RAM里的安排由用户自行决定,只要不引起冲突即可,以下源程序代码实现的只是其中的一种分配方案。

部分源程序清单:

structethernet{

   unsignedcharstatus;         //接收状态

   unsignedcharnextpage;       //下一个页

   unsignedint length;         //以太网长度,以字节为单位

   unsignedint destnodeid[3];  //目的网卡地址

   unsignedint sourcenodeid[3];//源网卡地址

   unsignedint protocal;       //下一层协议

   unsignedcharpacket[1500];   //包的内容

};

voidne2000init()//ne2000网卡初始化

{

   rtl8019as_rst();

   reg00=0x21;  //选择页0的寄存器,网卡停止运行,因为还没有初始化。

   delay_ms(10);//延时10毫秒,确保芯片进入停止模式

//使芯片处于mon和loopback模式,跟外部网络断开

   page(0);

   reg0a=0x00;

   reg0b=0x00;

   reg0c=0xE0;//monitormode(nopacketreceive)

   reg0d=0xE2;//loopbackmode

//使用0x40-0x4B为网卡的发送缓冲区,共12页,刚好可以存储2个最大的以太网包。

//使用0x4c-0x7f为网卡的接收缓冲区,共52页。

   reg01=0x4C;//Pstart 接收缓冲区范围

   reg02=0x80;//Pstop

   reg03=0x4C;//BNRY

   reg04=0x40;//TPSR   发送缓冲区范围

   reg07=0xFF;/*清除所有中断标志位*/

   reg0f=0x00;//IMRdisableallinterrupt

   reg0e=0xC8;//DCRbytedma8位dma方式

   page

(1);//选择页1的寄存器

   reg07=0x4D;//CURR 

   reg08=0x00;//MAR0

   reg09=0x41;//MAR1

   reg0a=0x00;//MAR2

   reg0b=0x80;//MAR3

   reg0c=0x00;//MAR4

   reg0d=0x00;//MAR5

   reg0e=0x00;//MAR6

   reg0f=0x00;//MAR7 

   initNIC(); //初始化MAC地址和网络相关参数

//将网卡设置成正常的模式,跟外部网络连接

   page(0);

   reg0c=0xCC;//RCR

   reg0d=0xE0;//TCR

   reg00=0x22;//这时让芯片开始工作?

   reg07=0xFF;//清除所有中断标志位

}

voidsend_packet(unionnetcard*txdnet,unsignedintlength)//ne2000发包子程序

{//发送一个数据包的命令,长度最小为60字节,最大1514字节需要发送的数据包要先存放在txdnet缓冲区

   unsignedchari;

   unsignedintii;

   page(0);

   if(length<60)length="60";

   for(i=0;i<3;i++)

       txdnet->etherframe.sourcenodeid[i]=my_ethernet_address.words[i];

   txd_buffer_select=!

txd_buffer_select;

   if(txd_buffer_select)

       reg09=0x40;         //txdwritehighaddress

   else

       reg09=0x46;         //txdwritehighaddress      

   reg08=0x00;   //readpageaddresslow

   reg0b=length>>8;         //readcounthigh

   reg0a=length&0xFF;       //readcountlow;

   reg00=0x12;    //writedma,page0

  

   for(ii=4;ii

       reg10=txdnet->bytes.bytebuf[ii];

   for(i=0;i<6;i++){                  //最多重发6次

       for(ii=0;ii<1000;ii++)         //检查txp为是否为低

           if((reg00&0x04)==0)break;

        

       if((reg04&0x01)!

=0)break;     //表示发送成功       

 

       reg00=0x3E;

   }

 

   if(txd_buffer_select)reg04=0x40;  //txdpacketstart;

   elsereg04=0x46;         //txdpacketstart;        

   reg06=length>>8;         //highbytecounter

   reg05=length&0xFF;       //lowbytecounter

   reg00=0x3E;              //tosendpacket; 

}

bitrecv_packet(unionnetcard*rxdnet)//ne2000收包子程序

{

   unsignedchari;

   unsignedintii;

   unsignedcharbnry,curr;

  

   page(0);

   reg07=0xFF;

   bnry="reg03";              //bnrypagehaveread读页指针

   page

(1);

   curr="reg07";              //currwritepoint8019写页指针

   page(0);

   if(curr==0)

       return0;            //读的过程出错 

   bnry="bnry"++;

   if(bnry>0x7F)bnry="0x4C";

   if(bnry!

=curr){          //此时表示有新的数据包在缓冲区里

 //读取一包的前18个字节:

4字节的8019头部,6字节目的地址,6字节原地址,2字节协议

 //在任何操作都最好返回page0

       page(0);

       reg09=bnry;          //readpageaddresshigh

       reg08=0x00;          //readpageaddresslow

       reg0b=0x00;          //readcounthigh

       reg0a=18;            //readcountlow;

       reg00=0x0A;          //readdma

       for(i=0;i<18;i++)

           rxdnet->bytes.bytebuf[i]=reg10;

       i="rxdnet-">bytes.bytebuf[3];    //将长度字段的高低字节掉转

       rxdnet->bytes.bytebuf[3]=rxdnet->bytes.bytebuf[2];

       rxdnet->bytes.bytebuf[2]=i;   

       rxdnet->etherframe.length=rxdnet->etherframe.length-4;//去掉4个字节的CRC

       //表示读入的数据包有效

       if(((rxdnet->bytes.bytebuf[0]&0x01)==0)||(rxdnet->bytes.bytebuf[1]>0x7F)||(rxdnet->bytes.bytebuf[1]<0x4C)||(rxdnet->bytes.bytebuf[2]>0x06)){

           //接收状态错误,或者next_page_start错误或者长度错误,将丢弃所有数据包

           page

(1);

           curr="reg07";      //page1

           page(0);         //切换回page0

           bnry="curr-1";

           if(bnry<0x4C)bnry="0x7F";

           reg03=bnry;      //writetobnry    

           return0;

       }

       else{//表示数据包是完好的.读取剩下的数据

           if((rxdnet->etherframe.protocal==0x0800)||(rxdnet->etherframe.protocal==0x0806)){

           //协议为IP或ARP才接收       

               reg09=bnry;  //readpageaddresshigh

               reg08=4;     //readpageaddresslow

               reg0b=rxdnet->etherframe.length>>8;    //readcounthigh

               reg0a=rxdnet->etherframe.length&0xFF;  //readcountlow;

               reg00=0x0A;  //readdma

               for(ii=4;iietherframe.length+4;ii++)

                   rxdnet->bytes.bytebuf[ii]=reg10;

           }

  

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2