有了收发包的格式,如何发送和接收数据包呢?如图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,就会导致网卡芯片死机。
36
明白了发送和接收数据包的原理,那么数据包又是怎样被主机写入芯片RAM和从芯片RAM读出的呢?如图6所示,主机设置好远端DMA开始地址 (RSAR0,1)和远端DMA数据字节数(RBCR0,1),并在CR中设置读/写,就可以从远端DMA口寄存器里读出芯片RAM里的数据/把数据写入芯片RAM。 何谓本地/远端DMA呢?如图7所示,“远端”指CPU接口侧;“本地”指8019的硬件收发电路侧。没有更深的意思,与远近无关,仅仅为了区分主机和芯片硬件两个接口端。这里的DMA与平时所说的DMA有点不同。RTL8019AS的local DMA操作是由控制器本身完成的,而其remote DMA并不是在无主处理器的参与下,数据能自动移到主处理器的内存中。remote DMA指主机CPU给出起址和长度就可以读写芯片RAM,每操作一次RAM地址自动加1。而普通RAM操作每次要先发地址再处理数据,速度较慢。 在一些高档通信控制器上自带有MAC控制器,工作原理与8019的差不多,比如:Motorola 68360/MPC860T内部的CPM带有以太网处理器,通过设置BD表,使软件和硬件协同工作,它的缓冲区更大且可灵活配置。这些通信控制器的设计,体现了软硬件互相融合协同工作的趋势:软件硬化(VHDL),硬件软化(DSP),希望大家关注!
如图7所示,8019以太网控制器以存储器(16K双口RAM)为核心,本地和远端控制器并发操作。这种体系结构满足了数据带宽的需要。8019拥有控制、状态、数据寄存器,通过它们,51单片机可以与8019通信。由于51资源紧张,在实现TCPIP协议栈时不要进行内存块拷贝,建议(1)使用全局结构体变量,在内存中只保存一个数据包拷贝,其他没有来得及处理的包保存在8019的16K RAM里;(2)使用查询方式而不用中断;(3)客户服务器模型中服务器工作于串行方式,并发模式不适合51单片机。 芯片内部地址空间的分配如图8所示,其中0x00-0x0B(工作于8位DMA模式)用于存放本节点MAC地址,奇偶地址内容是重复放置的。如:MAC地址0000 1234 5678存放在0x00-0x0B中为000000001212343456567878,单地址和双地址的内容是重复的.一般使用偶数地址的内容,这主要是为了同时适应8位和16位的dma。Prom内容是网卡在上电复位的时候从93C46里读出来的。如果你没有使用93C46,就不要使用Prom,那么使用了93C46后如何获得网卡的地址呢?有两种方法,一是直接读93C46,二是读Prom。网卡MAC地址既不由93C46也不由Prom决定,而是由PAR0-PAR5寄存器决定。Prom只保存上电时从9346中读出的MAC地址(如果有93C46的话),仅此而矣。
37
网卡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---发送配置寄存器
38
DCR---数据配置寄存器 IMR---中断屏蔽寄存器 NCR---包发送期间碰撞次数 FIFO---环回检测后,查看FIFO内容 CNTR0---帧同步错总计数器 CNTR1---CRC错总计数器 CNTR2---丢包总计数器 PAR0-5---本节点MAC地址 MAR0-7---多播地址匹配
建议:将图形中寄存器名称标注上页号和地址偏移(如:BNRY 0页0x03),打印出此图,看图编程,直观且不容易出错。
备注:收缓冲区、发缓冲区、数据存储区在16K双口RAM里的安排由用户自行决定,只要不引起冲突即可,以下源程序代码实现的只是其中的一种分配方案。 部分源程序清单: struct ethernet{
unsigned char status; //接收状态 unsigned char nextpage; //下一个页
unsigned int length; //以太网长度,以字节为单位 unsigned int destnodeid[3]; //目的网卡地址 unsigned int sourcenodeid[3]; //源网卡地址 unsigned int protocal; //下一层协议 unsigned char packet[1500]; //包的内容 };
void ne2000init()//ne2000网卡初始化 {
rtl8019as_rst();
reg00=0x21; //选择页0的寄存器,网卡停止运行,因为还没有初始化。 delay_ms(10); //延时10毫秒,确保芯片进入停止模式 //使芯片处于mon和loopback模式,跟外部网络断开 page(0); reg0a=0x00; reg0b=0x00;
reg0c=0xE0; //monitor mode (no packet receive) reg0d=0xE2; //loop back mode
//使用0x40-0x4B为网卡的发送缓冲区,共12页,刚好可以存储2个最大的以太网包。 //使用0x4c-0x7f为网卡的接收缓冲区,共52页。 reg01=0x4C; //Pstart 接收缓冲区范围 reg02=0x80; //Pstop reg03=0x4C; //BNRY
reg04=0x40; //TPSR 发送缓冲区范围 reg07=0xFF;/*清除所有中断标志位*/ reg0f=0x00;//IMR disable all interrupt reg0e=0xC8; //DCR byte dma 8位dma方式 page(1); //选择页1的寄存器 reg07=0x4D; //CURR reg08=0x00; //MAR0
39
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; //清除所有中断标志位 }
void send_packet(union netcard *txdnet,unsigned int length)//ne2000发包子程序
{//发送一个数据包的命令,长度最小为60字节,最大1514字节需要发送的数据包要先存放在txdnet缓冲区
unsigned char i; unsigned int ii; 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 ; //txdwrite highaddress else
reg09=0x46 ; //txdwrite highaddress reg08=0x00; //read page address low reg0b=length>>8; //read count high reg0a=length&0xFF; //read count low; reg00=0x12; //write dma, 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; } 40 百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库RTL8019AS使用 - 图文(8)在线全文阅读。
相关推荐: