嵌入式ARM(Allwinner H3)下使用rtl8188eus无线网卡



###你好!这里是风筝的博客,

###欢迎和我一起多多交流。


最近做东西,需要网络传输数据,所以在淘宝买了一款usb 网卡来使用:
板子:allwinner h3 (sun8i)
Linux:4.14
买回来的USB无线网卡芯片型号为rtl8188eus,本来想去他的官网下驱动源码的,结果他的官网居然没有了源码放出来,也许是这块芯片太老了吧…
后在我在github上找到了一些rtl8188的驱动源码:
https://github.com/quickreflex/rtl8188eus
适用于Linux4.x的源码,刚好合适我。
编译:
vi Makefile:
修改如下:

@@ -87,7 +87,7 @@
######### Notify SDIO Host Keep Power During Syspend ##########
CONFIG_RTW_SDIO_PM_KEEP_POWER = y
###################### Platform Related #######################
-CONFIG_PLATFORM_I386_PC = y
+CONFIG_PLATFORM_I386_PC = n
CONFIG_PLATFORM_ANDROID_X86 = n
CONFIG_PLATFORM_JB_X86 = n
CONFIG_PLATFORM_ARM_S3C2K4 = n
@@ -122,7 +122,7 @@
CONFIG_PLATFORM_ARM_SUNxI = n
CONFIG_PLATFORM_ARM_SUN6I = n
CONFIG_PLATFORM_ARM_SUN7I = n
-CONFIG_PLATFORM_ARM_SUN8I = n
+CONFIG_PLATFORM_ARM_SUN8I = y
CONFIG_PLATFORM_ACTIONS_ATM702X = n
CONFIG_PLATFORM_ACTIONS_ATM705X = n
CONFIG_PLATFORM_ACTIONS_ATV5201 = n
@@ -1234,9 +1234,10 @@
endif

ARCH := arm
-CROSS_COMPILE := /home/android_sdk/Allwinner/a23/android-jb42/lichee/out/an droid/common/buildroot/external-toolchain/bin/arm-linux-gnueabi-
-KVER := 3.4.39
-KSRC :=/home/android_sdk/Allwinner/a23/android-jb42/lichee/linux-3.4
+CROSS_COMPILE := /usr/local/arm/opt/FriendlyARM/toolschain/4.9.3/bin/arm-co rtexa9-linux-gnueabihf-
+KVER := 4.12
+KSRC :=/work/system/nanopi/linux
+MODULE_NAME := wlanrtl8188
endif

但是很可惜,make发生错误:

/work/system/nanopi/apply/rtl8188/rtl8188eus/core/rtw_ap.c:3200:2: error: implicit declaration of function ‘adapter_mac_addr’ [-Werror=implicit-function-declaration]
  u8 *addr = adapter_mac_addr(padapter);
rtl8188/rtl8188eus/core/rtw_ap.c:3202:2: error: implicit declaration of function ‘rtw_iface_bcmc_id_get’ [-Werror=implicit-function-declaration] cam_id = rtw_iface_bcmc_id_get(padapter);

我也不知道这个怎么解决。
后来我尝试换低一点的版本:比如我下载来的:rtl8188eus驱动源码
这个是个好东西,待会再说这个。
github上也有好几个rtl8188的驱动源码,我没试过,应该有几个也是正好合适我这个版本的,有兴趣的可以多下载几个试试。
先说我下载的这个版本低一点的驱动源码,同样的修改Makefile,make之后发现:

include/osdep_service.h:342:2: error: implicit declaration of function ‘allow_signal’ [-Werror=implicit-function-declaration]
  allow_signal(SIGTERM);

解决办法:

+ *** a/include/osdep_service.h 2015-04-17 09:54:43.000000000 +0300
+ --- b/include/osdep_service.h 2017-05-28 11:12:26.723593001 +0300

#ifndef __OSDEP_SERVICE_H_
#define __OSDEP_SERVICE_H_
 
+ #include 
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
+ #include 
+ #endif

#define _FAIL 0
#define _SUCCESS 1

但是后面还有一些错误,我也解决不了,太麻烦了。。。。。。

幸好,我发现我这Linux4.14的内核是支持,我在Ubuntu PC上lsusb,发现设备PID是0x8179:
在Linux源码下
cd drivers/net/wireless/
grep “0x8179” * -wnr
发现:

realtek/rtlwifi/rtl8188ee/sw.c:382:	{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8179, rtl88ee_hal_cfg)},

所以他的驱动就是在drivers/net/wireless/realtek/rtlwifi/rtl8188ee目录下。

配置如下:
make menuconfig

Bus support  ---> [*] PCI support 
Device Drivers  ---> [*] Staging drivers  ---> <*>   Realtek RTL8188EU Wireless LAN NIC driver
Device Drivers  ---> [*] Network device support  --->[*]   Wireless LAN  ---><*>     Realtek rtlwifi family of devices  ---><*>   Realtek RTL8188EE Wireless Network Adapter
Device Drivers  ---> [*] Network device support  ---><*>   USB Network Adapters  ---><*>   USB RTL8150 based ethernet device support  
[*] Networking support  --->  -*-   Wireless  --->  <*>   Generic IEEE 802.11 Networking Stack (mac80211)

这里我是把它配置成*,编进内核。
其中值得注意的是:
Device Drivers —> [] Staging drivers —> <> Realtek RTL8188EU Wireless LAN NIC driver
这里,Staging drivers表示的是正在测试,不稳定的驱动,所以Realtek RTL8188EU Wireless LAN NIC driver的depend on里写为m,所以这项最多被配置成 M 作为模块加载。

所以我用了一个很暴力的方法:
vi drivers/staging/rtl8188eu/Kconfig
把 depends on m 这句直接注释掉了、
这样就能把Realtek RTL8188EU Wireless LAN NIC driver直接配置成* 编进内核了。
这样我们加载Linux之后,插上usb 网卡就发现:

usb 4-1.4: new high-speed USB device number 3 using ehci-platform
usb 4-1.4: New USB device found, idVendor=0bda, idProduct=8179
usb 4-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 4-1.4: Product: 802.11n WLAN NIC
usb 4-1.4: Manufacturer: Realtek
Chip Version Info: CHIP_8188E_Normal_Chip_TSMC_A_CUT_1T1R_RomVer(0)

发现wlan0:

/ # cat /proc/net/wireless 
Inter-| sta-|   Quality        |   Discarded packets               | Missed | WE
 face | tus | link level noise |  nwid  crypt   frag  retry   misc | beacon | 22
 wlan0: 0000    0.    0.    0.       0      0      0      0      0        0

当然,ifconfig wlan0 up之后 ifconfig 命令也可以查看到wlan0、但是还需要固件支持:我上传了固件:rtl8188eus固件下载
当然,也可以去网站下载:https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/stats/
将固件放到根文件系统的/lib/firmware/rtlwifi/目录下即可

现在算是初步完成了,接下来我们要使用这个网卡,需要一点配置工具。
这里就提到我之前找的那个版本低一点的驱动网卡源码了,里面有wireless_tools非常好用:
rtl8188eus驱动源码
解压好源码:
cd wireless_tools/wireless_tools.30.rtl/
vi Makefile,修改Makefile、
其中:
CC = gcc
AR = ar
RANLIB = ranlib
改为
CC = arm-linux-gcc
AR = arm-linux-ar
RANLIB = arm-linux-ranlib
之后直接make就可以了,非常的方便,直接编译成功,不需要你自己去编译多余的依赖。
编译完成后,将生成的iwconfig,iwlist文件拷贝到根文件系统中的/bin目录下,
将iwlib.so拷贝到根文件系统中的/lib目录下。
这样我们就可以使用了:

iwlist scanning

扫描附件的热点。
假如我要连接一个热点,热点ssid:fengzheng,passwd:18290019557

iwconfig wlan0 key 18290019557
iwconfig wlan0 essid "fengzheng"
iwconfig wlan0 ap auto

值得一提的是,iw命令只能连接加密方式为wep或者无加密的热点。
如果连接wpa2的热点,则报错:

Error for wireless request "Set AP Address" (8B14) : SET failed on device wlan0

如果想自己下载iw,下载地址如下:https://w1.fi/wpa_supplicant/

如果想连接加密认证方式为wpa的热点,这需要下载wpa_supplicant,wpa_supplicant 是一个开源软件项目,它实现了 Station 对无线网络进行管理和控制的功能。
下载网址如下:https://w1.fi/wpa_supplicant/
当然,这也是比较麻烦的,他需要一些依赖库。比如openssl,比较麻烦,
所以还是我之前下载的那个好,里面自带了一些wireless tools,就包括了这个wpa_supplicant。
解压:tar -xzvf wpa_supplicant_hostapd-0.8_rtw_r7475.20130812.tar.gz
cd wpa_supplicant_hostapd-0.8_rtw_r7475.20130812/wpa_supplicant/
vi Makefile

if xxxx
CC=gcc
endif
修改为
CC=arm-linux-gcc
然后
cp …/…/wpa_0_8.conf .
之后直接
make
make DESTDIR=$PWD/tmp install
这样,在当前目录下的tmp目录下就是我们的安装路径了。
把里面三个可执行文件wpa_cli wpa_passphrase wpa_supplicant都复制到根文件的/bin目录下即可、
连接热点:
mkdir -p /var/run/wpa_supplicant
vi /etc/wpa_supplicant.conf
内容为:
ctrl_interface=/var/run/wpa_supplicant
network={
ssid=“fengzheng”
psk=“18290019557”
}

最后:
wpa_supplicant -B -c/etc/wpa_supplicant.conf -iwlan0
即可连接上热点、如果出现错误:

nl80211: Driver does not support authentication/association or connect commands
nl80211: deinit ifname=wlan0 disabled_11b_rates=0
wlan0: Failed to initialize driver interface

则命令修改为:
wpa_supplicant -B -c/etc/wpa_supplicant.conf -iwlan0 -D wext
即可连上热点。参考:https://wiki.archlinux.org/index.php?title=WPA_supplicant_(简体中文)&oldid=452628

wpa_cli -iwlan0 status 可以查看连接状态。
ifconfig wlan0 192.168.43.110
ping 192.168.43.1
发现是能ping通我的热点的,大功告成。
但是此时还不能连接外网,需要修改/etc/resolv.conf添加DNS:
nameserver 192.168.43.1
设置网关:
route add default gw 192.168.43.1

或者使用命令:
udhcpc -i wlan0
可以自动获取ip,
或者自己下dhclient来用吧。

或者想实现开机自动连接wifi:
在etc/profile文件里添加:

wpa_supplicant -B -c/etc/wpa_supplicant.conf -iwlan0 -D wext
wpa_cli -a/sbin/wpa_action.sh -B

接着创建/sbin/wpa_action.sh脚本:

#!/bin/sh
IFNAME=$1
CMD=$2
if [ "$CMD" = "CONNECTED" ]; then
   echo connect $IFNAME, dhclient for it > /dev/console
   udhcpc -i $IFNAME
#dhclient $IFNAME
fi
if [ "$CMD" = "DISCONNECTED" ]; then
   echo disconnect $IFNAME, kill dhclient for it > /dev/console
   killall udhcpc
#killall dhclient
fi

记得要给脚本运行权限:chmod +x /sbin/wpa_action.sh