基于RTL8019的以太网应用系统2007-11-0610:57:09本文已公布到博客频道校园·教育分类基于RTL8019的以太网应用系统基于RTL8019的以太网应用系统以太网接口模块是构造一给通用的基于网络的嵌入式Linux系统的基础,该接口模块的主要任务就是完成与外界信息的交互,以达到网络监控的目的。使用RTL8019作为以太网的物理层接口,它的基本工作原理:是在收到由主机发来的数据报后(从目的地址域到数据域),侦听网络线路。如果线路忙,就等到线路空闲为止,否则,立即发送数据桢。RTL8019为台湾芯片生产商Realtek公司第三代快速以太网连接而设计,它支持多种嵌入式处理器芯片,内置FIFO缓存器用于发送和接受数据。系统硬件电路结构图:系统工作流程图:网络数据的发送流程:网络数据的接收:RTL8019工作代码://RTL8019.c#includeGloblDef.h#includeMMenage.h#includeRTL8019.hexternBYTEMemAllocation(WORDsize);externvoidFreePage(BYTEpage);externBYTExdata*MemPageToPoint(BYTEpage);externBYTEWriteQueue(BYTEpage,structQueuexdata*pQueue);BYTExdataLocalMACAddr[6]={0x52,0x54,0x4c,0x30,0x2e,0x2f};structQueuexdataQueueNetPacketIn;BYTEStartPageOfPacket;/*接收头文件信息*/structRTLReceiveHeader{BYTEReceiveStatus;BYTENextPacketStartPage;BYTEPacketSizeLow;BYTEPacketSizeHigh;}Head;Head须为全局变量.BYTExdataHead[4];/*上一次传输起始页*/BYTELastSendStartPage;sbitRTLResetPin=RTL_RESET_PIN;/*读rtl8019寄存器端口*/BYTEReadReg(WORDport){BYTExdata*p;p=(BYTExdata*)port;return*p;}/*写寄存器*/voidWriteReg(WORDport,BYTEvalue){BYTExdata*p;p=(BYTExdata*)port;*p=value;}/*选择寄存器页使用*/voidRTLPage(BYTEIndex){/*设置CR,CR_TXP7-6位为0(为1,包重传)*/BYTEtemp;temp=ReadReg(CR);temp=temp&0x3B;/*set7-6and3bitto0*/Index=Index6;temp=temp|Index;WriteReg(CR,temp);}/*PRA为物理地址*/voidRTLInitial(){BYTEtemp;inti;/*硬件重启*/RTLResetPin=1;for(i=0;i255;i++);RTLResetPin=0;/*如果硬件重启时延很大,rtl自我初始化*/for(i=0;iDELAY_AFTER_HARDWARE_RESET;i++);/*写重启口*/temp=ReadReg(RESET_PORT);WriteReg(RESET_PORT,temp);/*初始化RTL寄存器*/WriteReg(CR,(CR_PAGE0|CR_ABORT_COMPLETE_DMA|CR_STOP_COMMAND));/*设置page0,stopcommand*/WriteReg(PSTART_WPAGE0,RECEIVE_START_PAGE);/*Pstart*/WriteReg(PSTOP_WPAGE0,RECEIVE_STOP_PAGE);/*Pstop*/WriteReg(BNRY_WPAGE0,RECEIVE_START_PAGE);/*BNRY*/WriteReg(TPSR_WPAGE0,SEND_START_PAGE0);/*TPSR*/WriteReg(RCR_WPAGE0,0xCE);/*RCR:在Rtl8019as.h定义*/WriteReg(TCR_WPAGE0,0xE0);/*TCR:在Rtl8019as.h定义*/WriteReg(DCR_WPAGE0,0xC8);/*DCR:在Rtl8019as.h定义*/WriteReg(IMR_WPAGE0,0);/*RTL接收中断使能*/WriteReg(ISR_WPAGE0,0xFF);/*写FF清除所有中断标志*/RTLPage(1);WriteReg(CURR_WPAGE1,RECEIVE_START_PAGE+1);/*MAR0*/WriteReg(0x08,0x00);WriteReg(0x09,0x41);WriteReg(0x0a,0x00);WriteReg(0x0b,0x80);WriteReg(0x0c,0x00);WriteReg(0x0d,0x00);WriteReg(0x0e,0x00);WriteReg(0x0f,0x00)/*设置物理地址*/WriteReg(PRA0_WPAGE1,LocalMACAddr[0]);WriteReg(PRA1_WPAGE1,LocalMACAddr[1]);WriteReg(PRA2_WPAGE1,LocalMACAddr[2]);WriteReg(PRA3_WPAGE1,LocalMACAddr[3]);WriteReg(PRA4_WPAGE1,LocalMACAddr[4]);WriteReg(PRA5_WPAGE1,LocalMACAddr[5]);/*传输起始页*/LastSendStartPage=SEND_START_PAGE0;StartPageOfPacket=RECEIVE_START_PAGE+1;/*初始化结束*/WriteReg(CR,(CR_PAGE0|CR_ABORT_COMPLETE_DMA|CR_STOP_COMMAND));}/*写buffer到rltram*/voidRTLWriteRam(WORDaddress,WORDsize,BYTExdata*buff){WORDi;BYTEPrePage;/*storepage*/PrePage=ReadReg(CR);RTLPage(0);WriteReg(RSARH_WPAGE0,(BYTE)((address8)&0x00ff));WriteReg(RSARL_WPAGE0,(BYTE)address);WriteReg(RBCRH_WPAGE0,(BYTE)((size8)&0x00ff));WriteReg(RBCRL_WPAGE0,(BYTE)size);WriteReg(CR,(0x00|CR_REMOTE_WRITE|CR_START_COMMAND));for(i=0;isize;i++){WriteReg(REMOTE_DMA_PORT,buff[i]);}/*完成dma*/WriteReg(RBCRH_WPAGE0,0);WriteReg(RBCRL_WPAGE0,0);WriteReg(CR,((PrePage&0xC0)|CR_ABORT_COMPLETE_DMA|CR_START_COMMAND));}/*读rltram数据到buffer*/voidRTLReadRam(WORDaddress,WORDsize,BYTExdata*buff){WORDi;BYTEPrePage;/*存储页*/PrePage=ReadReg(CR);RTLPage(0);WriteReg(RSARH_WPAGE0,(BYTE)((address8)&0x00ff));WriteReg(RSARL_WPAGE0,(BYTE)address);WriteReg(RBCRH_WPAGE0,(BYTE)((size8)&0x00ff));WriteReg(RBCRL_WPAGE0,(BYTE)size);WriteReg(CR,(0x00|CR_REMOTE_READ|CR_START_COMMAND));for(i=0;isize;i++){buff[i]=ReadReg(REMOTE_DMA_PORT);}/*完成dma*/WriteReg(RBCRH_WPAGE0,0);WriteReg(RBCRL_WPAGE0,0);WriteReg(CR,((PrePage&0xC0)|CR_ABORT_COMPLETE_DMA|CR_START_COMMAND));}BYTERTLSendPacket(BYTExdata*buffer,WORDsize){BYTEStartPage;/*存储页*/BYTEPrePage;PrePage=ReadReg(CR);/*检查包大小*/if(sizeMIN_PACKET_SIZE||sizeMAX_PACKET_SIZE)returnFALSE;/*写包到ram*/if(LastSendStartPage==SEND_START_PAGE0){StartPage=SEND_START_PAGE1;LastSendStartPage=SEND_START_PAGE1;}else{StartPage=SEND_START_PAGE0;LastSendStartPage=SEND_START_PAGE0;}RTLWriteRam(((WORD)StartPage)8,size,buffer);/*等待上一次传输结束*/while((ReadReg(CR)&CR_TXP)==CR_TXP);/*写传输起始页和大小*/RTLPage(0);WriteReg(TPSR_WPAGE0,StartPage);/*TPSR*/WriteReg(TBCRL_WPAGE0,(BYTE)size);/*low*/WriteReg(TBCRH_WPAGE0,(BYTE)((size8)&0x00ff));/*high*/WriteReg(CR,((PrePage&0xC0)|CR_ABORT_COMPLETE_DMA|CR_TXP|CR_START_COMMAND));returnTRUE;}voidRTLReceivePacket(){BYTEcurr,bnry;WORDaddress;WORDPacketSize;BYTEMemPage;structMemHeaderxdata*pMemHead;RTLPage(1);curr=ReadReg(CURR_RPAGE1);RTLPage(0);/*在接收缓存中读所有包*/while(TRUE){/*检验起始页是否未知错误*/if(StartPageOfPacket=RECEIVE_STOP_PAGE||StartPageOfPacketRECEIVE_START_PAGE){/*用curr作为StartPageOfPacket*/StartPageOfPacket=curr;break;}/*检查是否有包读到*/if(StartPageOfPacket==curr)break;/*读一个包*//*读包头信息*/address=((WORD)StartPageOfPacket)8;RTLReadRam(address,4,Head);/*校验rsr*/if(Head[0]&RSR_RECEIVE_NO_ERROR){/*好包*//*得到MAC校验和*/PacketSize=((WORD)Head[3])*256+Head[2]-4;/*分配buffer,读包到buffer*/MemPage=MemAllocation(PacketSize);if(MemPage!=PAGE_NOT_F