为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

NE2000网卡芯片驱动程序

2011-11-15 9页 pdf 248KB 39阅读

用户头像

is_940561

暂无简介

举报
NE2000网卡芯片驱动程序 NE2000网卡芯片驱动程序网卡芯片驱动程序网卡芯片驱动程序网卡芯片驱动程序 巨龙公司系统集成开发部 杨屹 asdjf@163.com 2002/10/20 引言引言引言引言 自从发表 uCOS51移植心得 以来 我收到了很多朋友们的来信 大家对公开源码表 示鼓励 谢谢大家的支持 很多人对于编写自己的操作系统很感兴趣 uCOS51是个不错的 选择 它的优点是简单易懂 学习成本低 有利于向 32 位 CPU 过渡 目前 嵌入式 BBS 上的热点是 嵌入式实时多任务操作系统 单片机上网 32bitC...
NE2000网卡芯片驱动程序
NE2000网卡芯片驱动程序网卡芯片驱动程序网卡芯片驱动程序网卡芯片驱动程序 巨龙公司系统集成开发部 杨屹 asdjf@163.com 2002/10/20 引言引言引言引言 自从发表 uCOS51移植心得 以来 我收到了很多朋友们的来信 大家对公开源码表 示鼓励 谢谢大家的支持 很多人对于编写自己的操作系统很感兴趣 uCOS51是个不错的 选择 它的优点是简单易懂 学习成本低 有利于向 32 位 CPU 过渡 目前 嵌入式 BBS 上的热点是 嵌入式实时多任务操作系统 单片机上网 32bitCPU 如 ARM 等 其实通 过 uCOS51学习完全可以掌握这些热门技术的精髓 而且学习成本低廉 为此我会陆续将我 在研发过程中的经验体会写出来与大家交流 共同进步 我准备讨论以下内容 uCOS51 高效内核 OS 人机界面 SHELL 的编写 51 机开发板 的硬件设计 RTL8019AS网卡驱动程序 51TCP/IP栈设计 应用协议 FTP PPP HTTP SMTP SNMP 在 51上的实现技术 51OS任务划分和应用程序实例 由 51软件系统向 ARM的移植以及其他想到的目 欢迎大家积极参与 注 开发板原理图 PCB图 GAL烧录文件 芯片手册 全部源程序可以来信索取 在整理好后会共享在网上 讨论讨论讨论讨论 3---- RTL8019AS网卡驱动程序网卡驱动程序网卡驱动程序网卡驱动程序 我的 SNMP网管板使用了 RTL8019AS 10M ISA网卡芯片接入以太网 选它的好处是 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的 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的话) 仅此而矣 网卡 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---多播地址匹配 建议 将图形中寄存器名称标注上页号和地址偏移(如 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 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;iibytes.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; //txd packet start; else reg04=0x46; //txd packet start; reg06=length>>8; //high byte counter reg05=length&0xFF; //low byte counter reg00=0x3E; //to sendpacket; } bit recv_packet(union netcard *rxdnet)//ne2000收包子程序 { unsigned char i; unsigned int ii; 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(bnry>0x7F) bnry=0x4C; if(bnry!=curr){ //此时表示有新的数据包在缓冲区里 //读取一包的前 18个字节:4字节的 8019头部,6字节目的地址,6字节原地址,2字节协议 //在任何操作都最好返回 page0 page(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;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.byteb uf[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; //write to bnry return 0; } else{//表示数据包是完好的.读取剩下的数据 if((rxdnet->etherframe.protocal==0x0800)||(rxdnet->etherframe.protocal==0x0806)){ //协议为 IP或 ARP才接收 reg09=bnry; //read page address high reg08=4; //read page address low reg0b=rxdnet->etherframe.length>>8; //read count high reg0a=rxdnet->etherframe.length&0xFF; //read count low; reg00=0x0A; //read dma for(ii=4;iietherframe.length+4;ii++) rxdnet->bytes.bytebuf[ii]=reg10; } bnry=rxdnet->bytes.bytebuf[1]-1;//next page start-1 if(bnry<0x4C) bnry=0x7F; reg03=bnry; //write to bnry return 1; //have new packet } } return 0; } 参考文献 1 老古网站(www.laogu.com) 2 单片机与嵌入式系统应用 2001(7-12)合订本第 228页 以太网控制器的嵌入式设备网 络互连 湖南师范大学 万静华 丁亚军 3 RTL8019AS数据手册
/
本文档为【NE2000网卡芯片驱动程序】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索