class="markdown_views prism-atom-one-light">
本文所用开发板:tiny4412,当然也可以在jz2440上实现。
嵌入式中设备想要联网,无非就 有线和无线 两种方式。
有线就插上网线,没什么好说的;无线的话一种是将WIFI模块集成焊接在板子上,另一种是WIFI模块以USB的方式接到板子上。
本次使用的就是USB接口的WIFI无线网卡,实现开发板使用WIFI无线网卡访问互联网和作为个人热点。
1.准备工作
1.2 WIFI基础知识
WIFI网卡有两种工作模式,
一种是
无线终端模式(STA) ,也就是手机日常使用的模式,通过该模式连接网络上网;
一种是
无线热点模式(AP) ,也就是手机的个人热点模式,通过该模式提供热点供其它设备上网;
无线网络的安全性由两部分组成:
认证 和
加密 。
认证: 使得只有允许的设备才能连接到无线网络;
加密: 确保数据的保密性和完整性,即数据在传输过程中不会被篡改;
常用的认证算法有:开放认证、共享秘钥认证、802.11x认证、PSK认证 。
其中802.11x认证和PSK认证安全性较高,分别应用于企业和个人的环境;
常用的加密算法有:WEB加密、TKIP加密、CCMP加密算法 。
其中WEB加密和TKIP加密都是RC4的加密算法,安全性较低;CCMP加密采用AES对称加密算法,安全性较高。
安全策略 认证方式 加密方式 备注 Openopenopen开放WiFi,无任何加密openWEP开放WiFi,仅数据加密WEPWEPWEP共享密钥认证,容易破解WAP802.11XTKIP/WEP比较安全,用于企业PSKTKIP/WEP比较安全,用于个人WAP2802.11XCCMP/TKIP/WEP目前最安全,用于个人PSKCCMP/TKIP/WEP目前最安全,用于个人
连入超市、商场等公共WIFI的时候,不需要输入密码,但要通过网页输入手机号,使用验证码验证,也就是采用802.11X进行的验证,通过服务器完成的验证。
使用手机开个人热点的时候,可以选择安全性OPEN、WEP、WAP、WAP2,也就对应不同的安全等级。
我手里的MIX2S,MIUI10个人热点里面就仅OPEN和WAP2两个选项,感觉这是个趋势,要么最简单的OPEN,要么就最安全的WAP2(WAP2是向下兼容的),逐渐扔掉历史的包袱。
1.2 选择无线网卡
首先是选择合适的无线网卡,选取的原则是
根据WIFI无线网卡的VID
和PID
判断内核是否支持该无线网卡。
1.获取无线网卡ID
将无线网卡插入Windows电脑,打开设备管理器,选中无线网卡,右键“属性”,切换到“详细信”息选项卡,在“属性”下拉栏中选择"硬件ld",即可得到无线网卡的ID:
我的无线网卡VID
是0x148F
,PID
是0x3070
;
2.查询内核是否支持
可以从wireless.kernel.org 得到支持的设备列表 。
可以从列表中搜到前面的VID
和PID
,因此说明内核是支持现在使用的无线网卡。此外,还可以得知对应的驱动应该为rt2800usb
、rt2870sta
。
1.3 移植WIFI驱动
前面根据ID得到了对应的网卡驱动名字,但还不是很靠谱,建议直接在驱动中搜索ID,更靠谱:
grep "0x3070" drivers/net/wireless/ -nr
得到:
drivers/net/wireless/ralink/rt2x00/rt2800usb.c:1091: { USB_DEVICE(0x148f, 0x3070) },
知道了对应的驱动文件是
rt2800usb.c
;
cat drivers/net/wireless/ralink/rt2x00/Makefile
得到:
obj-$(CONFIG_RT2800USB) += rt2800usb.o
,
知道了对应的宏是
CONFIG_RT2800USB
;
make menuconfig
搜索
CONFIG_RT2800USB
,得知其依赖:
Depends on: NETDEVICES [=y] && WLAN [=y] && WLAN_VENDOR_RALINK [=y] && RT2X00 [=n] && USB [=y]
,
可以知道
RT2X00 [=n]
没有打开,再搜索它,如此循环,直到
RT2800USB [=y]
。
这里有个注意的就是,当开启的上层的某个依赖,下层的某个选项可能会多出来许多选项,而这些选项原来是没有的,不要固化思维。
最后重新编译内核即可。
1.4 使用buildroot移植应用
想要使用无线网卡,需要用到四个软件:
**iw:**可用于OPEN、WEP这两种"认证/加密",以及扫描WIFI热点等;
**- wpa_supplicant:**可用于前面4种"认证/加密";
**hostapd:**能够使得无线网卡切换为AP模式;
dhcp: STA模式使WIFI网卡动态获取IP,AP模式分配IP;
也就是需要移植这四个软件,目前的方法有:
**1.**逐个下载源码,交叉编译,配置,可以还需要相关依赖库,缺点是费时费力;
**2.**使用
Yocto
等工具,制作发行版的根文件系统,例如Ubuntu16.04,里面有apt-get,可以自动下载安装,缺点是制作发行版根文件系统比较麻烦,且体积较大;
**3.**使用
buildroot
制作根文件系统,选择需要的软件,自动生成根文件系统,相对简单,体积也较小;
本次就以buildroot为例,制作包含应用程序的根文件系统。
首先从GitHub下载针对Tiny4412修改后的buidroot
git clone -b board_tiny4412 https://github.com/hceng/buildroot.git
cd buildroot/
make list-defconfigs
得知tiny4412对应的配置文件:
tiny4412_defconfig - Build for tiny4412
;
make tiny4412_defconfig
make menuconfig
对应勾选所需软件:
Target packages --->
Networking applications --->
[*] dhcp (ISC)
[*] dhcp server
[*] Enable delayed ACK feature
[*] dhcp relay
[*] dhcp client
……
[*] hostapd
[*] Enable ACS (NEW)
[*] Enable EAP
[*] Enable WPS
……
[*] iw
……
[*] wpa_supplicant
[*] Enable nl80211 support
[*] Enable AP mode
[ ] Enable EAP
[ ] Enable HS20
[ ] Enable syslog support
[ ] Enable WPS
[*] Install wpa_cli binary
[*] Install wpa_client shared library
[*] Install wpa_passphrase binary
System configuration --->
(tiny_4412) System hostname
(Welcome to hceng's board.) System banner
……
[*] Enable root login with password
(123456) Root password
make
buildroot
会自动下载相关源码包,整个过程时间比较久,最后生成
buildroot/output/images/rootfs.tar
,解压到SD卡rootfs分区即可。
1.5 添加firmware
此时开发板启动Linux后,使用
ifconfig wlan0 up
启动无线网卡,提示:
ieee80211 phy0: rt2x00lib_request_firmware: Info - Loading firmware file 'rt2870.bin'
rt2800usb 2-2.2:1.0: Direct firmware load for rt2870.bin failed with error -2
ieee80211 phy0: rt2x00lib_request_firmware: Error - Failed to request Firmware
ifconfig: SIOCSIFFLAGS: No such file or directory
提示需要firmware文件
rt2870.bin
。
继续通过网站
wireless.wiki.kernel.org 去下载
该固件 。
得到
rt2870.bin
后,拷贝到单板
/lib/firmware/
下即可。
1.6 启动WIFI网卡
注意:
双网卡的单板的两个网卡IP不能设置为同一网段。原因参考:(https://www.zhihu.com/question/41331151 )。
也就是先把有线网卡IP设置为其它网段,比如:
ifconfig eth0 192.168.2.220
然后启动WIFI网卡,并设置IP(路由器IP为192.168.1.1):
ifconfig wlan0 up
ifconfig wlan0 192.168.1.220
此时效果如下:
2.无线终端模式——STA
完成前面的准备工作后,就可以通过软件使用无线网卡了。
2.1 iw的使用
iw list
iw dev wlan0 scan
iw dev wlan0 scan | grep SSID:
iw wlan0 connect hceng
iw dev wlan0 link
iw wlan0 disconnect
还可以连接加密的WEP,这里就不研究了。
注意:
1.如果连接的不是路由器(IP为192.168.1.1
),而是Android手机热点(IP一般为192.168.43.1
),那么要将WIFI网卡IP设置为43网段,如:192.168.43.10
,才能ping通192.168.43.1
。
2.此时只能ping路由器和局域网设备,如果要联外网,还需要如下操作:
①修改/etc/resolv.conf
,添加DNS:nameserver 192.168.1.1
,如果是手机热点为nameserver 192.168.43.1
;
②设置网关,输入命令:route add default gw 192.168.1.1
,如果是手机热点为route add default gw 192.168.43.1
;
2.2 wpa_supplicant的使用
wpa_supplicant
本是开源项目,被谷歌修改后加入android移动平台,它主要是用来支持WEP,WPA/WPA2和WAPI无线协议和加密认证的。
wpa_supplicant
是一个连接、配置WIFI的工具,它主要包含
wpa_supplicant
(命令行模式)与
wpa_cli
(交互模式)两个程序。
通常情况下,可以通过
wpa_cli
来进行WIFI的配置与连接,如果有特殊的需要,可以编写应用程序直接调用
wpa_supplicant
的接口直接开发。
记得以前想查看Android手机连接过的WIFI热点密码时,就直接使用RE文件管理器查看
/data/misc/wifi/wpa_supplicant.conf
即可(需ROOT),里面有所有连接过的WIFI名字和密码。
从这里可以看出,最后WIFI名字和密码,都会被保存到一个配置文件里,在Linux中,路径就是
/etc/wpa_supplicant.conf
。
连接开放网络
向/etc/wpa_supplicant.conf
加入:
network={
ssid="hceng"
key_mgmt=NONE
}
初始化wpa_supplicant,执行:
wpa_supplicant -B -d -i wlan0 -c /etc/wpa_supplicant.conf
查看连接状态:
wpa_cli -iwlan0 status
断开连接:
wpa_cli -iwlan0 disconnect
killall wpa_supplicant
重新连接:
wpa_cli -iwlan0 reconnect
连接加密网络(WAP2)
向/etc/wpa_supplicant.conf
加入:
network={
ssid="hceng_test"
psk="12345678"
}
初始化wpa_supplicant,执行:
wpa_supplicant -B -d -i wlan0 -c /etc/wpa_supplicant.conf
至于WEP和WAP方式,也就是配置文件的不同,这里就不去深究了,以后遇到了再说。
2.3 dhclient的使用
至此,已经可以连接WIFI了,但还有一些问题。
就如前面,需要手动设置设备的IP,且要根据热点的网段设置,还可能与同网段的设备IP冲突。
为了解决这个问题,引入了DHCP,自动分配IP地址。
就像家里的设备连接到路由器一样,除了输入名字,密码,其它都不用操作,而且还不会出现IP冲突的情况。
连接好WIFI后,输入:
dhclient wlan0
实现自动获取分配的IP,并设置。
2.4 自动脚本
现在已经从功能上实现了WIFI无线网卡的使用,但使用过程步骤比较多,相对麻烦。
理想的效果无论何时插上WIFI无线网卡,都自动连接WIFI,且自动获取IP地址。
这就要用到USB的热拔插机制,很久以前写过一篇
U盘自动挂载 的文章,用的就是这个机制。
1.首先修改/etc/mdev.conf
配置文件
加入WIFI无线网卡的热拔插事件:
# hceng add for wifi
wlan0 root:root 660 * /sbin/auto_wifi.sh
其中
*
表示插拔都执行后面的脚本。
2.自动连接脚本/sbin/auto_wifi.sh
但检测到USB网卡插拔后,就会执行该脚本:
#!/bin/sh
if [ $ACTION = "add" ];
then
echo --------usb wifi connect--------- > /dev/console
wpa_supplicant -B -d -i wlan0 -c /etc/wpa_supplicant.conf
wpa_cli -B -i wlan0 -a/sbin/auto_dhcp.sh
else
echo --------usb wifi disconnect--------- > /dev/console
killall wpa_supplicant
killall wpa_cli
killall dhclient
fi
如果是插入USB无线网卡,将执行
wpa_supplicant -B -d -i wlan0 -c /etc/wpa_supplicant.conf
连接wifi,再执行
wpa_cli -B -i wlan0 -a/sbin/auto_dhcp.sh
调用dhcp的脚本;
如果是拔出USB无线网卡,将清除所有相关进程;
3.自动dhcp脚本/sbin/auto_dhcp.sh
#!/bin/sh
IFNAME=$1
CMD=$2
if [ "$CMD" = "CONNECTED" ]; then
echo ========connect $IFNAME, dhclient for it======= > /dev/console
dhclient $IFNAME
fi
if [ "$CMD" = "DISCONNECTED" ]; then
echo ========disconnect $IFNAME, kill dhclient for it======= > /dev/console
killall dhclient
fi
如果是连接,将调用
dhclient
分配IP,反之清除
dhclient
进程。
chmod +x /sbin/auto_wifi.sh
chmod +x /sbin/auto_dhcp.sh
最后便可实现自动连接WIFI,且自动获取IP地址。
3.无线热点模式——AP
无线热点模式共需要两步操作,先使用
hostapd
将无线网卡切换成AP模式,再使用
dhcpd
分配IP。
3.1 hostapd的使用
先清除前面STA模式的所有操作,重新启动单板。
1.OPEN模式:
ctrl_interface=/var/run/hostapd
ssid=hceng
channel=1
interface=wlan0
driver=nl80211
2.WAP/WAP2模式:
ctrl_interface=/var/run/hostapd
ssid=hceng
#hw_mode=g
channel=1
interface=wlan0
#bridge=br0
driver=nl80211
macaddr_acl=0
#accept_mac_file=/etc/hostapd.accept
#deny_mac_file=/etc/hostapd.deny
auth_algs=1
wpa=3
wpa_passphrase=12345678
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
注释 :
ctrl_interface
:为了后面hostapd_cli
链接上hostapd
;
ssid
:无线热点名字;
hw_mode
:指定802.11协议 ,其中a=IEEE 802.11a
,b=IEEE 802.11b
, g=IEEE 802.11g
;
channel
:设定无线信道 ;
interface
:指定使用哪一个无线网卡;
bridge
:指定所处网桥,对于一个同时接入公网、提供内部网和无线接入的路由器来说,设定网桥很有必要;
driver
:指定无线驱动;
macaddr_acl
:指定MAC地址过滤规则:
0表示允许除禁止列表外的设备;
1表示只允许在允许列表的设备;
2表示使用外部RADIUS服务器;
accept_mac_file
:指定允许MAC列表文件所在路径;
deny_mac_file
:指定禁止MAC列表文件所在路径;
auth_algs
:指定采用哪种认证算法,采用位域(bit fields)方式来制定;
1表示使用WPA;
2表示使用WEP;
3表示使用WPA/WEP;
wpa
:指定WPA类型,采用位域(bit fields)方式来制定;
1表示使用WPA;
2表示使用WPA2;
3表示使用WPA2/WPA;
wpa_passphrase
:WIFI的密钥;
wpa_key_mgmt
:PSK为个人AP,不使用服务器认证;
wpa_pairwise
:指定WPA的加密方式;
rsn_pairwise
:指定WPA2的加密方式;
3.2 dhcpd的使用
如果此时启动热点,实测手机一直卡在获取IP地址,无法连接到热点,因此热点还需自动分配IP地址。
subnet 192.168.2.0 netmask 255.255.255.0 {
range 192.168.2.10 192.168.2.100;
option domain-name-servers 192.168.2.1;
option routers 192.168.2.1;
}
指定了子网IP起始地址、子网掩码、动态分配的IP范围、DNS服务器、路由。
3.3 启动热点
ifconfig wlan0 up
ifconfig wlan0 192.168.2.1
hostapd -B /etc/hostapd.conf
dhcpd -cf /etc/dhcpcd.conf wlan0
对应的停止命令:
killall hostapd
killall dhcpd
hostapd_cli all_sta
查看热点配置:
hostapd_cli get_config
查看已连接的设备:
iw dev wlan0 station dump
3.4 自动脚本
和前面的一样,假如希望实现USB无线网卡的热拔插,自动进入AP模式,只需如下操作:
1.首先修改/etc/mdev.conf
配置文件
加入WIFI无线网卡的热拔插事件:
# hceng add for wifi
#wlan0 root:root 660 * /sbin/auto_wifi.sh
wlan0 root:root 660 * /sbin/auto_wifi_ap.sh
2.自动AP脚本/sbin/auto_wifi_ap.sh
但检测到USB网卡插拔后,就会执行该脚本:
#!/bin/sh
if [ $ACTION = "add" ];
then
echo --------usb wifi connect--------- > /dev/console
hostapd -B /etc/hostapd.conf
ifconfig wlan0 192.168.2.1
dhcpd -cf /etc/dhcpcd.conf wlan0
else
echo --------usb wifi disconnect--------- > /dev/console
killall hostapd
killall dhcpd
fi
chmod +x /sbin/auto_wifi_ap.sh
之后插上无线网卡,自动启动热点;拔掉无线网卡,自动关闭热点。
参考教程 :韦东山第3期视频之WiFi网卡移植
关注公众号baiwenkeji第一时间获得嵌入式干货。
技术交流加个人威信13266630429,验证:CSDN博客