ImageVerifierCode 换一换
格式:DOCX , 页数:23 ,大小:203.38KB ,
资源ID:10136317      下载积分:12 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/10136317.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Linux 下wifi 驱动开发 SDIO接口WiFi驱动浅析.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Linux 下wifi 驱动开发 SDIO接口WiFi驱动浅析.docx

1、Linux 下wifi 驱动开发 SDIO接口WiFi驱动浅析Linux 下wifi 驱动开发(三) SDIO接口WiFi驱动浅析 SDIO-Wifi模块是基于SDIO接口的符合wifi无线网络标准的嵌入式模块,内置无线网络协议IEEE802.11协议栈以及TCP/IP协议栈,能够实现用户主平台数据通过SDIO口到无线网络之间的转换。SDIO具有传输数据快,兼容SD、MMC接口等特点。 对于SDIO接口的wifi,首先,它是一个sdio的卡的设备,然后具备了wifi的功能,所以,注册的时候还是先以sdio的卡的设备去注册的。然后检测到卡之后就要驱动他的wifi功能了,显然,他是用sdio的协议

2、,通过发命令和数据来控制的。下面先简单回顾一下SDIO的相关知识:一、SDIO相关基础知识解析1、SDIO接口 SDIO故名思义,就是SD 的 I/O 接口(interface)的意思,不过这样解释可能还有点抽像。更具体的说明,SD 本来是记忆卡的标准,但是现在也可以把 SD 拿来插上一些外围接口使用,这样的技术便是 SDIO。 所以 SDIO 本身是一种相当单纯的技术,透过 SD 的 I/O 接脚来连接外部外围,并且透过 SD 上的 I/O 数据接位与这些外围传输数据,而且 SD 协会会员也推出很完整的 SDIO stack 驱动程序,使得 SDIO 外围(我们称为SDIO 卡)的开发与应用

3、变得相当热门。 现在已经有非常多的手机或是手持装置都支持 SDIO 的功能(SD 标准原本就是针对 mobile device 而制定),而且许多 SDIO 外围也都被开发出来,让手机外接外围更加容易,并且开发上更有弹性(不需要内建外围)。目前常见的 SDIO 外围(SDIO 卡)有: Wi-Fi card(无线网络卡) CMOS sensor card(照相模块) GPS card GSM/GPRS modem card Bluetooth card SDIO 的应用将是未来嵌入式系统最重要的接口技术之一,并且也会取代目前 GPIO 式的 SPI 接口。2、SDIO总线 SDIO总线 和 U

4、SB总线 类似,SDIO也有两端,其中一端是HOST端,另一端是device端。所有的通信都是由HOST端 发送 命令 开始的,Device端只要能解析命令,就可以相互通信。CLK信号:HOST给DEVICE的 时钟信号,每个时钟周期传输一个命令。CMD信号:双向 的信号,用于传送 命令 和 反应。DAT0-DAT3 信号:四条用于传送的数据线。VDD信号:电源信号。VSS1,VSS2:电源地信号。3、SDIO热插拔原理方法:设置一个定时器检查或插拔中断检测硬件:假如GPG10(EINT18)用于SD卡检测GPG10 为高电平 即没有插入SD卡GPG10为低电平 即插入了SD卡4、SDIO命令

5、 SDIO总线上都是HOST端发起请求,然后DEVICE端回应请求。sdio命令由6个字节组成。a - Command:用于开始传输的命令,是由HOST端发往DEVICE端的。其中命令是通过CMD信号线传送的。b - Response:回应是DEVICE返回的HOST的命令,作为Command的回应。也是通过CMD线传送的。c - Data:数据是双向的传送的。可以设置为1线模式,也可以设置为4线模式。数据是通过DAT0-DAT3信号线传输的。 SDIO的每次操作都是由HOST在CMD线上发起一个CMD,对于有的CMD,DEVICE需要返回Response,有的则不需要。 对于读命令,首先HO

6、ST会向DEVICE发送命令,紧接着DEVICE会返回一个握手信号,此时,当HOST收到回应的握手信号后,会将数据放在4位的数据线上,在传送数据的同时会跟随着CRC校验码。当整个读传送完毕后,HOST会再次发送一个命令,通知DEVICE操作完毕,DEVICE同时会返回一个响应。 对于写命令,首先HOST会向DEVICE发送命令,紧接着DEVICE会返回一个握手信号,此时,当HOST收到回应的握手信号后,会将数据放在4位的数据线上,在传送数据的同时会跟随着CRC校验码。当整个写传送完毕后,HOST会再次发送一个命令,通知DEVICE操作完毕,DEVICE同时会返回一个响应。二、SDIO接口驱动

7、前面讲到,SDIO接口的wifi,首先,它是一个sdio的卡的设备,然后具备了wifi的功能,所以SDIO接口的WiFi驱动就是在wifi驱动外面套上了一个SDIO驱动的外壳,SDIO驱动仍然符合设备驱动的分层与分离思想: 设备驱动层(wifi 设备) |核心层(向上向下提供接口) |主机驱动层 (实现SDIO驱动) 下面先分析SDIO接口驱动的实现,看几个重要的数据结构(用于核心层与主机驱动层 的数据交换处理)。 /include/linux/mmc/host.h struct mmc_host 用来描述卡控制器struct mmc_card 用来描述卡struct mmc_driver 用

8、来描述 mmc 卡驱动struct sdio_func 用来描述 功能设备struct mmc_host_ops 用来描述卡控制器操作接口函数功能,用于从 主机控制器层向 core 层注册操作函数,从而将core 层与具体的主机控制器隔离。也就是说 core 要操作主机控制器,就用这个 ops 当中给的函数指针操作,不能直接调用具体主控制器的函数。 HOST层驱动分析在 前面的系列文章中Linux SD卡驱动开发(二) SD 卡驱动分析HOST篇有详细阐述,下面只简单回顾一下一些重要函数处理1、编写Host层驱动 这里参考的是S3C24XX的HOST驱动程序 /drivers/mmc/host

9、/s3cmci.ccppview plaincopy1.staticstructplatform_drivers3cmci_driver=2.driver=3.name=s3c-sdi,/名称和平台设备定义中的对应4.owner=THIS_MODULE,5.pm=s3cmci_pm_ops,6.,7.id_table=s3cmci_driver_ids,8.probe=s3cmci_probe,/平台设备探测接口函数9.remove=_devexit_p(s3cmci_remove),10.shutdown=s3cmci_shutdown,11.;12.13.s3cmci_probe(stru

10、ctplatform_device*pdev)14.15./.16.structmmc_host*mmc;17.mmc=mmc_alloc_host(sizeof(structs3cmci_host),&pdev-dev);/分配mmc_host结构体18.19./.20.21.22./*注册中断处理函数s3cmci_irq,来处理数据收发过程引起的各种中断*/23.request_irq(host-irq,s3cmci_irq,0,DRIVER_NAME,host)/注册中断处理函数s3cmci_irq24.25./*注册中断处理s3cmci_irq_cd函数,来处理热拨插引起的中断,中断触

11、发的形式为上升沿、下降沿触发*/26.request_irq(host-irq_cd,s3cmci_irq_cd,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,DRIVER_NAME,host)27.28.mmc_add_host(mmc);/initialisehosthardware/向MMCcore注册host驱动29.-device_add(&host-class_dev);/添加设备到mmc_bus_type总线上的设备链表中30.-mmc_start_host(host);/启动mmchost31.32./*MMCdriversshouldcal

12、lthiswhentheydetectacardhasbeeninsertedorremoved.检测sd卡是否插上或移除*/33.-mmc_detect_change(host,0);34.35./*ScheduledelayedworkintheMMCworkqueue.调度延时工作队列*/36.mmc_schedule_delayed_work(&host-detect,delay);搜索host-detected得到以下信息:/drivers/mmc/core/host.ccppview plaincopy1.NIT_DELAYED_WORK(&host-detect,mmc_resc

13、an);2.3.mmc_rescan(structwork_struct*work)4.-mmc_bus_put(host);/card从bus上移除时,释放它占有的总线空间5.6./*判断当前mmchost控制器是否被占用,当前mmc控制器如果被占用,那么host-claimed=1;否则为07.*如果为1,那么会在while(1)循环中调用schedule切换出自己,当占用mmc控制器的操作完成之后,执行*mmc_release_host()的时候,会激活登记到等待队列&host-wq中的其他程序获得mmc主控制器的使用权8.*/9.mmc_claim_host(host);10.mmc_

14、rescan_try_freq(host,max(freqsi,host-f_min);11.12.staticintmmc_rescan_try_freq(structmmc_host*host,unsignedfreq)13.14.15./*Ordersimportant:probeSDIO,thenSD,thenMMC*/16.if(!mmc_attach_sdio(host)17.return0;18.if(!mmc_attach_sd(host)19.return0;20.if(!mmc_attach_mmc(host)21.return0;22.23.24.25.mmc_attac

15、h_sdio(structmmc_host*host)/匹配sdio接口卡26.-mmc_attach_bus(host,&mmc_sdio_ops);27.28./*当card与总线上的驱动匹配,就初始化card*/29.mmc_sdio_init_card(host,host-ocr,NULL,0);30.-card=mmc_alloc_card(host,NULL);/分配一个card结构体31.mmc_set_bus_mode(host,MMC_BUSMODE_PUSHPULL);/设置mmc_bus的工作模式32.33.structsdio_func*sdio_funcSDIO_MA

16、X_FUNCS;/SDIOfunctions(devices)34.35.sdio_init_func(host-card,i+1);36.-func=sdio_alloc_func(card);/分配structsdio_fun(sdio功能设备)结构体37.mmc_io_rw_direct();38.card-sdio_funcfn-1=func;39.40.mmc_add_card(host-card);/将具体的sdio设备挂载到mmc_bus_types总线41.sdio_add_func(host-card-sdio_funci);/将sdio功能设备挂载到sdio_bus_typ

17、es总线这里一系列函数调用在前面的SD驱动蚊帐中已经阐述过了,不再详细阐述2、SDIO设备的热插拔 当插拔SDIO设备,会触发中断通知到CPU,然后执行卡检测中断处理函数在这个中断服务函数中,mmc_detect_change-mmc_schedule_delayed_work(&host-detect,delay), INIT_DELAYED_WORK(&host-detect, mmc_rescan)会调度mmc_rescan函数延时调度工作队列,这样也会触发SDIO设备的初始化流程,检测到有效的SDIO设备后,会将它注册到系统中去。cppview plaincopy1.staticirq

18、return_ts3cmci_irq_cd(intirq,void*dev_id)2.3.structs3cmci_host*host=(structs3cmci_host*)dev_id;4.5.mmc_detect_change(host-mmc,msecs_to_jiffies(500);6.7.returnIRQ_HANDLED;8.三、wifi 驱动部分解析wifi驱动的通用的软件架构1. 分为两部分,上面为主机端驱动,下面是我们之前所说的firmware2. 其中固件部分的主要工作是:因为天线接受和发送回来的都是802.11帧的帧,而主机接受和传送出来的数据都必须是802.3的帧,

19、所以必须由firmware来负责802.3的帧和802.11帧之间的转换3. 当天线收到数据,并被firmware处理好后会放在一个buffer里,并产生一个中断,主机在收到中断后就去读这个buffer。 SDIO设备的驱动由sdio_driver结构体定义,sdio_driver其实是driver的封装。通过sdio_register_driver函数将SDIO设备驱动加载进内核,其实就是挂载到sdio_bus_type总线上去。1、设备驱动的注册与匹配Drivers/net/wireless/libertas/if_sdio.ccppview plaincopy1./*SDIOfuncti

20、ondevicedriver*/2.3.structsdio_driver4.char*name;/设备名5.conststructsdio_device_id*id_table;/设备驱动ID6.int(*probe)(structsdio_func*,conststructsdio_device_id*);/匹配函数7.void(*remove)(structsdio_func*);8.structdevice_driverdrv;9.;下面是具体函数的填充:cppview plaincopy1./*if_sdio.c*/2.3.staticstructsdio_driverif_sdio

21、_driver=4.name=libertas_sdio,5.id_table=if_sdio_ids,/用于设备与驱动的匹配6.probe=if_sdio_probe,7.remove=if_sdio_remove,8.drv=9.pm=&if_sdio_pm_ops,10.11.;设备注册函数cppview plaincopy1./*2.*sdio_register_driver-registerafunctiondriver3.*drv:SDIOfunctiondriver4.*/5.6.intsdio_register_driver(structsdio_driver*drv)7.8.

22、drv-drv.name=drv-name;9.drv-drv.bus=&sdio_bus_type;/设置driver的bus为sdio_bus_type10.returndriver_register(&drv-drv);11.总线函数cppview plaincopy1.staticstructbus_typesdio_bus_type=2.name=sdio,3.dev_attrs=sdio_dev_attrs,4.match=sdio_bus_match,5.uevent=sdio_bus_uevent,6.probe=sdio_bus_probe,7.remove=sdio_bus

23、_remove,8.pm=SDIO_PM_OPS_PTR,9.;注意:设备或者驱动注册到系统中的过程中,都会调用相应bus上的匹配函数来进行匹配合适的驱动或者设备,对于sdio设备的匹配是由sdio_bus_match和sdio_bus_probe函数来完成。cppview plaincopy1.staticintsdio_bus_match(structdevice*dev,structdevice_driver*drv)2.3.structsdio_func*func=dev_to_sdio_func(dev);4.structsdio_driver*sdrv=to_sdio_driver

24、(drv);5.if(sdio_match_device(func,sdrv)6.return1;7.8.return0;9.10.11.staticconststructsdio_device_id*sdio_match_device(structsdio_func*func,12.structsdio_driver*sdrv)13.14.conststructsdio_device_id*ids;15.ids=sdrv-id_table;16.17.if(sdio_match_one(func,ids)18.returnids;19.由以上匹配过程来看,通过匹配id_table 和 sdi

25、o_driver设备驱动中id,来匹配合适的驱动或设备。最终会调用.probe函数,来完成相关操作。2、If_sdio_probe函数 当检测到sdio卡插入了之后就会调用If_sdio_probe,而当卡被移除后就会调用If_sdio_remove。下面先看下If_sdio_probet函数,if_sdio_prob 函数 主要做了两件事 cppview plaincopy1.staticstructsdio_driverif_sdio_driver=2.name=libertas_sdio,3.id_table=if_sdio_ids,/用于设备和驱动的匹配4.probe=if_sdio_

26、probe,5.remove=if_sdio_remove,6.drv=7.pm=&if_sdio_pm_ops,8.,9.;10.11.12.1/定义一个if_sdiocard的结构体13.structif_sdio_card*card;14.structif_sdio_packet*packet;/sdio包的结构体15.structmmc_host*host=func-card-host;16.17./查询是否有指定的功能寄存器在mmc18./_sdio_card中19.for(i=0;icard-num_info;i+)20.if(sscanf(func-card-infoi,21.802.11SDIOID:%x,&model)=1)22.23./在这里进行片选选择到我们使用的marvell8686的设备24.caseMODEL_8686:25.ca

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1