USB wifi模块mt7601U移植至imx 6q android 6.0平台

        最近公司使用imx6q开发新产品,我们没有经验,选了最新的android 6.0平台来做开发。而硬件给我们提供的wifi模块竟然是使用USB外接的wifi模块,没错,就是淘宝上买的那种小型无线网卡,不是嵌入式wifi模块(不想说硬件兄弟坑我们了,没办法,小公司就是这样),当然附带的光盘里面的驱动是windows驱动,不过挺良心的还有linux驱动代码,这多少让我感到有些安慰,以为有驱动应该好办。不说其他的,进入正题。

【调试驱动】

        光盘附带的linux驱动代码,确实是ralink的原厂驱动,网上一搜mt7601U驱动,找了很多,确实跟光盘附带的一样,不外乎以下两个:

           MT7601U_LinuxAP_3.0.0.1_20130802.tar.bz2

           DPA_MT7601U_LinuxSTA_3.0.0.4_20130916.tar.bz2

       所以,暂时相信它是可用的,拷贝出来放到unbuntu 14.04系统上编译(因为我们没有android开发经验,选了android 6.0.1版本,linux内核是3.14,而安装的ubuntu编译环境内核是3.13版本的,比较相近),首先试试驱动在PC机上能不能用,结果悲剧了,驱动代码编不过。本来想尝试修改下编不过的驱动代码,不过改了一个,又出现更多错误,想想还是放弃了,因为驱动代码毕竟不了解,即使最后编过了,也可能不能用。

        好在天无绝人之路,把目光转向依赖开源驱动。感谢github上的大神terence-deng和SunlionLM,最后下载了他们的驱动代码(下载地址:https://github.com/terence-deng/mt7601u  和  https://github.com/2421/mt7601u_driver_linux),终于在我的平台上验证能够编译通过。

        虽然折腾了点,但是这说明了前期的技术预研很有必要,技术预研要做到什么程度也需要考虑。我们没有预研,没有考虑软硬件版本兼容,乱选android版本和wifi硬件外设,导致走了弯路。

        最终驱动代码需要交叉编译,才能在imx6q平台使用,因此需要修改Makefile。修改如下:

       1、Makefile修改:

        默认平台是PC,定义一个我自己的平台

           PLATFORM = IMX6DQ

        然后添加交叉编译链

ifeq ($(PLATFORM),IMX6DQ)
LINUX_SRC = /home
/1-trunk/kernel_imx
CROSS_COMPILE= /home/1-trunk/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androideabi-
ARCH = arm
export ARCH
endif
 

      2、os/linux/config.mk修改:

     添加下列选项

ifeq ($(PLATFORM),IMX6DQ)
    EXTRA_CFLAGS := $(WFLAGS) -D__KERNEL__ -DMODULE -fno-pic -Wno-error=date-time
endif

     因为我是在android平台使用,所以也添加了以下选项

       HAS_WPA_SUPPLICANT=y

       HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=y       

       #Support for android
       HAS_ANDROID_SUPPORT=y

这样修改完成以后,就可以编译出mt7601Usta.ko。(terence-deng大神的代码编译出来是三个ko:mtutil7601Usta.ko、mt7601Usta.ko、mtnet7601Usta.ko,因为我用不上,所以最后采用了SunlionLM大神的代码)。

【驱动加载】

        为了验证驱动是可用的,我首先使用iwpriv来测试是否可以连上AP。android上并没有wireless_tools,所以要先去下载一下wireless_tools.29,然后添加Android.mk(可以参考http://blog.csdn.net/armeasy/article/details/6566462),

修改\1-trunk\build\target\product\base.mk,在PRODUCT_PACKAGES后面添加

iwpriv \
iwconfig \
iwlist

这样,就把wireless_tools编译到目标文件中了。

先手动加载驱动

     insmod /system/lib/modules/mt7601Usta.ko

    然后 

    ifconfig wlan0 up

    iwpriv wlan0 set Channel=auto
    iwpriv wlan0 set AutoReconnect=1
    iwpriv wlan0 set AuthMode=OPEN
    iwpriv wlan0 set EncrypType=NONE
    iwpriv wlan0 set SSID=ssid-xxx

连无密码的AP可以连上,但是奇怪的是我连有密码的AP却死活连不上(参数反复确认是正确的),命令如下:

     iwpriv wlan0 set Channel=auto
     iwpriv wlan0 set AutoReconnect=1
     iwpriv wlan0 set AuthMode=WPA2PSK
     iwpriv wlan0 set EncrypType=AES
     iwpriv wlan0 set SSID="TP-LINK_9792"
     iwpriv wlan0 set WPAPSK="1234567890"
     iwpriv wlan0 set SSID="TP-LINK_9792"

但是连不上,不知道什么原因,不知道是不是驱动的问题。后面为了赶进度就没有研究为什么连不上有密码AP了,接着调试android使用wpa_supplicant_8启动wifi。

android wpa_supplicant_8调试

     android源码里面默认支持的设备是broadcom的,因此要修改支持的设备
1、\1-trunk\device\fsl\sabresd_6dq\BoardConfig.mk 修改
BOARD_WLAN_DEVICE            := UNITE
改为:
BOARD_WLAN_DEVICE            := MediaTek

WPA_SUPPLICANT_VERSION       := VER_0_8_UNITE
改为:
WPA_SUPPLICANT_VERSION       := VER_0_8_X

并添加
BOARD_WLAN_VENDOR :=         MediaTek

2、1-trunk\device\fsl\imx6\sabresd_6dq.mk 修改
PRODUCT_COPY_FILES后面添加
kernel_imx/drivers/net/wireless/mt7601u-master-terence-deng/src/os/linux/mt7601Usta.ko:system/lib/modules/mt7601Usta.ko \
kernel_imx/drivers/net/wireless/mt7601u-master-terence-deng/etc/Wireless/RT2870AP/RT2870STA.dat:system/etc/Wireless/RT2870STA/RT2870STA.dat 

insmod mt7601Usta.ko出现内存分配错误,要在uboot启动参数cmdline后面加上coherent_pool=2M

        RT2870STA.dat这个文件一定要拷贝到板子上,否则,执行ifconfig会出现Operation not permitted 错误

3、创建目录1-trunk\hardware\mediatek\wlan\wpa_supplicant_8_lib,并在该目录下添加driver_cmd_nl80211.c和driver_cmd_wext.c

      这两个源文件我是从1-trunk\hardware\realtek\wlan\wpa_supplicant_8_lib直接拷贝过来使用的,因为我买的模块是成品,卖家根本没有提供。幸运的是,直接拷贝的这两个文件是能用的。然后修改下Android.mk,把这两个文件编入lib_driver_cmd_MediaTek.so

          LOCAL_MODULE := lib_driver_cmd_MediaTek

4、1-trunk\frameworks\opt\net\wifi\service\Android.mk 修改

        ifeq ($(BOARD_WLAN_DEVICE), bcmdhd)
  LIB_WIFI_HAL := libwifi-hal-bcm
else ifeq ($(BOARD_WLAN_DEVICE), qcwcn)
  LIB_WIFI_HAL := libwifi-hal-qcom
else ifeq ($(BOARD_WLAN_DEVICE), mrvl)
  # this is commented because none of the nexus devices
  # that sport Marvell's wifi have support for HAL
  # LIB_WIFI_HAL := libwifi-hal-mrvl
else ifeq ($(BOARD_WLAN_DEVICE), MediaTek)
  # support MTK WIFI HAL
  LIB_WIFI_HAL := libwifi-hal-mt66xx

endif

改为:

ifeq ($(BOARD_WLAN_DEVICE), bcmdhd)
  LIB_WIFI_HAL := libwifi-hal-bcm
else ifeq ($(BOARD_WLAN_DEVICE), qcwcn)
  LIB_WIFI_HAL := libwifi-hal-qcom
else ifeq ($(BOARD_WLAN_DEVICE), mrvl)
  # this is commented because none of the nexus devices
  # that sport Marvell's wifi have support for HAL
  # LIB_WIFI_HAL := libwifi-hal-mrvl
else ifeq ($(BOARD_WLAN_DEVICE), MediaTek)
  # support MTK WIFI HAL
  LIB_WIFI_HAL := libwifi-hal

endif

freescale给的源码里面居然有MediaTek分支,可能是freescale调试过mediatek的芯片,但是同样的,卖家没有给我libwifi-hal-mt66xx库,所以hal库只好改成默认的。好像也没有什么影响。


5、1-trunk\hardware\libhardware_legacy\wifi\Android.mk中添加

else ifeq ($(BOARD_WLAN_VENDOR), MediaTek)
 LOCAL_SRC_FILES += wifi/wifi_mediatek.c
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../external/wpa_supplicant_8/src/common

       然后将wifi_mediatek.c 拷贝到目录(1-trunk\hardware\libhardware_legacy\wifi)底下,这个是编译到libhardware_legacy.so库,最终在wifi-service中提供JNI调用,供android层调用。这里面实现的接口主要是:

        wifi_load_driver  (加载驱动)

        wifi_unload_driver  (卸载驱动)

        wifi_start_supplicant   (启动wpa_supplicant服务)

        wifi_stop_supplicant    (关闭wpa_supplicant服务)

        ......

      参照一下原有的wifi.c文件,改成mt7601u可用的就行了,并命名为wifi_mediatek.c

6、启动脚本修改

       1-trunk\device\fsl\sabresd_6dq\init.rc 修改

service wpa_supplicant /system/bin/wpa_supplicant \
   -iwlan0 -Dwext -c/system/etc/wifi/wpa_supplicant.conf \
   -I/system/etc/wifi/wpa_supplicant_overlay.conf

因为现在多数wifi支持的是nl80211 driver,但是github上大神提供的驱动并不支持这个,因此上wpa_supplicant官网上看了,后来改成wext driver方式试试,发现的确是可以使用。

      1-trunk\system\core\rootdir\init.rc 修改

    添加以下语句

# Prepare for wifi
chmod 777 /data/misc/keystore
mkdir /data/misc/dhcp 0770 dhcp dhcp
chown dhcp dhcp /data/misc/dhcp
mkdir /system/etc/wifi 0777 wifi wifi
chmod 777 /system/etc/wifi
chmod 777 /system/etc/wifi/wpa_supplicant.conf
chown wifi wifi /system/etc/wifi/wpa_supplicant.conf
mkdir /data/misc/wifi 0777 wifi wifi
mkdir /data/misc/wifi/sockets 0770 wifi wifi
chmod 777 /data/misc/wifi
chmod 777 /data/misc/wifi/wpa_supplicant.conf
chmod 777 /data/misc/wifi/p2p_supplicant.conf
chown wifi wifi /data/misc/wifi
chown wifi wifi /data/misc/wifi/wpa_supplicant.conf

否则android启动wpa_supplicant服务时会有权限问题,导致服务起不来


这一切都修改好以后,直接编译固件,下载到板子上,在设置--wifi选项中直接点开toggle,就可以看到模块搜索到附近的AP,选一个可用的连上OK。


参考资料:

http://blog.csdn.net/armeasy/article/details/6566462


你可能感兴趣的:(USB wifi模块mt7601U移植至imx 6q android 6.0平台)