Platform: RockChip
OS: Android 6.0
Kernel: 4.4
WiFi/BT/FM 模组: AP6354
前面的基本概念搜罗于网络;
后面的驱动流程分析是根据 RockChip 3399 的 Kernel 部分来进行分析的。
-
- 基本概念
- Wifi
- WLAN
- 关系
- STA 模式 和 AP 模式
- 无线接入过程的三个阶段
- SD 和 MMC
- SDIOSecure Digital IO
- SDIO 卡 和 SD 卡 的区别
- SDIO-Wifi 模块
- SDIO 总线
- SDIO 命令
- WIFI 模块解析和启动流程
- SDIO 接口驱动
- WIFI 驱动流程分析
- 调试问题
- 调试步骤
- 确保配置无误
- 检查供电是否正常
- 扫描模块初始化模块
- 检查模块能否处于工作状态
- 确认Android层是否能够打开
- 吞吐率问题
- 其他问题
- 无法连接热点
- softap 无法打开正基系列的
- P2P 问题
- 调试步骤
- 基本概念
本博客唯一地址:http://blog.csdn.net/dearsq/article/details/53318887
欢迎转载,转载请注明作者 Younix~ 谢谢~
基本概念
Wifi
wifi 英文全称是 WIreless-FIdelity,翻译成中文就是无线保真,英文简称WiFi。
WLAN
wlan 英文全名:Wireless Local Area Networks, 无线局域网络。
关系
wifi 是实现 wlan 的一种技术。
STA 模式 和 AP 模式
AP模式: Access Point,提供无线接入服务,允许其它无线设备接入,提供数据访问,一般的无线路由/网桥工作在该模式下。AP和AP之间允许相互连接。
Sta模式: Station, 类似于无线终端,sta本身并不接受无线的接入,它可以连接到AP,一般无线网卡即工作在该模式。
无线接入过程的三个阶段
STA(工作站)启动初始化、开始正式使用AP传送数据帧前,要经过三个阶段才能够接入(802.11MAC层负责客户端与AP之间的通讯,功能包括扫描、接入、认证、加密、漫游和同步等功能):
1)扫描阶段(SCAN)
2)认证阶段 (Authentication)
3)关联(Association)
更详细的 wifi 相关介绍可以参考这篇文章 WiFi基础知识解析
后面介绍 Wifi 的接口 SDIO 的基本概念。
SD 和 MMC
SD (Secure Digital) 与 MMC (Multimedia Card)
MMC 是较早的一种记忆卡标准,目前已经被 SD 标准取代。
SD 是一种 flash memory card 的标准,也就是一般常见的 SD 记忆卡。
SDIO(Secure Digital I/O)
SDIO 就是 SD 的 I/O 接口的意思。
更具体的说,SD 本来是记忆卡的标准,但是现在也可以把 SD 拿来插上一些外围接口使用,这样的技术便是 SDIO。
SDIO 通过 SD 的 I/O 管脚来连接外部的外围 device 并传输数据。这些外围设备,我们称为 SDIO 卡,常见的有:
- Wi-Fi card(无线网络卡)
- CMOS sensor card(照相模块)
- GPS card
- GSM/GPRS modem card
- Bluetooth card
- Radio/TV card
SDIO 卡 和 SD 卡 的区别
SD卡使用的是SD卡协议,而SDIO卡使用的是SDIO协议!
协议不一样,初始化/读写方式也不一样!
SDIO-Wifi 模块
SDIO-Wifi 模块是基于 SDIO 接口的符合 wifi 无线网络标准的嵌入式模块,内置无线网络协议IEEE802.11协议栈以及TCP/IP协议栈,能够实现用户主平台数据通过SDIO口到无线网络之间的转换。
SDIO 具有传输数据快,兼容SD、MMC接口等特点。
对于SDIO接口的wifi,首先,它是一个sdio的卡的设备,然后具备了wifi的功能。
所以,注册的时候还是先以sdio的卡的设备去注册的。然后检测到卡之后就要驱动他的wifi功能。
SDIO 总线
SDIO总线 和 USB总线 类似,SDIO也有两端,其中一端是HOST端,另一端是device端。所有的通信都是由HOST端 发送 命令 开始的,Device端只要能解析命令,就可以相互通信。
CLK信号:HOST给DEVICE的 时钟信号,每个时钟周期传输一个命令。
CMD信号:双向 的信号,用于传送 命令 和 反应。
DAT0-DAT3 信号:四条用于传送的数据线。
VDD信号:电源信号。
VSS1,VSS2:电源地信号。
SDIO 命令
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,有的则不需要。
对于读命令,首先HOST会向DEVICE发送命令,紧接着DEVICE会返回一个握手信号,此时,当HOST收到回应的握手信号后,会将数据放在4位的数据线上,在传送数据的同时会跟随着CRC校验码。当整个读传送完毕后,HOST会再次发送一个命令,通知DEVICE操作完毕,DEVICE同时会返回一个响应。
对于写命令,首先HOST会向DEVICE发送命令,紧接着DEVICE会返回一个握手信号,此时,当HOST收到回应的握手信号后,会将数据放在4位的数据线上,在传送数据的同时会跟随着CRC校验码。当整个写传送完毕后,HOST会再次发送一个命令,通知DEVICE操作完毕,DEVICE同时会返回一个响应。
WIFI 模块解析和启动流程
对于 Wifi 模组的 Android 上层的分析,这篇文章讲的非常不错:
http://blog.csdn.net/ylyuanlu/article/details/7711433
这篇文章将下图蓝色的和绿色的部分讲的非常详细。
我这个板子上所采用的 WiFi 模组是 AP6354, 它是一个 Wifi / BT4.0 / FM 三合一模组。接口是 SDIO。
本文主要分析 Kernel Driver 部分。所以先从 SDIO 接口的驱动来切入。
SDIO 接口驱动
SDIO 接口的 wifi,首先,它是一个 sdio 卡 设备,然后具备了 wifi 的功能,所以 SDIO 接口的 WiFi 驱动就是在 wifi 驱动 外面套上了一个 SDIO 驱动 的外壳。
SDIO 驱动部分代码结构如下
drivers/mmc 下有 mmc卡、sd卡、sdio 卡驱动。
SDIO驱动仍然符合设备驱动的分层与分离思想。
设备驱动层(wifi 设备):
|
核心层(向上向下提供接口)
|
主机驱动层(实现 SDIO 驱动)
我们主要关心 core 目录(CORE 层),其中是媒体卡的通用代码。包括 core.c host.c stdio.c。
CORE 层完成了
1. 不同协议和规范的实现
2. 为 HOST 层的驱动提供了接口函数
3. 完成了 SDIO 总线注册
4. 对应 ops 操作
5. 以及支持 mmc 的代码
host 目录(HOST 层)是根据不通平台而编写的 host 驱动。
WIFI 驱动流程分析
rockchip_wifi_init_module_rkwifi //创建了一个内核线程 wifi_init_thread
—wifi_init_thread //->
——dhd_module_init
———dhd_wifi_platform_register_drv // 查找设备,注册 wifi 驱动,注册成功调用后面的 bcmdhd_wifi_plat_dev_drv_probe
————wifi_ctrlfunc_register_drv
————|—bus_find_device //查找 wifi 设备
————|—platform_driver_register(&wifi_platform_dev_driver) //注册 wifi 驱动
————bcmdhd_wifi_plat_dev_drv_probe //->
—————dhd_wifi_platform_load //两个操作
——————wl_android_init //1. wlan 初始化
——————dhd_wifi_platform_load_sdio //2. 根据 接口类型 usb、sdio、pcie 选择不同的操作
———————dhd_bus_register // 注册成功就调用 dhd_sdio.dhdsdio_probe
————————bcmsdh_register(&dhd_sdio)
————————|—bcmsdh_register_client_driver
————————|——sdio_register_driver(&bcmsdh_sdmmc_driver) //注册成功调用 bcmsdh_sdmmc_probe
————————|———bcmsdh_sdmmc_probe //->
————————|———sdioh_probe
————————dhdsdio_probe
参考文章
在全志平台调试博通的wifi驱动(类似ap6212)
wifi 详解(三)
调试问题
调试步骤
1.确保配置无误
dts文件的配置wifi部分是在net/rfkill-wlan.c中进行配置;先通过内核启动日志确认相关配置是否有正常解析,如果解析过程出现异常,确认是所配置的gpio是否存在冲突;
2.检查供电是否正常
确认wifi的供电控制是否受控
Echo 0 > /sys/class/rkwifi/power //对wifi模块掉电
Echo 1 > /sys/class/rkwifi/power//对wifi模块上电
如果执行上面命令对模块进行上下电,而 实际测量对应管脚不受控,可以通过io 命令读取对应的寄存器,确认是否写入,如果正确写入但是实际测量不受控请检查硬件部分;
3. 扫描模块初始化模块
检查内核中是否配置
CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP=y;
调测wifi时请把该宏配置为 n;
执行 echo 1 > /sys/class/rkwifi/driver 命令会调用模块的驱动的初始化操作,初始化成功后看到wlan0 节点;
如何判断是否识别到模块
* Usb接口的模块:出现如下 log
* SDIO 接口的模块
对于sdio接口的模块,执行” echo 1 > /sys/class/rkwifi/driver”命令 ,正常情况下 sdio_clk 和sdio_cmd 能够测量到相关波形,内核打印上能够看到如下打印,如果没有测量到波形也没有看到如下打印,根据配置文档检查是否正确配置sdio;
Wifi驱动会根据扫描到的sdio模块的vid pid 进行驱动匹配,rtl的驱动会根据读取到的vid,pid进行驱动匹配;其中正基系列的模块会根据后面从data数据线上读取到F1 function 读取的数值进行 驱动与固件匹配(正基目前的驱动兼容所有sdio接口正基模块,根据F1 function 读取的值 匹配固件);
如果能够扫描模块但是初始化过程看到data fifo error,检查下 sdio接口电平是否一致;方法如下:
echo 1 > /sys/class/rkwifi/power
测量 VDDIO sdio_clk sdio_cmd sdio_data0~sdio_data3 的电压;正常情况下 sdio_clk 为 0V,sdio其他五根线与vddio电压一致;
如果电压不一致:312x平台确认下 sdio接口的内部上下拉是否禁掉,参看文档RK Kernel 3.10平台WiFi BT不工作异常排查.pdf Part C;其他平台考虑加外部上拉(注clk绝对不要加外部上拉);
同时测量执行echo 1 > /sys/class/rkwifi/driver 时 外部晶体是否有起振,如果扫描时没有起振检查下硬件;同时建议测量外部晶体频偏,频偏比较大情况下,会出现能扫描到模块但是初始化失败;除检查晶振外,正基系列还需要外部32k,测量32k的峰峰值(峰峰值>=0.7*VDDIO && 峰峰值 <= 1*VDDIO);【注:频偏和峰峰值一定要测量检查,频偏过大峰峰值不对会影响wifi(扫描连接热点)和蓝牙(扫描连接设备))】
电压一致情况下,晶振频偏和32k的峰峰值没有问题(正基系列的要考虑晶振频偏与32k峰峰值,具体结合自己电路实际情况)但是初始化依然出问题;
考虑降低sdio_clk ,重新测试;如果降低clk可以,考虑硬件上走线;
如果降低clk依然不行,考虑使用sdio单线模式方法如下
&sdio {...bus-width = <1>;...
};
- 1
- 2
- 3
- 4
- 5
使用 sdio 单线模式。如果单线模式可以而使用4线模式不行,检查硬件上sdio_data0~sdio_data3 四根线的线序是否弄错;
如果降低clk,使用单线模式均不可以检查下是否是使用最新的sdk代码和最新的wifi驱动(ftp服务器上有相关patch);
上述检查均无结果,check 图纸 是否周围器件有贴错器件;
4.检查模块能否处于工作状态
netcfg wlan0 up 或busybox ifconfig wlan0 up //执行完成后检查 wlan0 是否处于up状态;如果没有处于up状态;做如下检查确认
1 确认相关固件是否存在(正基系列,通过看内核日志可以看到),固件不存在考虑到ftp下载固件;此时如果还报其他错误从两个方面排查1 上电时序,2检查sdio部分走线;
2 尝试使用原始最新的sdk代码做测试;(有客户出现过,上层做了相关修改导致wifi初始化成功,但是执行netcfg wlan0 up 报告无法识别 ioctl 命令等奇怪错误,原生sdk生成的sysytem.img 没有问题)
执行iwlist wlan0 scanning ,测试扫描热点是否正常(3368平台下执行iwlist 命令有问题,忽略此步骤)
5. 确认Android层是否能够打开
述检查各个步骤可以工作,而通过上层settings界面打开失败;以下几个方面排查
1 dts中的wifi_type配置是否正确;cat /sys/class/rkwifi/chip 确认 下 打印的结果和你的模块是否匹配
2 确认 wpa_supplicant 相关服务是否生成,libhardware_leacy 启动的wpa服务是否正确;
3 抓取logcat 日志上传readmine
吞吐率问题
- pcb检查,一定要让模块原厂检查确认 pcb是否存在问题
- RF指标确认是否ok
- 天线是否做过匹配
- Sdio 接口的可以考虑 提到sdio的clk 启用sdio3.0【前提 平台支持 sdio3.0 ,模块支持sdio3.0】
其他问题
无法连接热点
1.无法连接热点,正基系列模块检查确认晶振频偏和32k峰峰值;
rtl模块考虑驱动配置是否正确,是否匹配;
2.检查确认p2p wlan0 的mac地址是否一致如果检查是否有调用rockchip_wifi_mac_addr读取mac地址,如果有考虑直接在该函数中return -1;
3.检查确认是否有做RF指标测试以及天线匹配测试
4.上述检查没有问题,做如下测试 (首先用给手机连接所测试的热点做确认)
1 连接无加密热点 2 连接加密热点 测试能否连接成功,并记录对应的logcat 日志与内核日志(开机到打开wifi以及连接热点的整个过程)
softap 无法打开(正基系列的)
1.查看打开热点时的内核日志,确认下 下载固件是否正确 ,正基系列的模块 softap 下载的固件一般是带ap后缀结尾的;
2.固件下载没有问题 ,考虑使用原始的sdk代码做测试
P2P 问题
P2p 无法打开:确认是否有p2p节点,有p2p节点的检查确认mac地址是否与wlan0 一样,如果一样按照热点问题中的step 2 处理;
第一次开机能够打开,重启后无法打开:考虑检查上电时序,目前遇到都是rtl的模块出现过,问题在于chipen 脚不受控,建议做成受控,在重启时对chipen脚下电;可以通过如下方法实现net/rfkill-wlan.c中的rfkill_wlan_driver 中增加shutdown函数 在该函数中对chip_en 下电;
休眠唤醒出现wifi无法打开:
1 对比检查休眠唤醒前后 sdio 的iomux 是否发生变更
2 对比 休眠前后以及休眠中 wifi的外围供电是否发生变更