基于海思Hi3798MV200-android7.0适配RTL8733BU模块WiFi流程梳理
在Android方案开发中,经常需要移植不同厂商不同型号的WiFi模块驱动,并与系统软件进行适配。模块厂商一般都会提供相应的开发文档以及驱动源码,我们需要做的就是将驱动源码编译成驱动模块ko文件,或者直接编进kernel中,我的项目中基本都是编译成ko驱动文件,方便不同型号的固件间替换文件即可。然后根据开发文档进行差异化适配,下面以在海思Hi3798MV200-android7.0适配RTL8733BU模块为例,整理记录整个流程。

厂商提供的源码及开发文档如上图目录,基本只需要关心三个地方,驱动源码、Android版本适配差异、wpa_supplicant(WiFi连接通讯相关)版本源码。
1.BoardConfig.mk中新增全局WiFi模块开关定义
代码路径:\HiSTBAndroidV600R003C00SPC020\device\hisilicon\Hi3798MV200\BoardConfig.mk
# RTL8188FTV
BOARD_WLAN_DEVICE_RTL8188FTV := n
# RTL8188EUS
BOARD_WLAN_DEVICE_RTL8188EUS := n
# RTL8188ETV
BOARD_WLAN_DEVICE_RTL8188ETV := n
# RTL8192EU
BOARD_WLAN_DEVICE_RTL8192EU := n
# RTL8821CU
BOARD_WLAN_DEVICE_RTL8821CU := y
# RTL8731BU新增
BOARD_WLAN_DEVICE_RTL8733BU := y
# HI1131C
BOARD_WLAN_DEVICE_HI1131C := n
ifeq ($(BOARD_WLAN_DEVICE_RTL8821CU),y)
BOARD_WIFI_VENDOR := realtek
endif
#新增厂商定义
ifeq ($(BOARD_WLAN_DEVICE_RTL8733BU),y)
BOARD_WIFI_VENDOR := realtek
endif
#更据7.0开发文件定义wpa_supplicant版本等信息
#BOARD_WIFI_VENDOR := realtek
ifeq ($(BOARD_WIFI_VENDOR), realtek)
WPA_SUPPLICANT_VERSION := VER_0_8_X
BOARD_WPA_SUPPLICANT_DRIVER := NL80211
BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_rtl
BOARD_HOSTAPD_DRIVER := NL80211
BOARD_HOSTAPD_PRIVATE_LIB := lib_driver_cmd_rtl
BOARD_WLAN_DEVICE := rtl8822bu # 根据实际芯片选择
WIFI_DRIVER_MODULE_NAME := "wlan"
WIFI_DRIVER_MODULE_PATH := "/vendor/modules/wlan.ko"
WIFI_DRIVER_MODULE_ARG := "ifname=wlan0 if2name=p2p0"
WIFI_FIRMWARE_LOADER := "rtw_fwloader"
WIFI_DRIVER_FW_PATH_STA := "STA"
WIFI_DRIVER_FW_PATH_AP := "AP"
WIFI_DRIVER_FW_PATH_P2P := "P2P"
WIFI_DRIVER_FW_PATH_PARAM := "/dev/null"
endif
2.kernel.mk中新增对应模块驱动编译定义
代码路径:HiSTBAndroidV600R003C00SPC020\device\hisilicon\bigfish\build\kernel.mk
#----------------------------------------------------------------------
# Update Wifi Drivers
#----------------------------------------------------------------------
WIFI_CFG := \
CFG_HI_WIFI_DEVICE_RTL8188EUS=$(BOARD_WLAN_DEVICE_RTL8188EUS) \
CFG_HI_WIFI_DEVICE_RTL8192EU=$(BOARD_WLAN_DEVICE_RTL8192EU) \
CFG_HI_WIFI_DEVICE_RTL8812AU=$(BOARD_WLAN_DEVICE_RTL8812AU) \
CFG_HI_WIFI_DEVICE_RTL8723BU=$(BOARD_BLUETOOTH_WIFI_DEVICE_RTL8723BU) \
CFG_HI_WIFI_DEVICE_RTL8822BU=$(BOARD_BLUETOOTH_WIFI_DEVICE_RTL8822BU) \
CFG_HI_WIFI_DEVICE_RTL8821AU=$(BOARD_BLUETOOTH_WIFI_DEVICE_RTL8821AU) \
CFG_HI_WIFI_DEVICE_MT7601U=$(BOARD_WLAN_DEVICE_MT7601U) \
CFG_HI_WIFI_DEVICE_MT7662TE=$(BOARD_BLUETOOTH_WIFI_DEVICE_MT7662TE) \
CFG_HI_WIFI_DEVICE_MT76X2U=$(BOARD_BLUETOOTH_WIFI_DEVICE_MT76X2TU) \
CFG_HI_WIFI_DEVICE_QCA6174=$(BOARD_BLUETOOTH_WIFI_DEVICE_QCA6174) \
CFG_HI_WIFI_DEVICE_HI1131C=$(BOARD_WLAN_DEVICE_HI1131C) \
CFG_HI_WIFI_DEVICE_AP6XXX=$(BOARD_BLUETOOTH_WIFI_DEVICE_AP6356S) \
CFG_HI_WIFI_DEVICE_RTL8822BEH=$(BOARD_BLUETOOTH_WIFI_DEVICE_RTL8822BEH) \
CFG_HI_WIFI_DEVICE_RTL8188FU=$(BOARD_WLAN_DEVICE_RTL8188FTV) \
CFG_HI_WIFI_DEVICE_RTL8821CU=$(BOARD_WLAN_DEVICE_RTL8821CU) \
#新增CFG_HI_WIFI_DEVICE_RTL8733BU关联上一步BOARD_WLAN_DEVICE_RTL8733BU开关
CFG_HI_WIFI_DEVICE_RTL8733BU=$(BOARD_WLAN_DEVICE_RTL8733BU) \
CFG_HI_WIFI_MODE_STA=y CFG_HI_WIFI_MODE_AP=y
3.系统源码中WiFi驱动相关编译Makefile中新增模块驱动源码路径
代码路径:HiSTBAndroidV600R003C00SPC020\device\hisilicon\bigfish\sdk\source\component\wifi\drv\Makefile
ifeq ($(CFG_HI_WIFI_DEVICE_RTL8821CU),y)
objects += usb_rtl8821cu
endif
#根据上一步定义的开关增加模块驱动源码路径目录名称
ifeq ($(CFG_HI_WIFI_DEVICE_RTL8733BU),y)
objects += usb_rtl8733bu
endif
然后在drv目录下新增刚才定义的usb_rtl8733bu目录,里面放置厂商提供的驱动源码文件夹,如下


usb_rtl8733bu创建Makefile文件,内容如下:
obj-m += rtl8733BU_WiFi_linux_v5.15.12-123-g23d8f6271.20240806_COEX20230616-330e/
4.修改驱动源码中的Makefile,根据自己实际情况,配置对应的平台信息,编译链路径等才能正确编译出驱动ko文件
源码路径:HiSTBAndroidV600R003C00SPC020\device\hisilicon\bigfish\sdk\source\component\wifi\drv\usb_rtl8733bu\rtl8733BU_WiFi_linux_v5.15.12-123-g23d8f6271.20240806_COEX20230616-330e\Makefile
选择平台-CONFIG_PLATFORM_HISILICON_HI3798

选择自己源码中kernel路径和编译链路径:

至此,编译kernel就可以得到驱动文件8733bu.ko
源码根目录执行:make kernel -j32 2>&1 | tee kernel.log
得到kernel.img和system/lib/module/8733bu.ko
5.编译厂商提供的rtw_fwloader和wpa_supplicant,用于WiFi连接通讯
使用 Realtek 提供的 wpa_supplicant_8_N_7.0_rtw 替换系统默认版本:
-
删除原
external/wpa_supplicant_8 -
解压 Realtek 提供的版本并重命名为
wpa_supplicant_8 -
编译后得到/system/bin/wpa_supplicant
使用厂商提供给rtw_fwloader源码hardware/realtek拷贝到源码对应位置,编译后得到
/sysetm/bin/rtw_fwloader
6.init.xxx.rc 添加服务,开机启动上一步得到rtw_fwloader和wpa_supplicant的执行文件
代码路径:HiSTBAndroidV600R003C00SPC020\device\hisilicon\Hi3798MV200\etc\init.Hi3798MV200.rc
service rtw_fwloader /system/bin/rtw_fwloader
class main
disabled
oneshot
service wpa_supplicant /system/bin/wpa_supplicant \
-iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \
-e/data/misc/wifi/entropy.bin -g@android:wpa_wlan0
class main
socket wpa_wlan0 dgram 660 wifi wifi
disabled
oneshot
service p2p_supplicant /system/bin/wpa_supplicant \
-ip2p0 -Dnl80211 -c/data/misc/wifi/p2p_supplicant.conf \
-e/data/misc/wifi/entropy.bin -N \
-iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \
-g@android:wpa_wlan0
class main
socket wpa_wlan0 dgram 660 wifi wifi
disabled
oneshot
service dhcpcd_wlan0 /system/bin/dhcpcd -aABDKL
class main
disabled
oneshot
service dhcpcd_p2p /system/bin/dhcpcd -aABKL
class main
disabled
oneshot
7.修改libhardware_legacy开机自动加载对应WiFi模块驱动
这一步可参考之前文章Android 开机自动加载新wifi模块驱动
代码目录:HiSTBAndroidV600R003C00SPC020\hardware\libhardware_legacy\include\hardware_legacy\wifi.h
typedef enum {
WIFI_RALINK_MT7601U,
WIFI_REALTEK_RTL8188EUS,
WIFI_REALTEK_RTL8188ETV,
WIFI_REALTEK_RTL8192EU,
WIFI_REALTEK_RTL8812AU,
WIFI_REALTEK_RTL8723BU,
WIFI_MEDIATEK_MT7632U,
WIFI_MEDIATEK_MT7662U,
WIFI_MEDIATEK_MT7612U,
WIFI_REALTEK_RTL8821AU,
WIFI_ATHEROS_QCA6174,
WIFI_REALTEK_RTL8822BU,
WIFI_REALTEK_RTL8822BE,
WIFI_HISI_HI1131C,
WIFI_AMPAK_AP6356S,
WIFI_REALTEK_RTL8188FU,
WIFI_MEDIATEK_MT7662TE,
WIFI_MEDIATEK_MT7662TU,
WIFI_REALTEK_RTL8821CU,
WIFI_REALTEK_RTL8731BU, //新增
WIFI_INVALID_DEVICE = ~0x0 ,
} wifi_id_e;
kl90x\HiSTBAndroidV600R003C00SPC020\hardware\libhardware_legacy\wifi\wifi.c
static wifi_modules_s sta_drivers[] = {
{DRIVER_MODULE_MT7601U_STA}, // MediaTek MT7601U
{DRIVER_MODULE_RTL8188EUS}, // RealTek RTL8188EUS
{DRIVER_MODULE_RTL8188EUS}, // RealTek RTL8188ETV
{DRIVER_MODULE_RTL8192EU}, // RealTek RTL8192EU
{DRIVER_MODULE_RTL8812AU}, // RealTek RTL8812AU
{DRIVER_MODULE_RTL8723BU}, // RealTek RTL8723BU
{DRIVER_MODULE_MT7632U}, // MediaTek MT7632U
{DRIVER_MODULE_MT7632U}, // MediaTek MT7662U
{DRIVER_MODULE_MT7632U}, // MediaTek MT7612U
{DRIVER_MODULE_RTL8821AU}, // RealTek RTL8821AU
{DRIVER_MODULE_QCA6174}, // Atheros QCA6174
{DRIVER_MODULE_RTL8822BU}, // RealTek RTL8822BU
{DRIVER_MODULE_RTL8822BE}, // RealTek RTL8822BE
{DRIVER_MODULE_HI1131C}, // Hisi Hi1131C
{DRIVER_MODULE_AP6356S_STA}, // AMPAK AP6356S
{DRIVER_MODULE_RTL8188FU}, // RealTek RTL8188FTV
{DRIVER_MODULE_MT7662TE}, //MediaTek MT7662TE
{DRIVER_MODULE_MT7662TU}, //MediaTek MT7662TU
{DRIVER_MODULE_RTL8821CU}, //RealTek RTL8821CU
{DRIVER_MODULE_RTL8731BU} //RealTek RTL8731BU
};
static wifi_modules_s sta_drivers[] = {
{DRIVER_MODULE_MT7601U_STA}, // MediaTek MT7601U
{DRIVER_MODULE_RTL8188EUS}, // RealTek RTL8188EUS
{DRIVER_MODULE_RTL8188EUS}, // RealTek RTL8188ETV
{DRIVER_MODULE_RTL8192EU}, // RealTek RTL8192EU
{DRIVER_MODULE_RTL8812AU}, // RealTek RTL8812AU
{DRIVER_MODULE_RTL8723BU}, // RealTek RTL8723BU
{DRIVER_MODULE_MT7632U}, // MediaTek MT7632U
{DRIVER_MODULE_MT7632U}, // MediaTek MT7662U
{DRIVER_MODULE_MT7632U}, // MediaTek MT7612U
{DRIVER_MODULE_RTL8821AU}, // RealTek RTL8821AU
{DRIVER_MODULE_QCA6174}, // Atheros QCA6174
{DRIVER_MODULE_RTL8822BU}, // RealTek RTL8822BU
{DRIVER_MODULE_RTL8822BE}, // RealTek RTL8822BE
{DRIVER_MODULE_HI1131C}, // Hisi Hi1131C
{DRIVER_MODULE_AP6356S_STA}, // AMPAK AP6356S
{DRIVER_MODULE_RTL8188FU}, // RealTek RTL8188FTV
{DRIVER_MODULE_MT7662TE}, //MediaTek MT7662TE
{DRIVER_MODULE_MT7662TU}, //MediaTek MT7662TU
{DRIVER_MODULE_RTL8821CU}, //RealTek RTL8821CU
{DRIVER_MODULE_RTL8731BU} //RealTek RTL8731BU
};
#define DRIVER_MODULE_RTL8821CU 2, \
{ \
{"cfg80211",MODULE_PATH"cfg80211.ko","","cfg80211 "}, \
{"rtl8821cu",MODULE_PATH"rtl8821cu.ko","ifname=wlan0 if2name=p2p0","rtl8821cu "} \
}
#define DRIVER_MODULE_RTL8731BU 2, \
{ \
{"cfg80211",MODULE_PATH"cfg80211.ko","","cfg80211 "}, \
{"8733bu",MODULE_PATH"8733bu.ko","ifname=wlan0 if2name=p2p0","8733bu "} \
}
编译得到/system/lib/libhardware_legacy.so,至此整个适配流程完成了。
手动调试命令:
1.检测WiFi设备:#lsusb 或 cd /sys/bus/usb/devices(设备名称在hardware\libhardware_legacy\wifi\wifi.c)
2.加载驱动:进入ko目录 cd /system/lib/modules
a.加载CFG80211驱动:insmod cfg80211.ko
b.加载WiFi驱动:insmod rt18188eu.ko
c.查看WiFi网口:iwconfig (有wlan0 网口说明WiFi初始化成功)
d.启动WiFi网口:ifconfig wlan0 up
e.扫描WiFi列表:iwlist wlan0 scan
wifi调试相关
1. 添加模块
insmod /system/vendor/modules/8733bs.ko ifname=wlan0 if2name=p2p0
2. 启动wpa_supplicant
wpa_supplicant -D nl80211 -i wlan0 -c /data/misc/wifi/wpa_supplicant.conf -B
wpa_supplicant -D nl80211 -i wlan0 -c /etc/wpa_supplicant.conf -B
3. 扫描二维码
wpa_cli scan
模块与系统通讯逻辑:
Android中Wifi里Frameworks和Wpa_Supplicant交互的方式
Wifi中主要通过WifiNative与WPAS通信。如果想从framework层控制WPAS层的OKC,步骤如下:
WifiNative–>com_android_server_wifi_WifiNative.cpp–>wifi.c–>wpa_supplicant.c
com_android_server_wifi_WifiNative.cpp是WifiNative的JNI,
wifi.c是底层wifi_start_supplicant() native方法的定义,
wifi.c中通过wifi_send_command() 使用ctrl_conn 中的wpa_ctrl 对象向WPAS 发送命令并接收回复。
wifi_ctrl_recv() 使用monitor_conn 中的wpa_ctrl 对象接收来自WPAS 的消息:
代码路径:
/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java
/frameworks/opt/net/wifi/service/jni/com_android_server_wifi_WifiNative.cpp
/hardware/libhardware_legacy/wifi/wifi.c
/external/wpa_supplicant_8/wpa_supplicant/wpa_supplicant.c
# Android 12上
frameworks/opt/net/wifi/libwifi_hal/rk_wifi_ctrl.cpp
4. wifi添加模块处理
android/hardware/libhardware_legacy/wifi_hardware_info/wifi_hardware_info.c
更多推荐


所有评论(0)