wifi模块rtl8723b的驱动移植

来源:互联网 发布:c语言default语句 编辑:程序博客网 时间:2024/06/01 07:21

一、前言

      在调试wifi驱动的时候会遇到很多坑,相信每个调试驱动的工程师都深有体会吧。wifi驱动涉及到linux和android两个大层面,任意一个环节出错都有可能导致wifi驱动不能正常工作,现在我总结一下我在移植wifi驱动的时候所遇到的坑。

1.sdio接口的wifi驱动rtl8723bs安装后只提示驱动安装成功,但平台设备驱动注册失败。

错误信息如下:

root@smdk4x12:/system/lib/modules # insmod wlan.ko                             [  454.470096] RTL871X: module init start[  454.472372] RTL871X: rtl8723bs v4.4.0_17166.20160322_BTCOEX20151223-654a[  454.479104] RTL871X: build time: Sep 11 2017 23:49:09[  454.484104] RTL871X: rtl8723bs BT-Coex version = BTCOEX20151223-654a[  454.490748] RTL871X: ## Calling platform_driver_register[  455.495153] RTL871X: rtw_android_wifictrl_func_add: platform_driver_register timeout[  455.501544] RTL871X: module init ret=0root@smdk4x12:/system/lib/modules # 
问题分析和解决:

        出现这个原因是因为linux系统检测不到这个sdio设备,没有调用平台设备的探测函数:probe。而sdio的设备驱动还需要一根cd线触发,通知linux系统有sdio设备接入,这时linux系统才会调用probe函数。这个cd线是利用sdio总线里的gpio来检测的,这是特定的gpio,理论上不能用别的io代替。

要对应地在linux系统里面配置sdio的cd引脚

通过配置cd脚后,当cd脚拉低,在linux上会打印调试信息的:

2|shell@smdk4x12:/ $ [  780.545219] *******mmc2: inserted!!!!!******[  780.629082] mmc2: new high speed SDIO card at address 0001
在linux的系统目录下可以看到sdio的设备:


当拔出cd脚,同样也会打印调试信息:

|shell@smdk4x12:/ $ [  820.596837] mmc2: card 0001 removed[  820.630223] *******mmc2: inserted!!!!!******[  820.685222] *******mmc2: inserted!!!!!******[  820.740234] *******mmc2: inserted!!!!!******[  820.795249] *******mmc2: inserted!!!!!******

如果你提前安装了wifi驱动,使用命令insmod wlan.ko,后面如果你把cd脚拉低后,系统会自动加载wifi驱动。

root@smdk4x12:/system/lib/modules # [  860.525217] *******mmc2: inserted!!!!!******[  860.609268] mmc2: new high speed SDIO card at address 0001[  860.618972] RTL871X: rtw_hal_config_rftype RF_Type is 3 TotalTxPath is 1 [  860.624660] RTL871X: Chip Version Info: CHIP_8723B_Normal_Chip_TSMC_F_CUT_1T1R_RomVer(0)[  860.642052] RTL871X: SetHwReg8723B: bMacPwrCtrlOn=1[  860.646977] RTL871X: PowerOnCheck: val_mix:0x0000063f, res:0x0000063f[  860.652052] RTL871X: PowerOnCheck: 0x100 the result of cmd52 and cmd53 is the same.[  860.659897] RTL871X: PowerOnCheck: 0x1B8 test Pass.[  860.665556] RTL871X: ReadAdapterInfo8723BS, 0x4e=0xe2[  860.669719] RTL871X: EEPROM type is E-FUSE[  860.674604] RTL871X: hal_EfuseSwitchToBank: Efuse switch bank to 0[  860.818585] RTL871X: hal_ReadEFuse_WiFi: data end at address=0xab[  860.823229] RTL871X: Efuse Realmap:[  860.826732] [  860.828155] 29 81 03 7C 51 08 28 00 62 07 0D 45 10 00 00 00 [  860.833797] 2F 2F 2F 2F 2F 2F 33 33 33 32 32 0D FF FF FF FF [  860.839443] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF [  860.845100] FF FF FF FF FF FF FF FF FF FF 28 28 28 28 28 28 [  860.850728] 28 28 28 28 28 00 FF FF FF FF FF FF FF FF FF FF [  860.856365] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF [  860.862007] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF [  860.867649] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF [  860.873291] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF [  860.878933] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF [  860.884575] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF [  860.890217] FF FF FF FF FF FF FF FF 20 3B 1F 00 00 00 FF FF [  860.895859] FF 29 20 11 00 00 00 FF 00 FF 12 FF FF FF FF FF [  860.901501] 3E 10 01 02 23 00 00 FF 20 04 4C 02 23 B7 21 02 [  860.907173] 0C 00 22 04 00 08 00 32 FF 21 02 0C 00 22 2A 01 [  860.917264] 01 00 00 00 00 00 00 00 00 00 00 00 02 00 FF FF [  860.926334] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

2.wifi驱动编译成功了,但是安卓系统无法正常调用

        rtl8723的驱动移植是分两步进行的,分别是linux层和安卓层,linux层的只需要把wifi驱动编译成ko的模块文件,把它拷贝到linux系统里面使用insmod就能安装,但是安卓系统无法直接调用,必须通过安卓系统与其对接才行。安卓系统是通过hal层的wifi_realtek.c文件里的inmod函数来代替人工的insmod,这样的话加载和卸载模块都由安卓系统掌控。

       如果遇到wifi驱动加载不成功,要检查下面几个可能:1.wifi模块的目录设置是否正确。2.wifi驱动在linux下用命令是否能正常安装。3.wifi驱动是否到到正确的目录。4.wifi驱动的目录用户组是不是wifi,读写权限是否是可读可写。5.wifi模块的用户组是否是wifi,读写权限是否是可读可写。通过init.rc文件里面添加初始化文件夹和文件的配置信息,可以达到上述的效果,安卓系统一开机就执行目录和文件的属性设置,保证对驱动正确加载和读写。配置信息如下:

# for wifi preparechmod 0770 /system/lib/moduleschown wifi wifi /system/lib/moduleschown wifi wifi /system/lib/modules/wlan.komkdir /system/etc/wifi 0770 wifi wifichmod 0770 /system/etc/wifichmod 0660 /system/etc/wifi/wpa_supplicant.confchown wifi wifi /system/etc/wifi/wpa_supplicant.conf       # wpa_supplicant socketmkdir /data/misc/wifi 0770 wifi wifimkdir /data/misc/wifi/sockets 0770 wifi wifichmod 0770 /data/misc/wifichmod 0660 /data/misc/wifi/wpa_supplicant.conf

但是千万别添加下面的配置信息

#mkdir /data/system/wpa_supplicant 0771 wifi wifi#chmod 0771 /data/system/wpa_supplicant
否则加载驱动的时候会找不到wlan0,提示错误信息如下:

09-19 17:21:44.770 1567-1604/system_process D/WifiHW: check_wifi_ifname_from_proc: find p2p009-19 17:21:44.770 1567-1604/system_process D/WifiHW: check_wifi_ifname_from_proc: find lo09-19 17:21:44.770 1567-1604/system_process D/WifiHW: check_wifi_ifname_from_proc: find rmnet009-19 17:21:44.770 1567-1604/system_process D/WifiHW: check_wifi_ifname_from_proc: find sit009-19 17:21:44.770 1567-1604/system_process D/WifiHW: check_wifi_ifname_from_proc: find ip6tnl009-19 17:21:44.770 1567-1604/system_process D/WifiHW: check_wifi_ifname_from_proc: find wlan009-19 17:21:44.770 1567-1604/system_process D/WifiHW: check_wifi_ifname_from_proc: find p2p009-19 17:21:44.795 2458-2458/? I/wpa_supplicant: define REALTEK_WIFI_VENDOR 09-19 17:21:44.810 1567-1604/system_process D/WifiMonitor: startMonitoring(wlan0) with mConnected = false09-19 17:21:44.820 1567-1604/system_process E/WifiHW: Unable to open connection to supplicant on "/data/misc/wifi/sockets/wlan0": No such file or directory09-19 17:21:45.815 1567-1604/system_process E/WifiHW: Unable to open connection to supplicant on "/data/misc/wifi/sockets/wlan0": No such file or directory09-19 17:21:46.825 1567-1604/system_process D/WifiConfigStore: Loading config and enabling all networks09-19 17:21:46.830 1567-1604/system_process E/WifiConfigStore: Error parsing configurationjava.io.FileNotFoundException: /data/misc/wifi/ipconfig.txt: open failed: ENOENT (No such file or directory)09-19 17:21:46.845 1567-1604/system_process E/WifiStateMachine: Failed to set device name smdk4x1209-19 17:21:46.850 1567-1604/system_process E/WifiStateMachine: Failed to set manufacturer SMDK4X12 by TOPEET (www.topeetboard.com)09-19 17:21:46.850 1567-1604/system_process E/WifiStateMachine: Failed to set model name Android On SMDK4X1209-19 17:21:46.850 1567-1604/system_process E/WifiStateMachine: Failed to set model number Android On SMDK4X1209-19 17:21:46.855 1567-1604/system_process E/WifiStateMachine: Failed to set serial number 09-19 17:21:46.855 1567-1604/system_process E/WifiStateMachine: Failed to set WPS config methods09-19 17:21:46.860 1567-1604/system_process E/WifiStateMachine: Failed to set primary device type 10-0050F204-509-19 17:21:46.875 1567-1603/system_process D/WifiMonitor: startMonitoring(p2p0) with mConnected = true09-19 17:21:46.885 1567-1604/system_process E/WifiStateMachine: Failed to set frequency band 009-19 17:21:46.895 1567-1603/system_process E/WifiP2pService: Unexpected loss of p2p socket connection
可是你即使一次又一次确认目录“/data/misc/wifi/sockets/wlan0”下是有wlan0,文件夹的目录属性及用户组都很正常,可是安卓系统就是找不到wlan0,这是一个很令人抓狂的问题。最后通过谷歌找到老外的说明,说是如果新建了
/data/system/wpa_supplicant
这个目录,会导致wpa_supplicant功能失效,因为hardware/libhardware_legacy/wifi/wifi.c 会检测是否存在目录“/data/system/wpa_supplicant”,如果有则会传递一个错误的参数给函数“wpa_ctrl_open()”,一般unix系统才需要目录“/data/system/wpa_supplicant”,安卓系统千万不要新建这个目录。

       最后谨记wifi驱动和相关的系统文件目录的用户组都必须是wifi,且必须是可读可写,不然的话在加载驱动或者开启wifi的时候会出现莫名其妙的问题。


3.如何调试wifi驱动

(1)通过安装驱动后查看系统文件,如果系统文件有驱动和设备都齐全则代表驱动安装成功,且linux可以根据设备加载对应的驱动。下面有sdio和usb两种接口的wifi模块,它在linux上有不同的表现。

下面是sdio接口:

下面的USB接口:

    

(2)通过各种命令查看linux下的网络信息来验证wifi模块是否正常驱动

第一个是netcfg命令,它可以查看当前网络哪些网络设备是否开启,ip地址是否分配

root@smdk4x12:/system/lib/modules # netcfg                                     lo       UP                                   127.0.0.1/8   0x00000049 00:00:00:00:00:00rmnet0   DOWN                                   0.0.0.0/0   0x00001002 4e:c0:15:04:86:easit0     DOWN                                   0.0.0.0/0   0x00000080 00:00:00:00:00:00ip6tnl0  DOWN                                   0.0.0.0/0   0x00000080 00:00:00:00:00:00wlan0    UP                               192.168.16.62/24  0x00001043 54:c9:df:ca:a0:bcp2p0     UP                                     0.0.0.0/0   0x00001003 56:c9:df:ca:a0:bc

第二个命令是iwconfig, 它可以查看网络设备的详细信息。

root@smdk4x12:/system/lib/modules # iwconfig                                   rmnet0    no wireless extensions.sit0      no wireless extensions.ip6tnl0   no wireless extensions.wlan0     IEEE 802.11bgn  ESSID:"\xE9\xAA\x8A\xE5\xBA\xAD\xE6\x99\xBA\xE8\x83\xBD\xE5\xAE\xB6\xE5\xB1\x85\xE4\xBA\x8C\xE6\xA5\xBC"  Nickname:"<WIFI@REALTEK>"          Mode:Managed  Frequency:2.452 GHz  Access Point: D4:EE:07:40:5C:EA             Bit Rate:150 Mb/s   Sensitivity:0/0            Retry:off   RTS thr:off   Fragment thr:off          Encryption key:****-****-****-****-****-****-****-****   Security mode:open          Power Management:off          Link Quality=99/100  Signal level=-67 dBm  Noise level=0 dBm          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0          Tx excessive retries:0  Invalid misc:0   Missed beacon:0p2p0      unassociated  Nickname:"<WIFI@REALTEK>"          Mode:Managed  Frequency=2.412 GHz  Access Point: Not-Associated             Sensitivity:0/0            Retry:off   RTS thr:off   Fragment thr:off          Encryption key:off          Power Management:off          Link Quality=0/100  Signal level=0 dBm  Noise level=0 dBm          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0          Tx excessive retries:0  Invalid misc:0   Missed beacon:0

第三个命令是iwlist,这个命令可以扫描wifi设备,如果wifi模块正常的话是可以扫描到路由器的ssid

iwlist wlan0 scan
(3)通过查看安卓系统输出的logcat信息和linux调试串口的信息可以知道驱动或者设备是否正常工作。