The Design and Implementation of Wireless Network Card Driver in eCos
Abstract:This paper analyses the architecture of wireless network interface card driver in eCos, and provides the method to design it. The paper concretely studies porting wireless configuration tools of linux 2.6 kernel to eCos, which extends the wireless function in eCos.
Key words:eCos, WLAN driver, wireless extensions
摘要:本文详细介绍了 eCos下无线网卡驱动程序的体系结构及其设计方法,并将 linux2.6内核所提供的无线配置工具移植到 eCos下,扩展了 eCos下的无线配置管理功能。
关键词:嵌入式可配置操作系统;无线网卡驱动;无线扩展工具
一、引言系统启动时,初始化函数 wlan_eth_init()被调用,其主要功能是初始化硬件。实现的步骤包括:判断硬件是否正常工作;向系统注册网卡设备;初始化无线网卡的相关寄存器,收发数据包的缓冲区等;为上层协议栈分配内存。实现的伪代码如下:
static int wlan_eth_init(struct cyg_netdevtab_entry *tab)
{
cyg_pci_init(); /* 初始化PCI 总线 */
/*扫描总线上的PCI 设备,并将扫描到的设备存入devid 中 */
if (cyg_pci_find_next(CYG_PCI_NULL_DEVID, &devid)){
do {
cyg_pci_get_device_info(devid, &dev_info); /*查询当前设备信息,并存入dev_info*/
cyg_pci_translate_interrupt(&dev_info,&priv->irq) /*为网卡申请中断号,存入irq*/
if (cyg_pci_configure_device(&dev_info)) { /*为网卡分配内存和I/O 地址空间*/
} while (cyg_pci_find_next(devid, &devid)); }
cyg_drv_interrupt_create(…………… ); /*将中断号映射到相应的中断处理函数*/
cyg_drv_interrupt_attach(priv->interrupt_handle);
cyg_drv_interrupt_unmask(priv->irq); /*打开中断*/
……………………….. /*为上层802.11 协议栈分配内存*/
wlan_priv_data_init(priv); /*初始化网卡设备相关寄存器*/
sc->wireless_handlers=&wlan_iw_handler; /*实现无线配置函数*/
}
3.2驱动的接口函数:
网卡成功注册后,系统内核即可调用网卡驱动程序中相应的函数,实现数据包的发送和接收过程。在 eCos中,通过下面的宏实现各函数与内核的关联:
ETH_DRV_SC(
wlan_src, /*专用底层驱动函数接口名*/
&wlan _pri_data, /*网卡驱动私有数据结构*/
DRIVER_IF_NAME, /*网卡接口名*/
wlan_eth_start, /*系统初始化后被调用,打开网卡接口,允许网卡收发数据*/
wlan_eth_stop, /*关闭网卡,禁止收发数据*/
wlan_eth_control, /*实现对网卡接口的控制*/
wlan_eth_can_send, /*判断网卡接口状态,忙或空闲*/
wlan_eth_send, /*此函数实现发送数据过程*/
wlan_eth_recv, /*此函数实现接收数据过程*/
wlan_eth_deliver, /*与wlan_eth_dsr()函数结合实现需要花大量时间的数据搬移过程*/
wlan_eth_poll, /*此函数用于不能使用中断的驱动中以查询的方式去收发网卡数据*/
wlan_eth_int_vector /*返回中断向量号*/
);
通过实现上面的函数,我们的驱动程序就能实现收发数据的过程了。其中,各个函数在驱动程序中的关系及与上层的通信流程如图1所示,具体应用时,收发包流程如下:
发送流程:网卡初始化并启动后,由上层协议栈首先调用 can_send()函数确定网卡是否可以发送数据,驱动也可以从 can_send()函数的参数中知道将要发送的数据包数量并作相应处理。如果发送队列未满,返回“否”,上层协议栈将等待;如果发送队列已满,则调用 send()函数,send()函数将接受要发送的数据,处理后写入网卡的发送队列。
接收流程和中断处理流程:网卡初始化并启动后,网卡的接收中断已经打开。当中断到来时,中断服务程序 ISR将被调用, ISR主要负责确定接收是否成功以及对硬件装备中断信号的响应和清除。如果接收失败,程序立刻返回不作任何处理;如果接收成功,则调用 DSR中断服务函数(滞后中断服务函数)。在 DSR中断服务函数中,程序已不占操作体系中的核调度资源,因而 DSR函数与 deliver()函数执行了需要花费大量时间的数据搬移工作,此时接受到的数据处理后将被复制到 sg_list的上层链表中,并通知上层有数据已被接收。
此外,poll()函数主要是应用于不能使用中断时以查询的方式去接收和发送网卡数据,我们没有实现这个函数。
3.3对 eCos的无线配置扩充: 由于 Linux 2.6 内核中的无线扩展( Wireless Extensions)已经提供了对 WLAN设备的支持,为了减小工作量,我们将其移植到 eCos上。Linux的无线扩展的作用是对 WLAN设备的 IEEE 802.11 MAC协议栈管理,分为内核部分和应用程序部分。应用程序部分即无线扩展的工具集,无线扩展的工具集的移植主要做的就是把入口函数的形式改变。 eCos内核对其网络设备驱动支持 IOCTL,但只支持有限的一些,不能任意扩充。为了满足对管理 MAC的需要,我们扩充了其对 IOCTL的支持,使其支持更多的 IOCTL。仿照 Linux,我们添加的 IOCTL分为通用 IOCTL和私有 IOCTL,通用 IOCTL的输入和输出已经被约定了,不能更改和扩充,譬如,设置速率的 IOCTL,私有 IOCTL的输入和输出可以按需要定制,要在内核和工具集之间统一传递的数据的格式。由于应用层移植 Linux的工具集并作较少的改变,在内核里需要适合工具集传来的数据的格式。无线扩展工具调用 IOCTL时使用 ioctl(int skfd, int request, struct iwreq * pwrq) 这样的形式,而驱动的 IOCTL处理函数的形式要定义成 int wlan_io_ctrl_set_txpower(eth_drv *ndev, struct iw_request_info *info, struct iw_param*wrqu, char *extra)这样的形式,因此,对 eCos的内核里要判断是通用 IOCTL还是私有 IOCTL,提取并传递相应的参数。这些数据结构的转换在 Linux的源码 include/net/iw_handler.h和 include/linux/wireless.h 文件里,必须把它们移植到 eCos下。 在 eCos内核中的 eth_drv_sc结构中增加一个 structure iw_handler_def wireless_handlers结构,从中能够找到我们定义的 IOCTL函数指针,驱动在初始化时需要填充这个结构并把结构的指针赋值给 wireless_handlers,以此传递 IOCTL函数的函数指针。 修改 eCos的内核文件 packages/io/eth/v2_0/src/net/eth_drv.c中的 eth_drv_ioctl函数,使遇到不支持的 IOCTL码时到 iw_handler_def结构里去查找对应的 IOCTL处理函数,如果存在,则调用对应的 IOCTL处理函数;如果不存在,则继续原来的处理流程。在被调用的 IOCTL处理函数被调用返回后,如果需要在内核和用户层传递数据,则要做上面提到的数据结构的转换并完成数据传递。
四、总结
本文的创新点在于:由于 eCos下并没有提供无线网卡驱动模型,本文在设计时利用 eCos下原有的以太网驱动模型接口函数,在此基础上实现无线网卡设备的驱动程序,并将 Linux下的无线扩展工具移植到 eCos下,扩充了 eCos对无线网卡设备的管理功能,实现了无线局域网设备的通信功能。此外,本论文介绍了 eCos操作系统的优点,并详细介绍了在 eCos下设计无线网卡驱动程序的实现方法。根据 eCos越来越受欢迎以及无线局域网的快速发展趋势表明,本文所总结的 eCos下的无线网卡驱动程序的实现方法对嵌入式开发人员将具有正确及重要的指导参考意义。
五、参考文献
[1]秦怀峰,施笑安,周兴社,谷建华 . eCos 设备驱动程序设计分析 [J].微电子学与计算机,2003, 7.
[2]赵楚莹,尹俊勋,梁伟豪 . ECOS嵌入式系统的S3C2510 以太网驱动程序设计[J].微计算机信息,2006, 4-2:
[3] eCos Reference Manual. Red Hat Inc,2000.
[4] Alessandro Rubini,Jonathan Corbet . Linux设备驱动程序 (第三版)[M]. 中国电力出版社,2002.
作者简介:李伟,女, 1984年生,四川人,北京邮电大学电子工程学院 2006级硕士研究生,主要研究方向为智能通信。
邓中亮,男, 1965年生,北京邮电大学电子工程学院,教授,博士生导师,主要研究方向为通信系统与终端。 Biography:
Li Wei (1984~),female, born in Sichuan, graduate student of grade 2006 in School of Electronic Engineering, Beijing University of Post and Telecommunication, majoring in intelligent communication.
Deng Zhongliang (1965~),male, born in Hunan, doctor adviser in School of Electronic Engineering, Beijing University of Post and Telecommunication, researching on communication systems and terminals. 注:学校图书馆已经订阅贵刊。