基于S3C2440平台的USB_WiFi驱动移植
扫描二维码
随时随地手机看文章
引 言
随着科技的进步,基于 802.11 系列协议的WiFi 无线保真通信技术迅猛发展,使得WiFi 技术能够应用在多种不同的嵌入式设备上,并方便的连接运营商提供的接入点。WiFi 与其他无线通信技术相比,拥有组网灵活,数据传输速度快,传输距离远的特性。在已部署WiFi 网络的范围内搭建WSN 网络非常灵活而且组网成本不高。
1 WiFi技术和平台介绍
1.1 硬件平台总体设计
如图 1 所示, 能达到本文需求的无线传输系统由S3C2440 控制器、WiFi 无线网卡和上位机组成。测试系统将输入的数据传输给中心处理芯片S3C2440,S3C2440 将得到的数据储存到存储器,并对数据进行处理,然后由USB 接口将封装的数据通过WiFi 网络建立起的无线通信链路,传送到远端上位机。
1.2 USB 接口电路设计
S3C2440 处理器通过USB 接口与Atheros AR9271 无线网卡的USB 接口连接,实现数据的传输和接收。其中,数据的发送端是S3C2440。针对设备对系统资源需求的不同,在USB 规范中规定了4 种不同的数据传输方式, 这里使用实时传输方式。这种传输方式可以连续不断地在 S3C2440 与USB 设备之间传输数据。S3C2440 的DN0、DP0 引脚分别与AR9271 的 DM、DP 引脚相连接 ;DN 与 DP 输出的是一对差 分信号。
2 WiFi 驱动程序移植
2.1 WiFi 驱动体系结构
AR9271无线网卡正常工作所需要的驱动程序主要包括两 部分 :WLAN 驱动和 USB 接口驱动。WLAN 驱动的作用在 整个数据接收和传输的过程中非常重要,它既要接收从应用 层传来的数据,把数据从USB 接口转发到 S3C2440 平台 ;又 要响应 S3C2440 平台传过来的中断,借助 USB 驱动程序注册 的接口函数,读取硬件缓冲区的数据流,传递数据到应用层。 内核启动后,会自动加载 AR9271 的固件 htc_9271.fw,它在 S3C2440 平台根文件系统的 /lib/firmware 目录下。它的主要作 用是控制 WiFi 硬件上的接口,完成 802.11 数据帧和 802.3 数 据帧之间的转换和实现数据缓冲。由此可见,WiFi 无线网卡 设备在 Linux 中是被当作一般的以太网设备来识别。
2.2 USB 接口驱动分析
USB 接口初始化函数由 ath9k_hif_usb_init 入口,ath9k_ hif_usb_exit 出口。ath9k_hif_usb_init 所做的工作,就是通过 usb_register 函数将 ath9k_hif_usb 驱动挂入到内核 USB 驱动 链中。
ath9k_hif_usb_probe 函数是最重要的,主要用于设备的 探测以及所需内核资源的初始化。ath9k_hif_usb_suspend 和 ath9k_hif_usb_resume 主要是处理电源管理相关工作,如收到 suspend 时以怎样的低功耗工作,以及 resume 如何恢复等。
ath9k_hif_usb_disconnect 是当 USB 设备从系统中移除 之后会调用的接口。rtusb_usb_id 是驱动支持的 USB 设备 ID。
ath9k_hif_usb_driver 结构体初始化时向内核注册完之 后,驱动就会扫描 USB 总线,查找是否有此驱动相应的设备 在总线上,如果有设备,就会调用 probe 函数 ;或者驱动初始化后,再把设备插到系统上,此时也会从USB 总线的中断触 发到 ath9k_hif_usb_driver 的 probe 函数。两种调用的触发方 式不同。
2.3 无线网卡驱动分析
2.3.1 Probe 函数分析
ath9k_hif_usb_driver 中的 probe 函数作用是测试当前驱 动是否支持接入的 USB 设备。如果支持该 USB 设备,则调用 interface_to_usbdev()函数先获取该接口的信息,再让 udev 结构体指针指向这段信息,使用 kzalloc()函数为该 USB 设 备分配空间,用 hif_device_usb *hif_dev 指针接收。然后把设 备信息、接口信息、设备 ID 赋值给分配的 USB 设备
hif_dev->udev = udev ;
hif_dev->interface = interface ;
hif_dev->usb_device_id = id ;
接 着 probe 函 数 调 用 usb_set_intfdata(struct usb_ interface *intf,void *data)函数,这个函数的第一个参数是 通过 probe 函数接收的要支持 USB 设备接口的数据结构的 指针,第二个参数是内核中自己分配的描述该 USB 设备的结 构体指针。 这个函数主要的作用是把接口和本驱动要用到的 USB 设备结构体建立连接。通过 probe(struct usb_interface *interface,const struct usb_device_id *id)函数和上面一系列 的分析我们可以看出来,一个设备对应一个驱动。
在这一系列工作完成后,通过 init_completion(&hif_ dev->fw_done)函数把它放入等待队列,等待加载与之相对应 的固件。
2.3.2 数据的传输
USB 无线网卡与其它接口无线网卡不一样的地方是, USB 无线网卡是 ath9k_hif_usb_rx_cb()函数通过查询来确 定是否需要读取数据,而不是使用中断方式。当 USB 设备需 要传输数据给其它无线设备时,ath9k_hif_usb_alloc_rx_urbs() 函数会分配一个 URB 结构体,然后由 ath9k_hif_usb_rx_cb() 函数向 USB 核心发送一个读请求,以便它能够及时响应。当 准备发送数据时,802.11 协议层会构造并填充 kb_buff 结构体 来描述将要发送的数据包,并调用 hif_usb_send()函数来发 送该数据包 ;这个函数的另一个作用是根据数据包的长度把 它分割成 USB 设备能够传输的长度,然后构造写请求 URB, 再发送到 USB 核心,当 USB 设备从系统中移除后,就会调用 ath9k_hif_usb_disconnect()函数,释放已经分配的系统资源, 注销该设备。
3 结 语
作为目前无线网络应用最广泛的技术,在 S3C2440 平台 上 WiFi 驱动的移植非常具有实际意义。本文分析移植了基于 Linux 系统的 USB 接口 WiFi 驱动程序的具体过程,且测试可 用。这为其他的嵌入式平台 WiFi 驱动提供了参考。