hr基于RTL8019的以太网应用系统zl
基于RTL8019的以太网应用系统
2007-11-06 10:57:09 本文已公布到博客频道校园?教育分类
基于RTL8019的以太网应用系统
基于RTL8019的以太网应用系统
以太网接口模块是构造一给通用的基于网络的嵌入式Linux系统的基础,该接口模块的主要任务就是完成与外界信息的交互,以达到网络监控的目的。
使用RTL8019作为以太网的物理层接口,它的基本工作原理:是在收到由主机发来的数据报后,从目的地址域到数据域,,侦听网络线路。如果线路忙,就等到线路空闲为止,否则,立即发送数据桢。
RTL8019为台湾芯片生产商Realtek公司第三代快速以太网连接而
设计
领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计
,它支持多种嵌入式处理器芯片,内置FIFO缓存器用于发送和接受数据。
系统硬件电路结构图:
系统工作
流程
快递问题件怎么处理流程河南自建厂房流程下载关于规范招聘需求审批流程制作流程表下载邮件下载流程设计
图:
网络数据的发送流程:
网络数据的接收:
RTL8019工作代码:
//RTL8019.c
#include "GloblDef.h" #include "MMenage.h"
#include "RTL8019.h"
extern BYTE MemAllocation(WORD size); extern void FreePage(BYTE page); extern BYTE xdata *MemPageToPoint(BYTE page);
extern BYTE WriteQueue(BYTE page,struct Queue xdata * pQueue);
BYTE xdata LocalMACAddr[6]={0x52,0x54,0x4c,0x30,0x2e,0x2f};
struct Queue xdata QueueNetPacketIn; BYTE StartPageOfPacket;
/* 接收头文件信息 */
struct RTLReceiveHeader
{
BYTE ReceiveStatus;
BYTE NextPacketStartPage;
BYTE PacketSizeLow;
BYTE PacketSizeHigh;
}Head; Head 须为全局变量.
BYTE xdata Head[4];
/* 上一次传输起始页*/
BYTE LastSendStartPage;
sbit RTLResetPin = RTL_RESET_PIN;
/* 读rtl8019 寄存器端口*/
BYTE ReadReg(WORD port)
{
BYTE xdata * p;
p = (BYTE xdata *)port;
return *p;
}
/* 写寄存器*/
void WriteReg(WORD port,BYTE value) {
BYTE xdata * p;
p = (BYTE xdata *)port;
*p = value;
}
/* 选择寄存器页使用*/
void RTLPage(BYTE Index)
{
/* 设置 CR, CR_TXP 7-6位为 0(为 1 ,包重传) */
BYTE temp;
temp = ReadReg(CR);
temp = temp & 0x3B; /*set 7-6 and 3 bit to 0*/
Index = Index<<6;
temp = temp | Index;
WriteReg(CR,temp);
}
/* PRA 为物理地址 */
void RTLInitial()
{
BYTE temp;
int i;
/* 硬件重启 */
RTLResetPin = 1;
for(i = 0;i<255;i++);
RTLResetPin = 0;
/* 如果硬件重启时延很大, rtl自我初始化 */
for(i=0;i
>8)&0x00ff));
WriteReg(RSARL_WPAGE0,(BYTE)address);
WriteReg(RBCRH_WPAGE0,(BYTE)((size>>8)&0x00ff));
WriteReg(RBCRL_WPAGE0,(BYTE)size);
WriteReg(CR,(0x00 | CR_REMOTE_WRITE | CR_START_COMMAND));
for(i=0;i>8)&0x00ff));
WriteReg(RSARL_WPAGE0,(BYTE)address);
WriteReg(RBCRH_WPAGE0,(BYTE)((size>>8)&0x00ff));
WriteReg(RBCRL_WPAGE0,(BYTE)size);
WriteReg(CR,(0x00 | CR_REMOTE_READ | CR_START_COMMAND));
for(i=0;i MAX_PACKET_SIZE)
return FALSE;
/* 写包到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)((size>>8)&0x00ff)); /*high*/
WriteReg(CR,((PrePage&0xC0) | CR_ABORT_COMPLETE_DMA | CR_TXP |
CR_START_COMMAND));
return TRUE;
}
void RTLReceivePacket()
{
BYTE curr,bnry;
WORD address;
WORD PacketSize;
BYTE MemPage;
struct MemHeader xdata *pMemHead;
RTLPage(1);
curr = ReadReg(CURR_RPAGE1);
RTLPage(0);
/*在接收缓存中读所有包*/
while(TRUE)
{
/* 检验起始页是否未知错误*/
if(StartPageOfPacket >= RECEIVE_STOP_PAGE || StartPageOfPacket <
RECEIVE_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_FOUND)
{
pMemHead = (struct MemHeader xdata *)MemPageToPoint(MemPage);
pMemHead->StartPos = (BYTE xdata *)pMemHead + sizeof(struct MemHeader);
/* pos起始有效地址 */
pMemHead->StopPos = pMemHead->StopPos + PacketSize;
/* 停止pos */
address += 4;
if(StartPageOfPacket > Head[1] && Head[1] != RECEIVE_START_PAGE)
{
RTLReadRam(address,(((WORD)RECEIVE_STOP_PAGE)<<8) - address,pMemHead-
>StartPos); /* 读rtl */
RTLReadRam(((WORD)RECEIVE_START_PAGE)<<8,PacketSize - ((((WORD)RECEIVE_STOP_PAGE)<<8) - address),
pMemHead->StartPos + ((((WORD)RECEIVE_STOP_PAGE)<<8) - address)); /* 读rtl */
}
else
{
RTLReadRam(address,PacketSize,pMemHead->StartPos);
/ * 读rtl */
}
if(WriteQueue(MemPage,&QueueNetPacketIn) == PAGE_NOT_FOUND) /* 写
到对列 */
{
/* 对列满 */
#ifdef DEBUG
printf("\n-------queue full-------");
#endif
FreePage(MemPage);
break;
}
}
else
{
/* 结束 */
#ifdef DEBUG
printf("\n-------mem over-------");
#endif
break;
}
}
/* 得到下一包的起始页 */
StartPageOfPacket = Head[1];
}
/* 重置 bnry */
bnry = StartPageOfPacket - 1;
if(bnry < RECEIVE_START_PAGE)
bnry = RECEIVE_STOP_PAGE - 1;
WriteReg(BNRY_WPAGE0,bnry); }
系统调试代码:
//main.c
void main(void)
{
BYTE temp;
WORD port = 1001;
LocalMACAddr[0]=0x52;
LocalMACAddr[1]=0x54;
LocalMACAddr[2]=0x4c;
LocalMACAddr[3]=0x30;
LocalMACAddr[4]=0x2e;
LocalMACAddr[5]=0x2f;
LocalIPAddress = 0xc0a8020d; /* 本地地址192.168.2.14*/
ServerIPAddress = 0xc0a8020e; /* 目的地址192.168.2.13*/
/*初始化 */
SerialInitial();
MemInitial();
NetInInitial();
RTLInitial();
Start8019();
InterruptInitial();
// 建立一个ARP包
p[0] =0xff;
p[1] =0xff;
p[2] =0xff;
p[3] = 0xff;
p[4] = 0xff;
p[5] = 0xff;
p[6] = 0x52;
p[7] =0x54;
p[8] =0x4c;
p[9] =0x30;
p[10] =0x2e;
p[11] =0x2f;
p[12] = 0x08;
p[13] = 0x06;
p[14] = 0x00;
p[15] = 0x01;
p[16] = 0x08;
p[17] = 0x00;
p[18] = 0x06;
p[19] = 0x04;
p[20] = 0x00;
p[21] = 0x01;
// 发送ARP包
RTLSendPacket(p,60);
while(1);
#ifdef DEBUG
printf("\n-------bigine-------");
#endif
/* 处理 */
TCPBind(port);
if(TCPConnect(ServerIPAddress,1001) == TRUE)
{
while(UserFunc());
}
/* 延时 */
for(temp;temp<255;temp++);
#ifdef DEBUG
printf("\n run over!");
#endif
/* 存储 */
Stop8019();
while(1);
}