网络控制器 DM9000A 在嵌入式系统中的应用
1 引言
目前,网络技术在电子产品中的应用越来越广,更多的嵌入式设备需要提供网络接口,以方便与外部互联通讯。现在流行的大多数嵌入式 CPU(如ARM、PPC)都提供了此类接口,但对于一些相对复杂的嵌入式系统来说,可能需要扩展以太网口,以满足网络通讯需要。本文介绍一种新款网络接口芯片 DM9000A,它可以很方便的实现与嵌入式 CPU 的接口,实现扩展以太网口的功能。
2 DM9000A
DM9000A 是中国台湾 DAVICOM 公司推出的一款高速以太网接口芯片。其基本特征是:集成 10/100M 物理层接口;内部带有 16K 字节 SRAM 用作接收发送的 FIFO 缓存;支持 8/16bit 两种主机工作模式;通过 HP 认证的AUTO-Mdix(支持直接互连自动翻转)功能;支持 TCP/IP加速(IPV4 check sum offload)减轻 CPU 负担,提高整机效能;10ns I/O 读写时间。DM9000A 以太网控制器遵循 IEEE 颁布的 802.3 以太网传输协议。该电路还集成了 EEPROM 接口,自举时通过 EEPROM 接口输入到芯片中,从而实现自动初始化。
3 硬件接口设计
DM9000A 可以很方便的与目前主流的嵌入式 CPU 以 8 位或 16 位的总线方式连接,本文设计的系统 CPU 为 AT91RM9200,它是一个采用 ARM 核的 32 位微处理器。二者的接口设计如图 1。
系统上电时,AT91RM9200 通过总线配置 DM9000A内部网络控制寄存器(NCR)、中断寄存器(ISR)等,完成 DM9000A 的初始化。随后,DM9000A 进入数据收发等待状态。当 AT91RM9200 向以太网发送数据时,先将数据打包成 UDP 或 IP 数据包,并通过 16 bit 总线发送到 DM9000A 的数据发送缓存中,然后将数据长度等信息填充到 DM9000A 的相应寄存器内,使能发送。当 DM9000A 接收到外部网络送来的以太网数据时,首先检测数据帧的合法性,如果帧头标志有误或存在 CRC 校验错误,则将该帧数据丢弃。否则将数据帧缓存到内部 RAM,并通过中断标志位通知 AT91RM9200,由 AT91RM9200 对 DM9000A 接收到的数据进行处理。
4 Linux 驱动实现
4.1 Linux 网络驱动体系结构
在 Linux 操作系统中的设备驱动,根据各类外围 I/O 设备的不同,分为三类,即字符设备(如键盘、LCD)驱动、块设备(如硬盘、CF 卡)驱动和网络设备(如网卡)驱动。 Linux 网络设备驱动程序结构上由四部分组成(图 2):网络协议接口,网络设备接口,设备驱动功能层及网络设备介质。
图 2 Linux 网络驱动体系结构
设计开发 Linux 网络驱动程序时,最主要的工作就是完成设备驱动功能层。类似于对字符设备和块设备的处理,为了屏蔽网络环境中物理网络设备的多样性,Linux 利用面向对象的思想对所有的网络物理设备进行抽象,定义了一个统一的接口。对于所有网络硬件的访问都是通过接口进行的,接口向用户提供了一个对于所有类型的网络硬件一致化的操作集合。Linux 内核提供的统一网络设备结构为 net_device,此结构体位于网络驱动层的核心地位。
net_device 中有很多供系访问和协议层调用的设备方法,其中包括:
(1) dev->open:打开设备。open 方法应当注册网络设备需要的任何系统资源(I/O 口,IRQ,DMA 等),打开硬件,进行设备要求的其他设置。
(2) dev—>stop:停止设备。 该函数应当恢复在打开时进行的操作。
(3) dev->hard_start_xmit:发送报文。
(4) dev->tx_timeout:发送超时调用的方法,它应当处理这个问题并恢复报文发送。
(5) dev->set_mac_address:修改网络的硬件 MAC 地址。
网络驱动就是要实现这些具体的设备方法。
4.2 设备初始化
网络的初始化是设备工作的第一步。当系统加载网络驱动模块的时候,就会调用初始化过程。首先利用函数 request_mem_region 映射 DM9000A 的数据、地址端口,通过 dmfe_probe 函数检测网络物理设备是否存在,检测 DM9000A 内部串行 NIC 的值是否正确,然后再对设备进行资源配置,构造设备的 net_device 数据结构。包括一些低层硬件信息:base_addr(网络接口的 I/O 基地址), irq(安排的中断号)等。
4.3 打开设备和关闭设备
open 方法在网络设备被激活时被调用,具体 DM9000A 的硬件初始化工作放到这里来做。对于 DM9000A 需要完成的初始化包括:对 DM9000A 内部上电,软件复位,通过 NCR 寄存器设置网络工作模式,可以选择设置内部或者外部 PHY、全双工或者半双工模式、使能唤醒事件等网络操作,对 RX/TX 中断使能,使能数据接收功能。调用 request_irq() 申请中断号登记中断处理函数,调用 netif_carrier_on 侦测连接状态。
启动定时器,调用 netif_start_queue 激活设备发送队列。
这里对 DM9000A 的中断设计做了一个特殊处理,通常 AT91RM9200 提供最多 32 个中断源,默认提供7个外部中断源,但对于较复杂的嵌入式系统,可能会面临中断源不够用的情况。由于 AT91RM9200 的 PIO 可以实现功能复用,因此,可以把多余的 IO 引脚配置为可用的中断源。故本系统中,设计 DM9000A 中断源与 AT91RM9200 外部 I/O 口 PD8 引脚相连。一个 PIO 端口的 32 个引脚共享一个中断 ID,只需要在中断状态寄存器中区分具体哪个引脚引起中断,然后转向特定的中断处理函数执行操作,就可以实现中断处理。
close 所做的工作和 open 相反,主要释放 open 获得的资源,以减少系统负担。
4.4 数据包发送
数据包的发送和接收是实现 Linux 网络驱动程序中两个最关键的过程,对这两个过程处理的好坏将直接影响到驱动程序的整体运行质量。
暂无评论