工商银行私人银行岗位:嵌入式网络以太网卡驱动程序的实现

来源:百度文库 编辑:中财网 时间:2024/04/29 18:49:41
      摘要


   根据TCP/IP协议分层标准,各种物理接口的驱动程序处于最底层.为上层提供数据的收发服务.其中,以太网卡是最常用的一种物理接口.本文通过对一个实际工程开发的介绍来描述了一种以太网卡驱动程序的实现方法。

关健词:网卡驱动ucleusNetTCP/IP coldfire Am79c961共享存储器(sharedm emory)
                                                                        一.应用背景

某工程用网络化监测系统拓扑结构如图所示:

   其中,监控中心以及监测仪都是以嵌入式的计算机为核心的专用设备,它们通过总线型以太网相连。诸设备统一选用的以太网接口芯片是AMD公司生产的Am79c961型号芯片。由于是嵌入式的计算机,因此硬件设计并不像通用的PC机那样做成网卡再插在系统总线上,而是直接做在嵌入式计算机的主板上。监测仪的嵌入式处理器采用Motorola公司的coldfire系列的MC5206型号芯片。coldfire系列芯片是Motorola公司最近开发的采用RISC技术的高性价比的微控制器家族。

      在各监测仪上,采用的嵌入式操作系统内核是美国Accelerated Technology公司开发的Nucleus Plus内核;采用的嵌入式TCP/IP网络组件是^ccelerated Technology公司开发的Nucleus Net网络组件。在Nucleus Net的下层,是具体的网络接口芯片的驱动程序。由于各种网络接口芯片千差万别,而驱动程序又依赖于具体芯片的技术手册,因此Nucleus Net不可能一一提供其驱动程序,只能由用户根据所使用的具体网络接口芯片,按照Nucleus Net技术手册所提供的驱动程序接口自己编写驱动程序,最后再挂在Nucleus Net上。

            二.有关接口技术的考虑
      

      本应用中,Nucleus Net与网卡驱动程序以及网卡硬件之间的接口关系


                    

1.关于共享存储(shared memory)与总线控制(bus master)


       当存储器与外设进行数据交换时,有两种方式可供选择:共享存储(shared memory)方式
与总线控制(bus master)方式.
       当采用共享存储〔shared memory)方式时,CPU与外设共享一块存储空间,该存储空间由外
设管理.当需要把存储器中的数据向外设发送时,CPU只需要使用数据搬移指令把数据从存储器移向共享存储区即可实现向外设发送数据;同理,当需要把外设产生的数据向存储器传送时,外设只需把产生的数据写入共享存储区,然后使用数据搬移指令把数据从共享存储区移向存储器即可实现外设向存储器传送数据。
      当采用总线控制(bus master)方式时,如果要在存储器与外设之间传送数据,则需使用DMA方式。例如,当外设需要往存储器传送数据时,先要获得对总线的控制权。然后以DMA方式向存储器中写入数据。
       在该项工程中,网络接口芯片Am79c961是工作在共享存储(sharedm emory)方式。


2.关于轮询(Polling)方式和中断(Interrupt)方式


       当驱动程序接收网上的数据时,有两种方式可选择。
       如果选择轮询(Polling)方式,则驱动程序的上层将周期地调用驱动程序中的数据接收函数以接收数据;如果选择中断(Interrupt)方式,则当数据到来后产生中断,在中断处理程序中激活上层的接收任务处理数据。
       Nucleus Net支持两种方式,本驱动程序工作在中断(interrupt)方式。

                                          三.芯片编程的硬件基础        

      在本工程中,网络接口芯片采用的是Advanced Micro Devices(AMD)公司开发的以太网接口芯片Am79c961。由于网卡驱动程序的开发涉及到大量的芯片细节,因此先将驱动程序有关的芯片细节加以介绍.           

1.芯片内部控制寄存器
芯片内部共有两类控制寄存器: 一是控制状态寄存器(corrtrol and status registers,即CSR) ; 二是ISA控制状态寄存器(ISA control and status ragisters,即ISACSR) 。对芯片控制寄存器的访问是通过三个端口实现的:RAP (register address port,寄存器地址口 )、RDP (register data port,寄存器数据口)、IDP(ISACSR register data port , ISACSR寄存器数据口)。其中,RAP指示要访问的CS寄存器或ISACSR寄存器的地址,其I/0偏移地址为0x12;RDP是访问CSR寄存器的端口,其I/0偏移地址为0x10;IDP 是 访 问ISACSR寄存器的端口,其I/0偏移地址为0x16。

2.初始化块(Initialization Block)
初始化块 (Initialization Block)包括芯片初始化时的各种所需信息。芯片初始化以前,初始化块放在:shared memory的首地址处,一旦CSRO的INIT位置I,芯片开始初始化并读入初始化块的内容。当芯片读完初始化块后,将CSRO的IDO N位置I,并且如果允许中断,则将产生中断。下表为初始化块在:share memory中的存储映像。

       其中,IADR即是初始化块的起始地址,芯片用寄存器CSR1 和CSR2来存放IADR。在本工程中,把shared memory的首址作为初始化块的起始地址;MODE说明芯片的一些工作参数.包括是否允许发送、接收,是否重发,是否在发送时产生CRC等;PADR是该网络接口芯片的物理地址;LAD 是逻辑地址过滤器,在本工程中,除了广播地址外,不接收任何逻辑地址,因此内容为全0; RDRA与TDRA分别指明接收描述符环和发送描述符环的起始地址; RLEN与MEN分别指明接收和发送描述符环的长度。
下图说明了初始化块与描述符环的相互关系。

3.描述符环
       描述符环是网络接口芯片用来管理芯片收发数据缓冲区的数据结构。根据芯片技术手册,Am79c981把缓冲区按照一定的大小尺寸分成若干个buffer,每个buffer用于发送或接收一个以太网帧。每个buffer由描述符环中的一项(即一个描述符)加以管理。每个描述符为四个字长,包含管理对应buffer所需的各种信息。芯片与驱动程序都可以访问描述符,但是在访问描述符之前需要取得对描述符的拥有权。

       接收描述符(RMD)为四个字长的控制结构,每个字以RMD0-RMD4表示;发送描述符(TMD)也为四个字长的控制结构,每个字以TMDO-TMD4表示。下面分别说明接收、发送描述符控制结构。

     

        接收描述符 RMD:

                 


       其中,RMD0与RMD1的低八位组成24地址指向接收Buffer的首地址:RMD1的高八位包含8个状态指示位用于表示对应接收Buffer的属性,例如该buffer是属于芯片还是属于驱动程序,buffer中接收到的帧是否有错。如果有错是何种错误等等信息:RDM2的低12位指示对应接收buffer的大小,高4位未用:RMD3的低12位指示buffer中存放的帧大小,高4位未用。

 

        发送描述符TMD:


          


       其中,TMD0与TMD1的低八位组成24地址指向接收Buffer的首地址:TMD1的高八位包含8个状态指示位用于表示对应发送Buffer的属性,例如该buffer是属于芯片还是属于驱动程序,在发送buffer中的帧时有何具体要求等等信息;TMD2的低12位指示对应发送buffer的大小,高4位未用;TMD3 的高6位指示发送buffer帧后的出错状态,低10位用于表示芯片的内部计时器状态,在本驱动程序中并没有使用该项。

                   四.驱动程序框架结构

 

      驱动程序总体上由三部分组成: 初始化部分、发送部分、接收部分。
      1.初始化部分实现对网络接口芯片Am79c961的初始化以及发送、接收时的数据结构的初始化。另外,还要安装低级中断处理程序和高级中断处理程序。

      2.发送部分实现对数据的发送。发送时有两种方式可供选择:立即发送方式(即PACKET方式)、
非立即发送方式(如下图所示)。如果选择PACKET方式,则当上层数据需要发送时将立即发送;如果选择非立发送方式,则当上层数据需发送时只是放入发送队列等待发送。当驱动程序发送完一个数据后,产生一个发送中断,进入中断处理程序后自动到发送队列去取下一个发送数据。

         

       其中,函 数NU_XmitP acket( )实现以太网帧的发送,函数NU_Tranmit( )只有在非立即发送方式下才被调用。在NUJranamito中,首先检查发送队列上是否还有数据需要发送;若有,则调用NUJ(mit Packet ()实现发送。

      3.接收部分实现对网上数据的接收.数据的接收是通过低级中断处理程序与高级中断处理程序 配合完成。其中,低级中断处理程序是真正的硬件中断入口程序。高级中断处理程序 由低级中断处理程序激活。当网络接口芯片Am79c961收到数据后,产生一个接收中断进入低级中断处理程序,经过一些简单处理后激活高级中断处理程序,在高级中断处理程序中再完成对接收数据的搬移。


      AM9 61一ISR低级中断处理程序
      该函数是硬件中断的入口函数,使用系统中断向量表的26号表项。当硬们中断产生后,转向执行AM961—LISR。在函数中,首先把CSR0的寄存器的内容读入ISR—Status数组保存,然后清除CSR0寄存器中的个状态位并关中断,接着做一些简单的清理工作,最后激活高级中断处理程序并清除中断请求位。

 

      NU_Recv_HISR高级中断处理程序
      该函数只能AM961—LISR激活而执行。由硬件产生的中断只有三种类型,分别为:接收
中断、发送中断、出错中断.三种硬件中断使用同一个入口函数,硬件产生中断CSRO,寄存器的内容己由AM961—LISR预先放在中断状态数ISR-status中,NU_Recv_HISR从ISR_Ststus
中读出该状态,然后根据状态判断是哪种中断并做相应的处理。在AM961一LISR与NU_Recv_HISR的相互作用过程中引入了两个数据结构:ISR_Status数组和ISR—Count变量。
  其中,ISR_Stotus数组用于在AM961—L ISR中保存硬件中断产生时CSR0寄存器的内容,
以便在NU_Recv_HISR中根据其内容做相应的处理。ISR—Status数组上有两个指针:读指针
ISR_Read_Idx和写指针ISR_Mrite_Idx。AM961—L ISR只能对写指针进行操作,每当它读入一
个CSR0寄存器状态后,把写指针后移;NURecv_HISR只能对读指针进行操作,每当它从
ISR_Status数组中读出一个CSR0寄存器状态后,把读指针后移。

         过程如下图所示:

 

  另外, 还引入了一个全局变量ISR_Count,初始值为0。.以后每进入一次AM961_LISR则
加1,每进入一次NU_Recv_HISR则减1,ISR_count 实际上表示了已被响应还未被处理的中断个数。


             五.驱动程序的测试实验


1.UDP的实验

  首先做了两点之间的UDP收发实验,其中一台机器运行FTP公司的PC/TCP协议,另一台
运行 由 NucleusN et与所开发的网卡驱动程序相连后的网络协议。当两边的测试程序运行起 来 后 ,可达到80-100Kb ytes/秒的网络速度,误码率在0.5%以下。接下来做了三台机器的实验,其中两台机器为PC/TCP机,且为client方;另一台机器为Nucleus Net机,且为server方。测试实验为:server方与两台client方收发数据。测试程序运行起来后,可达到100K bytes/秒的网络速度,误码率在1%以下。

2. TCP实脸
      实验在两台机器之间进行,一台为PC/TCP机,一台为Nucleus机.Nucleus机先作cIient方,然后作server方。侧试程序运行起来后.可达到IOK bytes/秒的网络速度,误码率在 0. 12 5%以下。