wifi驱动的理解(1) | 您所在的位置:网站首页 › wifi软件驱动工程师 › wifi驱动的理解(1) |
在分析WIFI驱动前,分享一下个人对Linux驱动的一些了解,其实纵观Linux众多的设备驱动,几乎都是以总线为载体,所有的数据传输都是基于总线形式的,即使设备没有所谓的总线接口,但是Linux还是会给它添加一条虚拟总线,如platform总线等;介于WIFI的驱动实在是太庞大了,同时又是基于比较复杂的USB总线,所以建议读者在看此文章之前,先了解一下USB设备驱动和网络设备驱动。 我们要看懂WIFI驱动,首先要明白WIFI的工作原理。所以前期有几篇文章都是讲解WIFI的工作原理。从这篇文章开始,我们将进入WIFI的代码世界。对于支持802.11n、802.11ac这些比较新的无线标准的WIFI芯片,其驱动程序也会越来越复杂。那么我们怎么入手去了解及分析它呢? 特别声明:以下文章是以Station的角色去分析WIFI的驱动。 网上很多文章分析Linux设备驱动都是从模块加载入手去分析它的驱动源码。以博主从事Linux设备驱动多年的经验,这确实是一条很直观又非常好的思路。但是这只局限于设备功能少、接口较简单、驱动源码较少的设备驱动。对于功能复杂、驱动源码庞大的设备驱动,根据这条思路,很多开发者可能会无耐心走下去,或者会走向死胡同。 现在我们可以这样来看,从硬件层面上看,WIFI设备与CPU通信是通过USB接口的,与其他WIFI设备之间的通信是通过无线射频(RF)。从软件层面上看,Linux操作系统要管理WIFI设备,那么就要将WIFI设备挂载到USB总线上,通过USB子系统实现管理。而同时为了对接网络,又将WIFI设备封装成一个网络设备。 我们以USB接口的WIFI模块进行分析: (1)从USB总线的角度去看,它是USB设备; (2)从Linux设备的分类上看,它又是网络设备; (3)从WIFI本身的角度去看,它又有自己独特的功能及属性,因此它又是一个私有的设备; 通过上述的分析,我们只要抓住这三条线索深入去分析它的驱动源码,整个WIFI驱动框架就会浮现在你眼前。 1、现在我们先从USB设备开始,要写一个USB设备驱动,那么大致步骤如下: (1)需要针对该设备定义一个USB驱动,对应到代码中即定义一个usb_driver结构体变量。代码如下: struct usb_driver xxx_usb_wifi_driver; (2)填充该设备的usb_driver结构体成员变量。代码如下: static struct usb_driver xxx_usb_wifi_driver = { .name = "XXX_USB_WIFI", .probe= xxx_probe, .disconnect= xxx_disconnect, .suspend= xxx_suspend, .resume= xxx_resume, .id_table= xxx_table, }; (3)将该驱动注册到USB子系统。代码如下: usb_register(&xxx_usb_wifi_driver); 以上步骤只是一个大致的USB驱动框架流程,而最大和最复杂的工作是填充usb_driver结构体成员变量。以上步骤的主要工作是将USB接口的WIFI设备挂载到USB总线上,以便Linux系统在USB总线上就能够找到该设备。 2、接下来是网络设备的线索,网络设备驱动大致步骤如下: (1)定义一个net_device结构体变量ndev。代码如下: struct net_device *ndev; (2)初始化ndev变量并分配内存。代码如下: ndev=alloc_etherdev(); (3)填充ndev -> netdev_ops结构体成员变量。代码如下: static const struct net_device_ops xxx_netdev_ops= { .ndo_init= xxx_ndev_init, .ndo_uninit= xxx _ndev_uninit, .ndo_open= netdev_open, .ndo_stop= netdev_close, .ndo_start_xmit= xxx_xmit_entry, .ndo_set_mac_address= xxx_net_set_mac_address, .ndo_get_stats= xxx_net_get_stats, .ndo_do_ioctl= xxx_ioctl, }; (4)填充ndev->wireless_handlers结构体成员变量,该变量是无线扩展功能。代码如下: ndev->wireless_handlers = (struct iw_handler_def *)&xxx_handlers_def; (5)将ndev设备注册到网络子系统。代码如下: register_netdev(ndev); 3、WIFI设备本身私有的功能及属性,如自身的配置及初始化、建立与用户空间的交互接口、自身功能的实现等。 (1)自身的配置及初始化。代码如下: xxx_read_chip_info(); xxx_chip_configure(); xxx_hal_init(); (2)主要是在proc和sys文件系统上建立与用户空间的交互接口。代码如下: xxx_drv_proc_init(); xxx_ndev_notifier_register(); (3)自身功能的实现,在前面章节上我们已经讲解过WIFI的网络及接入原理,如扫描等。同时由于WIFI在移动设备中,相对功耗比较大,因此,对于功耗、电源管理也会在驱动中体现。 本文章只是博主结合自身工作经验分享一个大致的对wifi驱动框架的理解,后期文章将会细化这些内容。敬请读者期待,谢谢! 转载请注明出处:http://blog.csdn.net/Righthek 谢谢! |
CopyRight 2018-2019 实验室设备网 版权所有 |