1. 程式人生 > >wifi模組rtl8723b的驅動移植

wifi模組rtl8723b的驅動移植

一、前言

      在除錯wifi驅動的時候會遇到很多坑,相信每個除錯驅動的工程師都深有體會吧。wifi驅動涉及到linux和android兩個大層面,任意一個環節出錯都有可能導致wifi驅動不能正常工作,現在我總結一下我在移植wifi驅動的時候所遇到的坑。

1.sdio介面的wifi驅動rtl8723bs安裝後只提示驅動安裝成功,但平臺裝置驅動註冊失敗。

錯誤資訊如下:

[email protected]:/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=0
[email protected]
:/system/lib/modules #
問題分析和解決:

        出現這個原因是因為linux系統檢測不到這個sdio裝置,沒有呼叫平臺裝置的探測函式:probe。而sdio的裝置驅動還需要一根cd線觸發,通知linux系統有sdio裝置接入,這時linux系統才會呼叫probe函式。這個cd線是利用sdio匯流排裡的gpio來檢測的,這是特定的gpio,理論上不能用別的io代替。

要對應地在linux系統裡面配置sdio的cd引腳

通過配置cd腳後,當cd腳拉低,在linux上會列印除錯資訊的:

2|[email protected]
:/ $ [ 780.545219] *******mmc2: inserted!!!!!****** [ 780.629082] mmc2: new high speed SDIO card at address 0001
在linux的系統目錄下可以看到sdio的裝置:


當拔出cd腳,同樣也會列印除錯資訊:

|[email protected]:/ $ [  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驅動。

[email protected]:/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 prepare
	chmod 0770 /system/lib/modules
	chown wifi wifi /system/lib/modules
	chown wifi wifi /system/lib/modules/wlan.ko

	mkdir /system/etc/wifi 0770 wifi wifi
	chmod 0770 /system/etc/wifi
	chmod 0660 /system/etc/wifi/wpa_supplicant.conf
	chown wifi wifi /system/etc/wifi/wpa_supplicant.conf
       # wpa_supplicant socket
	mkdir /data/misc/wifi 0770 wifi wifi
	mkdir /data/misc/wifi/sockets 0770 wifi wifi
	chmod 0770 /data/misc/wifi
	chmod 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 p2p0
09-19 17:21:44.770 1567-1604/system_process D/WifiHW: check_wifi_ifname_from_proc: find lo
09-19 17:21:44.770 1567-1604/system_process D/WifiHW: check_wifi_ifname_from_proc: find rmnet0
09-19 17:21:44.770 1567-1604/system_process D/WifiHW: check_wifi_ifname_from_proc: find sit0
09-19 17:21:44.770 1567-1604/system_process D/WifiHW: check_wifi_ifname_from_proc: find ip6tnl0
09-19 17:21:44.770 1567-1604/system_process D/WifiHW: check_wifi_ifname_from_proc: find wlan0
09-19 17:21:44.770 1567-1604/system_process D/WifiHW: check_wifi_ifname_from_proc: find p2p0
09-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 = false
09-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 directory
09-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 directory
09-19 17:21:46.825 1567-1604/system_process D/WifiConfigStore: Loading config and enabling all networks
09-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 smdk4x12
09-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 SMDK4X12
09-19 17:21:46.850 1567-1604/system_process E/WifiStateMachine: Failed to set model number Android On SMDK4X12
09-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 methods
09-19 17:21:46.860 1567-1604/system_process E/WifiStateMachine: Failed to set primary device type 10-0050F204-5
09-19 17:21:46.875 1567-1603/system_process D/WifiMonitor: startMonitoring(p2p0) with mConnected = true
09-19 17:21:46.885 1567-1604/system_process E/WifiStateMachine: Failed to set frequency band 0
09-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地址是否分配

[email protected]:/system/lib/modules # netcfg                                     
lo       UP                                   127.0.0.1/8   0x00000049 00:00:00:00:00:00
rmnet0   DOWN                                   0.0.0.0/0   0x00001002 4e:c0:15:04:86:ea
sit0     DOWN                                   0.0.0.0/0   0x00000080 00:00:00:00:00:00
ip6tnl0  DOWN                                   0.0.0.0/0   0x00000080 00:00:00:00:00:00
wlan0    UP                               192.168.16.62/24  0x00001043 54:c9:df:ca:a0:bc
p2p0     UP                                     0.0.0.0/0   0x00001003 56:c9:df:ca:a0:bc

第二個命令是iwconfig, 它可以檢視網路裝置的詳細資訊。

[email protected]:/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:"<[email protected]>"
          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:0

p2p0      unassociated  Nickname:"<[email protected]>"
          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除錯串列埠的資訊可以知道驅動或者裝置是否正常工作。

(4)iwlist iwconfig iwpriv 這三個命令可以在安卓原始碼中生成

<1>tar zxvf wireless_tools.30.rtl.tar.gz
<2>cp wireless_tools.30.rtl <ANDROID_SDK>/external/
<3>cd <ANDROID_SDK>
<4>make iwconfig iwlist iwpriv 
或者在“device/softwinner/tulip-t1/tulip_t1.mk”檔案中新增相關編譯選項
PRODUCT_PACKAGES += \
    iwconfig \
    iwlist \
    iwpriv