【智能家居篇】wifi驱动的理解(2)

转载请注明出处:http://blog.csdn.net/Righthek 谢谢!

上一篇文章我们已经通过三条线索简单地描述了wifi驱动的框架,现在我们开始深入到每条线索中。首先我们从USB设备这条线索开始。在分析之前,我们需要理解在整个wifi模块中,USB充当什么角色?它的作用是什么?实质上wifi模块上的数据传输有两端,一端是wifi芯片与wifi芯片之间,通过无线射频(RF)进行数据传输;另一端则是wifi芯片与CPU之间,通过USB进行数据传输。

了解Linux的USB驱动的读者都知道,USB驱动分为两种:一种是USB主机驱动;另一种是USB设备驱动。而我们的USB接口的wifi模块对于CPU(主机)来说,属于USB设备,因此采用USB设备驱动。

有了以上信息之后,我们先让Linux系统识别该USB接口的wifi模块,首先我们在驱动源码中大致添加以下几步工作:

(1)定义一个usb_driver结构体变量:

structusb_driver xxx_usb_wifi_driver;

(2)填充该设备的usb_driver结构体成员变量:

staticstruct usb_driver xxx_usb_wifi_driver = {

.name =             "XXX_USB_WIFI",

.probe =   xxx_init_wifi,

.disconnect =   xxx_remove,

.suspend =        xxx_suspend,

.resume =         xxx_resume,

.id_table=        xxx_table,

};

(3)将该驱动注册到USB子系统:

usb_register(&xxx_usb_wifi_driver);

简单完成以上几步工作,再加上板级文件(arch/mach-xxx.c)对USB设备的支持,Linux的USB子系统几乎可以挂载该wifi模块为USB设备了。但是这并不是我们最终想要的结果。我们还要让Linux系统知道它挂载的USB设备属于无线网络设备,同时能够访问它,利用它实施无线网络的工作。

我们都知道,若要让USB设备真正工作起来,需要对USB设备的4个层次(设备、配置、接口、端点)进行初始化。当然这四个层次并不是一定都要进行初始化,而是根据你的USB设备的功能进行选择的,大致初始化流程如下伪代码:

static structdvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)

{

int    i;

u8     val8;

int    status= _FAIL;

structdvobj_priv *pdvobjpriv;

//设备

structusb_device                                *pusbd;

structusb_device_descriptor         *pdev_desc;

//配置

structusb_host_config                      *phost_conf;

structusb_config_descriptor           *pconf_desc;

//接口

structusb_host_interface                *phost_iface;

structusb_interface_descriptor     *piface_desc;

//端点

structusb_host_endpoint                 *phost_endp;

struct usb_endpoint_descriptor      *pendp_desc;

//设备的初始化

pdvobjpriv->pusbintf = usb_intf ;

pusbd =pdvobjpriv->pusbdev = interface_to_usbdev(usb_intf);

usb_set_intfdata(usb_intf, pdvobjpriv);

pdev_desc =&pusbd->descriptor;

//配置的初始化

phost_conf =pusbd->actconfig;

pconf_desc =&phost_conf->desc;

//接口的初始化

phost_iface =&usb_intf->altsetting[0];

piface_desc =&phost_iface->desc;

端点的初始化,由于wifi模块属于网络设备,传输批量数据,因此需要初始化为批量端点,端点方向(输入、输出)等。同时,由于wifi驱动功能比较多,需要初始化几个输入输出端点。

for (i = 0; i <pdvobjpriv->nr_endpoint; i++)

{

phost_endp = phost_iface->endpoint +i;

if (phost_endp)

{

pendp_desc =&phost_endp->desc;

//检查是否为输入端点

usb_endpoint_is_bulk_in(pendp_desc);

//检查是否为输出端点

usb_endpoint_is_bulk_out(pendp_desc);

}

}

usb_get_dev(pusbd);

}

完成以上的初始化工作之后,接下来我们需要理清一下USB接口的作用,它是wifi芯片内部的固件程序与主机上的Linux系统进行数据通信。USB设备通信不像普通字符设备那样采用I/O内存和I/O端口的访问,而是采用一种称为URB(USB Request Block)的USB请求块,URB在整个USB子系统中,相当于通电设备中的“电波”,USB主机与设备的通信,通过“电波”来传递。下面我们就来编写USB接口的读写操作函数,伪代码如下:

voidxxx_wifi_usb_intf_ops(struct _io_ops     *pops)

{

//当需要进行简单数据的读取时,采用以下操作

pops->_read8 = &usb_read8;

pops->_read16 = &usb_read16;

pops->_read32 = &usb_read32;

//当需要进行批量数据的读取时,采用以下操作

pops->_read_port = &usb_read_port;

//当需要进行简单数据的写时,采用以下操作

pops->_write8 = &usb_write8;

pops->_write16 = &usb_write16;

pops->_write32 = &usb_write32;

pops->_writeN = &usb_writeN;

//当需要进行批量数据的写时,采用以下操作

pops->_write_port = &usb_write_port;

//取消读写urb

pops->_read_port_cancel = &usb_read_port_cancel;

pops->_write_port_cancel = &usb_write_port_cancel;

}

在进行批量数据的读写时,如usb_read_port()和usb_write_port()函数,需要完成urb创建、初始化、提交、完成处理这个完整的流程。伪代码如下:

(1)批量读操作

static u32usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)

{

int err;

unsigned intpipe;

PURB purb =NULL;

structrecv_buf         *precvbuf = (structrecv_buf *)rmem;

structusb_device    *pusbd = pdvobj->pusbdev;

//创建urb,这里是在其它地方创建完成之后,传递过来

purb =precvbuf->purb;

//初始化批量urb

usb_fill_bulk_urb(purb, pusbd, pipe,

precvbuf->pbuf,

MAX_RECVBUF_SZ,

usb_read_port_complete,

precvbuf);//contextis precvbuf

//提交urb

err =usb_submit_urb(purb, GFP_ATOMIC);

}

(2)批量写操作

u32usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)

{

unsigned int pipe;

intstatus;

PURB        purb = NULL;

structxmit_priv       *pxmitpriv =&padapter->xmitpriv;

structxmit_buf *pxmitbuf = (struct xmit_buf *)wmem;

structxmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data;

structusb_device *pusbd = pdvobj->pusbdev;

structpkt_attrib *pattrib = &pxmitframe->attrib;

//创建urb,这里是在其它地方创建完成之后,传递过来

purb = pxmitbuf->pxmit_urb[0];

//初始化批量urb

usb_fill_bulk_urb(purb, pusbd, pipe,

pxmitframe->buf_addr,//= pxmitbuf->pbuf

cnt,

usb_write_port_complete,

pxmitbuf);//contextis pxmitbuf

//提交urb

status = usb_submit_urb(purb,GFP_ATOMIC);

return ret;

}

完成以上批量数据的读写操作之后,大家可能会疑问:这不是一般USB设备驱动的操作流程吗?貌似和wifi没有半毛钱的关系啊!

从这篇文章上看,确实和wifi没有任何联系,但是以上只是一个铺垫。我们一直强调USB接口在wifi模块中充当什么角色,既然是接口,那么它就是为数据传输而生。所以,和wifi扯上关系的就在于usb_read_port()和usb_write_port()这两个函数。

读者可结合USB设备驱动和网络设备驱动细心思考,它们之间是如何联系上的?

鉴于文章篇幅有限,以上问题将在下篇文章进行详细讲解,敬请期待!

转载请注明出处:http://blog.csdn.net/Righthek 谢谢!

时间: 2024-10-27 14:02:44

【智能家居篇】wifi驱动的理解(2)的相关文章

【智能家居篇】嵌入式WIFI与普通WIFI的区别

转载请注明出处:http://blog.csdn.net/Righthek 谢谢! 既然我们这系列的文章名称为<智能家居篇>,那么我们有必要提出一个与智能家居相关的概念.曾经一次在TI的无线研讨会上,提及这个概念.究竟是TI提出的,还是其他无线厂家提出的,这个就不去深究了.这个概念就是嵌入式WIFI,也有叫WIFI的IoT(全称:Internet of Things)解决方案,那么它和普通的WIFI又有什么区别呢?请继续阅读下文.         1.嵌入式WIFI的来源 我们都知道笔记本.手

【智能家居篇】通信技术简介

转载请注明出处:http://blog.csdn.net/Righthek 谢谢! 在这个巴西世界杯火爆进行的炎热夏天,能够静下心来写一篇技术性的文章,不容易.2014年科技领域最备受关注之一的莫过于智能家居了.从年初的国际消费电子展(CES)的其中一大看点智能家居,到苹果发布智能家居平台homekit.世界各个科技公司都相继推出自己的智能家居产品. 什么是智能家居呢? 好吧,概念性的东西,我们在谷歌上百度一下吧! 智能家居是以住宅为平台,利用综合布线技术.网络通信技术.安全防范技术.自动控制技

【智能家居篇】wifi驱动的理解(1)——驱动架构

转载请注明出处:http://blog.csdn.net/Righthek 谢谢! 在分析WIFI驱动前,分享一下个人对Linux驱动的一些了解,其实纵观Linux众多的设备驱动,几乎都是以总线为载体,所有的数据传输都是基于总线形式的,即使设备没有所谓的总线接口,但是Linux还是会给它添加一条虚拟总线,如platform总线等:介于WIFI的驱动实在是太庞大了,同时又是基于比较复杂的USB总线,所以建议读者在看此文章之前,先了解一下USB设备驱动和网络设备驱动. 我们要看懂WIFI驱动,首先要

【智能家居篇】wifi网络结构(上)

转载请注明出处:http://blog.csdn.net/Righthek 谢谢! WIFI是什么,相信大家都知道,这里就不作说明了.我们需要做的是深入了解其工作原理,包括软硬件.网络结构等.先说明一下WIFI是遵循IEEE802.11协议的,802.11是最早被国际标准组织认可的无线局域网协议,应该是1999年,到现在都有15年了.那时候哥还在读小学,连电脑都没摸过!太落后了...后来发展出很多以字母为后缀的802.11标准协议,如a.b.g.n.ac等. 本章节不作802.11协议的讲解,后

【智能家居篇】wifi在智能家居中的应用

转载请注明出处:http://blog.csdn.net/Righthek 谢谢! 在设计智能家居系统方案时,一个非常关键的point就是组网方式.组网方式关系到整个智能家居系统的稳定性.可扩展性.实时性等:从安装及维护等各方面考虑,对于组网方式,本人觉得现在应该没人会去搭建一个有线的智能家居网络了吧,呵呵...... 所以,我们毫无疑问选择了无线的组网方式! 无线组网方式有很多种,有采用Zigbee.Wifi.Z-wave等等,当然一个完整的智能家居系统不可能只采用单纯的一种无线通信方式进行组

智能家居常用WiFi模块

WiFi模块 WiFi模块就是整个系统的控制中心,控制很简单,就是输出一个开关信号控制继电器,而这个模块的核心是WiFi的连接,手机连接WiFi时需要扫描,输入密码,而这类本身没有屏幕和键盘的硬件设备,要想快捷的接入WiFi网络就需要更加便捷的连接方案,这就是这些模块厂家的主要工作了,所以这些模块都提供类似的连接方案,即手机APP扫描WiFi,在APP上输入对应WiFi的连接密码后自动由APP发送到模块,完成模块和WiFi的连接,本质上是一样的,只是叫的名字不同而已,有的叫SimpleLink有

【智能家居篇】wifi驱动的理解(3)——usb接口在wifi模块中的角色

转载请注明出处:http://blog.csdn.net/Righthek 谢谢! 上一篇文章已经提到USB接口在wifi模块中的最重要两个函数是usb_read_port()和usb_write_port().那它们是怎么和wifi扯上关系的呢?我们可以从以下三个方面去分析: 1.首先需要明确wifi模块是USB设备,主控(CPU)端是USB主机: 2.USB主机若需要对wifi模块进行数据的读写时,就必须经过USB接口: 3.既然涉及到数据的读写操作,必然要用相应的读写函数,那么usb_re

【智能家居篇】wifi网络接入原理(上)——扫描Scanning

转载请注明出处:http://blog.csdn.net/Righthek 谢谢! 对于低头党来说,在使用WIFI功能时,经常性的操作是打开手机上的WIFI设备,搜索到心目中的热点,输入密码,联网成功,各种低头上网...这个看似简单的过程,背后却是隐藏着大量的无线通信技术.用几个专业术语来表示这个过程,分别是:扫描(Scanning).认证(Authentication).关联(Association).下面用一张图来表示这个过程. 图1  WIFI接入网络过程 现在让我们来分析一下这个过程的工

【智能家居篇】wifi网络结构(下)

转载请注明出处:http://blog.csdn.net/Righthek 谢谢! 由于WIFI网络具有移动性,同时WIFI以无线电波作为传输媒介,这种媒介本质上是开放的,且容易被拦截,任何人都可以通过抓包工具截取无线网络的数据包.因此,在设计WIFI协议(其实就是802.11协议)时,需要提供一些传输数据和管理的服务.         1. 分布式(Distribution) 只要基础结构型网络里的移动式站点传送任何数据,就会使用这项服务.一旦基站接收到帧.就会使用分布式服务将帧送至目的地.任