1、NE2000网卡芯片驱动程序网卡芯片驱动程序网卡芯片驱动程序网卡芯片驱动程序 巨龙公司系统集成开发部 杨屹 2002/10/20 引言引言引言引言 自从发表uCOS51移植心得以来我收到了很多朋友们的来信大家对公开源码表示鼓励谢谢大家的支持很多人对于编写自己的操作系统很感兴趣uCOS51是个不错的选择它的优点是简单易懂学习成本低有利于向32位CPU过渡目前嵌入式BBS上的热点是嵌入式实时多任务操作系统单片机上网32bitCPU如ARM等其实通过uCOS51学习完全可以掌握这些热门技术的精髓而且学习成本低廉为此我会陆续将我在研发过程中的经验体会写出来与大家交流共同进步 我准备讨论以下内容uCO
2、S51高效内核OS人机界面SHELL的编写51机开发板的硬件设计RTL8019AS网卡驱动程序51TCP/IP协议栈设计应用协议FTP PPP HTTPSMTP SNMP在51上的实现技术51OS任务划分和应用程序实例由51软件系统向ARM的移植以及其他想到的题目欢迎大家积极参与 注开发板原理图PCB图GAL烧录文件芯片手册全部源程序可以来信索取在整理好后会共享在网上 讨论讨论讨论讨论3- RTL8019AS网卡驱动程序网卡驱动程序网卡驱动程序网卡驱动程序 我的SNMP网管板使用了RTL8019AS 10M ISA网卡芯片接入以太网选它的好处是NE2000兼容软件移植性好接口简单不用转换芯片如
3、PCI-ISA桥价格便宜2.1$/片(我的购入价为22元RMB/片)带宽充裕(针对51)较长一段时间内不会停产8019有3种配置模式跳线方式即插即用P /接收状态 unsigned char nextpage; /下一个页 unsigned int length; /以太网长度以字节为单位 unsigned int destnodeid3; /目的网卡地址 unsigned int sourcenodeid3; /源网卡地址 unsigned int protocal; /下一层协议 unsigned char packet1500; /包的内容 ; void ne2000init()/ne2
4、000网卡初始化 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页 re
5、g01=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 reg09=0x41; /MAR1 reg0a=0x00; /MAR2 reg0b=0x80; /MAR3 reg0c
6、=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字节,最
7、大1514字节需要发送的数据包要先存放在txdnet缓冲区 unsigned char i; unsigned int ii; page(0); if(lengthetherframe.sourcenodeidi=my_ethernet_address.wordsi; txd_buffer_select=!txd_buffer_select; if(txd_buffer_select) reg09=0x40 ; /txdwrite highaddress else reg09=0x46 ; /txdwrite highaddress reg08=0x00; /read page address
8、 low reg0b=length8; /read count high reg0a=length /read count low; reg00=0x12; /write dma, page0 for(ii=4;iibytes.bytebufii; for(i=0;i8; /high byte counter reg05=length /low byte counter reg00=0x3E; /to sendpacket; bit recv_packet(union netcard *rxdnet)/ne2000收包子程序 unsigned char i; unsigned int ii;
9、unsigned char bnry,curr; page(0); reg07=0xFF; bnry=reg03; /bnry page have read 读页指针 page(1); curr=reg07; /curr writepoint 8019写页指针 page(0); if(curr=0) return 0; /读的过程出错 bnry=bnry+; if(bnry0x7F) bnry=0x4C; if(bnry!=curr) /此时表示有新的数据包在缓冲区里 /读取一包的前18个字节:4字节的8019头部,6字节目的地址,6字节原地址,2字节协议 /在任何操作都最好返回page0 p
10、age(0); reg09=bnry; /read page address high reg08=0x00; /read page address low reg0b=0x00; /read count high reg0a=18; /read count low; reg00=0x0A; /read dma for(i=0;ibytes.bytebufi=reg10; i=rxdnet-bytes.bytebuf3; /将长度字段的高低字节掉转 rxdnet-bytes.bytebuf3=rxdnet-bytes.bytebuf2; rxdnet-bytes.bytebuf2=i; rxd
11、net-etherframe.length=rxdnet-etherframe.length-4; /去掉4个字节的CRC /表示读入的数据包有效 if(rxdnet-bytes.bytebuf0 curr=reg07; /page1 page(0); /切换回page0 bnry=curr-1; if(bnryetherframe.protocal=0x0800)|(rxdnet-etherframe.protocal=0x0806) /协议为IP或ARP才接收 reg09=bnry; /read page address high reg08=4; /read page address l
12、ow reg0b=rxdnet-etherframe.length8; /read count high reg0a=rxdnet-etherframe.length /read count low; reg00=0x0A; /read dma for(ii=4;iietherframe.length+4;ii+) rxdnet-bytes.bytebufii=reg10; bnry=rxdnet-bytes.bytebuf1-1;/next page start-1 if(bnry0x4C) bnry=0x7F; reg03=bnry; /write to bnry return 1; /have new packet return 0; 参考文献 1老古网站() 2单片机与嵌入式系统应用2001(7-12)合订本第228页以太网控制器的嵌入式设备网络互连湖南师范大学 万静华 丁亚军 3 RTL8019AS数据手册