2. 解决问题的理论和方法
图2.1 以太网内部结构 Fig. 2.1 Ethernet internal structure
其核心内容是由三大块寄存器组成:
控制寄存器 -- 控制寄存器提供主控制器和片内以太网控制器逻辑电路之间的主要接口。 写这些寄存器可控制接口操作,而读这些寄存器则允许主控制器监控这些操作。控制寄存器存储空间分为四个存储区,可用ECON1 寄存器中的存储区选择位BSEL1:BSEL0进行选择。 每个存储区都是32 字节长,可以用5 位地址值进行寻址。所有存储区的最后五个单元(1Bh 到1Fh)都指向同一组寄存器:EIE、EIR、ESTAT、ECON2 和ECON1。 它们是控制和监视器件工作的关键寄存器,由于被映射到同一存储空间,因此可以在不切换。
存储区的情况下很方便地访问它们。
以太网缓冲器 -- 以太网缓冲器包含供以太网控制器使用的发送和接收存储器。该缓冲器大小为8 KB,分成单独的接收和发送缓冲空间。 主控制器使用SPI 接口可以对发送和接收存储器的容量和位置进行编程。
PHY 寄存器 -- PHY 寄存器提供PHY 模块的配置和控制功能,以及操作的状态信息。 所有PHY寄存器都为16 位宽。 共有32个PHY 地址单元,但只可使用其中的9 个。对未用单元的写操作无效,而读操作将返回0。所有保留单元应写为0,当读取时其内容被忽略。与ETH、MAC 和MII 控制寄存器或缓冲器不同, PHY寄存器不能通过SPI 控制接口直接访问,而是通过一组带有MIIM (Media Independent Interface for Management)的特殊MAC 控制寄存器来访问的。这些控制寄存器被称为MII 寄存器。
2.3.5. 网卡的功能
网卡上面装有处理器和存储器(包括RAM和ROM)。网卡和局域网之间的通信是通过电缆或双绞线以串行传输方式进行的。而网卡和计算机之间的通信则是通过计算机主板上的I/O总线以并行传输方式进行。因此,网卡的一个重要功能就是要进行串行/并行转换。由于
- 10-
基于嵌入式系统网卡驱动的实现
网络上的数据率和计算机总线上的数据率并不相同,因此在网卡中必须装有对数据进行缓存的存储芯片。
在安装网卡时必须将管理网卡的设备驱动程序安装在计算机的操作系统中。这个驱动程序以后就会告诉网卡,应当从存储器的什么位置上将局域网传送过来的数据块存储下来。网卡还要能够实现以太网协议。
网卡并不是独立的自治单元,因为网卡本身不带电源而是必须使用所插入的计算机的电源,并受该计算机的控制。因此网卡可看成为一个半自治的单元。当网卡收到一个有差错的帧时,它就将这个帧丢弃而不必通知它所插入的计算机。当网卡收到一个正确的帧时,它就使用中断来通知该计算机并交付给协议栈中的网络层。当计算机要发送一个IP数据报时,它就由协议栈向下交给网卡组装成帧后发送到局域网。
随着集成度的不断提高,网卡上的芯片的个数不断的减少,虽然现在个厂家生产的网卡种类繁多,但其功能大同小异。网卡的主要功能有以下三个:
1.数据的封装与解封:发送时将上一层交下来的数据加上首部和尾部,成为以太网的帧。接收时将以太网的帧剥去首部和尾部,然后送交上一层;
2.链路管理:主要是CSMA/CD(Carrier Sense Multiple Access with Collision Detection ,带冲突检测的载波监听多路访问)协议的实现; 3.编码与译码:即曼彻斯特编码与译码。
- 11-
3. 解决问题的一个实例
3. 解决问题的一个实例
3.1. 网卡的硬件架构(MB96338 + ENC28J60)
MB96338控制器[1]是富士通芯片商生产的一款16位处理器的内核,在16位处理器中功能较强,支持USB,I2C,CAN,SPI等通信,但没有内置以太网模块,为了能够实现上网,我们可以外连一个ENC28J60(美国微芯科技公司制造的28引脚独立以太网控制器),它集成MAC 和10 BASE-T PHY。
ENC28J60 由七个主要功能模块组成:
SPI 接口——充当主控制器和ENC28J60 之间通信通道。 控制寄存器——用于控制和监视ENC28J60。 双端口RAM缓冲器——用于接收和发送数据包。
判优器——当DMA、发送和接收模块发出请求时对RAM 缓冲器的访问进行控制。 总线接口——对通过SPI 接收的数据和命令进行解析。
MAC (Medium Access Control)模块——实现符合IEEE 802.3 标准的MAC 逻辑。 PHY(物理层)模块——对双绞线上的模拟数据进行编码和译码。
该器件还包括其他支持模块,诸如振荡器、片内稳压器、电平变换器(提供可以接受5V 电压的I/O 引脚)和系统控制逻辑。
3.2. 底层驱动程序的实现
3.2.1. 概要设计
在TCPIP协议栈中,驱动层主要是传输数据的,数据从一台设备通过网络传输到另一个设备。为TCPIP栈发送,接受数据提供接口。如何实现呢?主要是通过设置网卡中的一些特定的寄存器。对缓冲器,PHY寄存器,MAC寄存器的读和写。内部和外部的接口之间的关系如下:
- 12-
基于嵌入式系统网卡驱动的实现
数据处理InPutOutPutsend_Packetreceive_Packetwrite_ENC28J60_Bufferread_ENC28J60_Bufferwrite_ENC28J60read_ENC28J60write_ENC28J60_cmdset_ENC28J60_Bankread_ENC28J60_cmdSPI_InitENC28J60_Initwrite_ENC28J60_Phy 图3.1 函数接口关系
Fig. 3.1 The relationship between function interfaces
初始化SPI口:设置SPI相关寄存器,使其可以与enc28j60数据传输格式相匹配。 初始化接收缓冲器:在接收数据包前,必须编程ERXST和ERXND指针来对接收缓冲器进行初始化;12所有未被用作接收缓冲器的存储空间都作为发送缓冲器。要发送的数据应写入未使用的空间。但在发送完一个数据包后,硬件会在存储器中数据包最后一个字节后写入一个7字节的状态向量。因此主控制器应在接收缓冲器的开始和每个包之间预留至少7个字节。不需要对发送缓冲器进行特定的初始化。
初始化发送缓冲器:应通过写ERXFCON寄存器使能或禁止相应的接收过滤器。 初始化等待OS:如果在上电复位后立即执行初始化,应查询ESTAT.CLKRDY位,确保在开始修改MAC和PHY寄存器前已经过足够的时间。
初始化MAC:在初始化过程中需要配置一些MAC寄存器。这些寄存器只需配置一次。 初始化PHY:对3个PHY模块寄存器中的位进行配置,已实现不同功能。
读PHY 寄存器
读PHY 寄存器可以获取其完整的16 位值。主要的操作步骤如下:
- 13-
3. 解决问题的一个实例
1. 将要读取的PHY 寄存器的地址写入MIREGADR寄存器;
2. 将MICMD.MIIRD 置1 开始读操作,同时MISTAT.BUSY 位置1。
3. 等待10.24 ?s。查询MISTAT.BUSY 位以确定操作是否完成。 当忙时,主控制器不应开始任何MIISCAN 操作或写MIWRH 寄存器。当MAC 得到寄存器内容时,BUSY 位会自动清零; 4. 将MICMD.MIIRD 位清零;
5. 从MIRDL 和MIRDH 寄存器中读取所需数据。先读哪一个寄存器都可以。
写PHY 寄存器
当写PHY 寄存器时,将一次写入全部的16 位数据,不能对位进行写操作。 如果只需要重新编程寄存器中的某几位,控制器必须首先读PHY 寄存器,修改读到的数据,然后将数据写回PHY 寄存器。主要的操作步骤如下:
1. 将要写入的PHY 寄存器的地址写入MIREGADR寄存器。 2. 将数据的低8 位写入MIWRL 寄存器。
3. 将数据的高8位写入MIWRH寄存器。 对MIWRH寄存器的写操作会自动启动MII 事务,所以必须在写入MIWRL 后才能写入该寄存器。MISTAT.BUSY 位置1。在MII 操作完成后写PHY 寄存器,用时10.24 ?s。当写操作完成后,BUSY 位将自动清零。 在忙时主控制器不应开始MIISCAN 或MIIRD 操作。
读缓冲存储器命令
读缓冲存储器(Read Buffer Memory,RBM)命令允许主控制器从8 KB 发送和接收缓冲存储器中读取字节。如果ECON2 寄存器中的AUTOINC 位置1,那么在读完每个字节的最后一位之后, ERDPT 指针将会自动地递增指向下一个地址。 正常情况下下一个地址为当前地址加1。 然而,如果读取了接收缓冲器中的最后一个字节(ERDPT = ERXND),则ERDPT 指针将转而指向接收缓冲器的起始单元。 这样主控制器可以从接收缓冲器中连续读取数据包,而无须跟踪何时需要折回。当读取地址1FFFh 时, 如果AUTOINC 被置1,且ERXND没有指向该地址时,则读指针将递增并折回到0000h。具体的步骤如下:
1. 将CS 引脚拉为低电平启动RBM 命令;
2. 将RBM 操作码及随后的5 位常量1Ah 发送给ENC28J60;
3. 读出缓冲存储器中的数据,在发送 RBM 命令和常量后,由ERDPT 指向的存储器
中的数据将从SO 引脚移出,首先移出最高位。 如果主控制器继续在SCK 引脚提供时钟信号,而没有拉高CS 的电平,ERDPT 指向的字节将再次从SO 引脚移出,同样首先移出最高位。当AUTOINC 被使能时,使用该方式就可以连续地从缓冲存
- 14-