文章目录
1.介绍
本文章在瑞芯微RV1103芯片移植了RTL8723BS模块的WIFI部分,实现了网络的链接。教程应该适配RV1103、RV1106、RV1126、RK3588等瑞芯微的芯片,对其他arm架构的Linux芯片的瑞昱WIFI移植也具有参考价值。
可以直接使用的SDK在最后一个章节。
- 平台介绍: 主控芯片为RV1103。
- SDK: 幸狐Luckfox的SDK V1.3
- WIFI模块: RTL8723BS是一个集成了蓝牙和WIFI的模块。
2.电路接口介绍
WL_REG_ON(WL_DIS): WIFI使能引脚,休眠的时候,请保持GPIO上电,否则会丢失WiFi内部的状态,导致WiFi唤醒失败;3.3V供电。
WL_HOST_WAKE: 主要用于WiFi设备有数据的时候,唤醒CPU,进入中断。
CLK信号: HOST给DEVICE的 时钟信号,每个时钟周期传输一个命令。
CMD信号:SDIO双向控制信号,在外设挂载上的适合,CPU会发一段信号给WIFI,同时WIFI回应则表示连接成功,调试先看有没有这个。
DAT0-DAT3 信号: 四条用于传送的数据线。
XTAL_OUT/TAL_IN: 外部晶振(与wifi和天线输出频率有关,不同WIFI时钟不同)
3.修改内核
配置WIFI的第二部需要修改内核,瑞芯微可以直接在内核中修改支持WIFI功能,可以在SDK根目录直接通过指令./build.sh kernelconfig
直接打开内核配置界面。
3.1 cfg80211
cfg80211 是 Linux 内核中用于无线局域网(WLAN)设备配置和管理的子系统。它提供了一个通用的、统一的接口,用于各种无线驱动和上层应用之间的通信。主要包含如下组件:
- nl80211 (Netlink 802.11) 是 cfg80211 的用户空间接口,通过 Netlink 套接字提供了一组命令和事件,用于配置和控制无线设备。它允许用户空间应用(如 wpa_supplicant)与内核中的 cfg80211 子系统进行通信。
- wiphy(Wireless Physical) 无线物理设备。每个无线物理设备都有一个唯一的标识(wiphy_idx),并包含了一些与无线设备相关的属性和操作函数,如支持的频段、支持的无线模式、驱动程序信息等。
- wdev(Wireless Device) Wireless Device 的缩写,表示一个无线设备(可能是虚拟的)。每个无线设备都有一个唯一的标识(wdev_id),并且 cfg80211 为其提供了一组操作函数,用于配置和管理无线设备。
此外还包含一些API接口,用于操作无线网络,负责处理各种无线配置请求,如扫描、连接、断开连接、设置安全参数等。
3.2 驱动配置
配置无线驱动程序,M表示将驱动编译成模块,可以通过insmod
函数加载到内核中。
3.3 rfkill
rfkill是Linux内核中的一个子系统,用于管理系统中无线电设备的开关状态。RF代表“射频”(Radio Frequency),而kill则指的是关闭或禁用这些射频设备。rfkill提供了一个接口,允许用户查询、激活和取消激活计算机系统中的无线电设备,如Wi-Fi、蓝牙等。这三个全都都要开启。
4.增加buildroot软件包
修改buildroot可以通过指令./build.sh buildrootconfig
,这个是也是1.3版本的SDK新加入的。这个部分也可以选择下载源码,自行交叉编译,不过倒是没有buildroot方便。
4.1 iw(可不选)
无线设备交互的命令行工具, iwlib 库的一部分,专为新的无线子系统(如 cfg80211 和 mac80211)设计。不过可选可不选,因为旧的指令ifconfig
也是可以用的,可以用来打开、关闭和管理WIFI的连接。
4.2 wpa_supplicant
经过编译后的wpa_supplicant源程序主要包括两个可执行工具:wpa_supplicant和wpa_cli。
- wpa_supplicant:作为核心服务程序在后台运行,处理网络连接的认证、加密等任务。
- wpa_cli:作为wpa_supplicant的客户端工具,用户可以通过wpa_cli发送命令给wpa_supplicant,实现网络配置、扫描、连接等操作。
不过不支持所有类型的无线网卡驱动,可以看一下是否支持你的无线网卡的驱动。
wpa_supplicant里面所有选项都选上
4.3 wireless tools
wireless tools是linux的无线管理软件工具集,通过提供一组简单易用的命令行工具,帮助用户配置和管理支持Wireless Extension的无线设备。
4.4 保存
在配置好了buildroot之后千万不要clean,如果clean了的话就会没掉了。如果是用指令./build.sh buildrootconfig
的话会自动保存,然后到buildroot文件夹里面make
一下就能够把软件包全部下载下来,下载下来之后也能够加快SDK的编译速度。
5.修改设备树
配置完了内核之后,需要修改设备树,打开SDIO设备。这里可以看看自己的设备树的引脚配置和继承方式。
5.1 电源控制节点
增加一个SDIO电源控制节点,注意这里的使能引脚要和自己的电路对应,我的是因为WIFI使能引脚直接上拉了,所以就随便配置了一个,这个节点是必须要有的。
//不同电路可能这个节点配置不同,有些可能还需要配置时钟
sdio_pwrseq: sdio-pwrseq {
compatible = "mmc-pwrseq-simple";
pinctrl-names = "default";
reset-gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>;//随便给的
};
有些电路设计的时候可能还将wake等引脚连接到了CPU上,也需要自行定义设备控制节点。
5.2 追加节点属性
追加sdmmc节点,将其配置支持SDIO,其他的可以视自己的情况而定。
&sdmmc {
max-frequency = <50000000>; /* sdio接口的最大频率,可调整 */
bus-width = <4>; /* 4线模式 */
cap-sd-highspeed; /* 高速的 SDIO 外设 */
cap-sdio-irq; /* 此配置标识该 SDIO 外设(通常是 Wifi)是否支持 sdio 中断,如果你的外设是 OOB 中断, 请不要加入此项。支持哪种类型的中断请联系 Wifi 原厂确定。 */
keep-power-in-suspend; /* 休眠模式不掉电,WIFI一般都有深度唤醒的需求 */
non-removable; /* 设备不可移除 */
rockchip,default-sample-phase = <90>;/* 默认采样相位 90° */
// no-sd;
// no-mmc;
supports-sdio; /* 支持sdio */
mmc-pwrseq = <&sdio_pwrseq>; /* 电源配置项,必须要有 */
pinctrl-names = "default"; /* 否则 Wifi 无法上电工作 */
pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_bus4 &sdmmc0_det>;
status = "okay"; /* 设备开启 */
};
由于默认使能引脚已经拉高了,就没有再pinctrl里追加使能引脚。
5.3 sdmmc0_det引脚拉低
在pincrtl节点下
sdmmc0{
sdmmc0_det: sdmmc0-det {
rockchip,pins =
/* sdmmc0_det */
<3 RK_PA1 1 &pcfg_pull_down>;
};
};
6.配置build.sh脚本
build.sh脚本这里根据这个链接luckfox wiki配置就可以了,这里把我修改后的贴出来。
...
function build_app() {
check_config RK_APP_TYPE || return 0
if [ "$RK_ENABLE_WIFI" = "y" ]; then
echo "Set Wifi SSID and PASSWD"
check_config LF_WIFI_PSK LF_WIFI_SSID || return 0
touch $WIFI_NEW_CONF
cat >$WIFI_NEW_CONF <<EOF
ctrl_interface=/var/run/wpa_supplicant
ap_scan=1
update_config=1
network={
ssid="$LF_WIFI_SSID"
psk="$LF_WIFI_PSK"
key_mgmt=WPA-PSK
}
EOF
mv $WIFI_NEW_CONF $WIFI_CONF
fi
echo "============Start building app============"
echo "TARGET_APP_CONFIG=$RK_APP_DEFCONFIG $RK_APP_DEFCONFIG_FRAGMENT $RK_APP_TYPE"
echo "========================================="
build_meta --export # export meta header files
build_meta --export --media_dir $RK_PROJECT_PATH_MEDIA # for rtl8723bs
test -d ${SDK_APP_DIR} && make -C ${SDK_APP_DIR}
finish_build
}
...
...
function build_meta() {
msg_info "============Start building meta============"
if [ -n "$RK_META_SIZE" ]; then
if [ -d "${RK_PROJECT_TOP_DIR}/make_meta" ]; then
__meta_param="$RK_META_PARAM $RK_CAMERA_PARAM --meta_part_size=$RK_META_SIZE"
${RK_PROJECT_TOP_DIR}/make_meta/build_meta.sh $@ \
--cam_iqfile ${RK_CAMERA_SENSOR_IQFILES} \
--meta_param $__meta_param \
--output $RK_PROJECT_OUTPUT_IMAGE \
--rootfs_dir $RK_PROJECT_PACKAGE_ROOTFS_DIR \
--media_dir $RK_PROJECT_PATH_MEDIA \
--pc_tools_dir $RK_PROJECT_PATH_PC_TOOLS \
--tiny_meta $RK_TINY_META
fi
fi
finish_build
}
...
...
function __PACKAGE_ROOTFS() {
local rootfs_tarball rootfs_out_dir _target_dir _install_dir
rootfs_tarball="$RK_PROJECT_PATH_SYSDRV/rootfs_${RK_LIBC_TPYE}_${RK_CHIP}.tar"
if [ -f $rootfs_tarball ]; then
tar xf $rootfs_tarball -C $RK_PROJECT_OUTPUT
else
msg_error "Not found rootfs tarball: $rootfs_tarball"
exit 1
fi
build_get_sdk_version
cat >$RK_PROJECT_PACKAGE_ROOTFS_DIR/bin/sdkinfo <<EOF
#!/bin/sh
echo Build Time: $(date "+%Y-%m-%d-%T")
echo SDK Version: ${GLOBAL_SDK_VERSION}
EOF
chmod a+x $RK_PROJECT_PACKAGE_ROOTFS_DIR/bin/sdkinfo
__COPY_FILES $RK_PROJECT_PATH_APP/root $RK_PROJECT_PACKAGE_ROOTFS_DIR
__COPY_FILES $RK_PROJECT_PATH_MEDIA/root $RK_PROJECT_PACKAGE_ROOTFS_DIR
__COPY_FILES $SDK_ROOT_DIR/external $RK_PROJECT_PACKAGE_ROOTFS_DIR
if [ -d "$RK_PROJECT_PACKAGE_ROOTFS_DIR/usr/share/iqfiles" ]; then
(
cd $RK_PROJECT_PACKAGE_ROOTFS_DIR/etc
ln -sf ../usr/share/iqfiles ./
)
fi
if [ -f $RK_PROJECT_FILE_ROOTFS_SCRIPT ]; then
chmod a+x $RK_PROJECT_FILE_ROOTFS_SCRIPT
cp -f $RK_PROJECT_FILE_ROOTFS_SCRIPT $RK_PROJECT_PACKAGE_ROOTFS_DIR/etc/init.d
fi
}
...
7.SDK全局支持WIFI
在启动的BoardConfig-SPI_NAND-Buildroot-RV1103_Luckfox_Pico_Plus-IPC.mk文件里添加
export RK_ENABLE_WIFI=y
8.添加固件
- 固件链接
- 在SDK根目录下创建文件夹
/external/lib/firmware/rtlwifi
,这个跟脚本对应的 - 把下载的rtl8723bs_nic.bin固件放进去
9.WIFI测试
9.1 安装驱动
# 进入板子的根文件系统
# 安装驱动模块
cd /oem/usr/ko
insmod libarc4.ko
insmod cfg80211.ko
insmod mac80211.ko
insmod r8723bs.ko
终端输出结果如下
[root@luckfox root]$ cd /oem/usr/ko
[root@luckfox ko]$ insmod libarc4.ko
[root@luckfox ko]$ insmod cfg80211.ko
[ 60.092827] cfg80211: Loading compiled-in X.509 certificates for regulatory database
[ 60.117749] cfg80211: Problem loading in-kernel X.509 certificate (-22)
[ 60.118795] platform regulatory[root@luckfox ko]$ .0: Direct firmware load for regulatory.db failed with error -2
[ 60.118820] cfg80211: failed to load regulatory.db
insmod mac80211.ko
[root@luckfox ko]$ insmod r8723bs.ko
[ 74.532808] r8723bs: module is from the staging directory, the quality is unknown, you have been warned.
[ 74.544011] RTL8723BS: module init start
[ 74.544055] RTL8723BS: rtl8723bs v4.3.5.5_12290.20140916_BTCOEX20140507-4E40
[ 74.544064] RTL8723BS: rtl8723bs BT-Coex version = BTCOEX20140507-4E40
[ 74.544421] pnetdev = a3237ac8
[ 74.572254] RTL8723BS: rtw_ndev_init(wlan0)
[ 74.581794] RTL8723BS: module init ret =0
要注意rtw_ndev_init(wlan0)初始化就代表WIFI成功初始化。
在终端输入指令
ifconfig -a
输出下面的信息,可以看到wlan0即为无线网卡。
[root@luckfox ko]$ ifconfig -a
eth0 Link encap:Ethernet HWaddr 46:BC:18:F4:69:1F
BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Interrupt:45
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:1804 errors:0 dropped:0 overruns:0 frame:0
TX packets:1804 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:133388 (130.2 KiB) TX bytes:133388 (130.2 KiB)
usb0 Link encap:Ethernet HWaddr CE:EC:72:B8:50:F9
inet addr:172.32.0.93 Bcast:172.32.255.255 Mask:255.255.0.0
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
wlan0 Link encap:Ethernet HWaddr AC:35:EE:C7:A1:8F
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
9.2 开启WIFI
输入指令up,开启WIFI
[root@luckfox ko]$ ifconfig wlan0 up
[ 78.904174] rtl8723bs: acquire FW from file:rtlwifi/rtl8723bs_nic.bin
然后可以用iwlist wlan0 scan
查看一下周围的网络,会依次展示周围的网络信息,我这里用的是手机热点,网络名称为222。
Cell 06 - Address: BE:64:59:2E:6E:4A
ESSID:"222"
Protocol:IEEE 802.11bgn
Mode:Master
Frequency:2.437 GHz (Channel 6)
Encryption key:on
Bit Rates:144 Mb/s
Extra:rsn_ie =30140100000fac040100000fac040100000fac020c00
IE: IEEE 802.11i/WPA2 Version 1
Group Cipher : CCMP
Pairwise Ciphers (1) : CCMP
Authentication Suites (1) : PSK
Quality=100/100 Signal level=100/100
Extra:fm =0003
9.3 配置WIFI信息
vi /etc/wpa_supplicant.conf
配置为对应的你的网络,注意一个配置文件对应着一个连接。WIFI名称、密码和加密方式等都要正确。WIFI配置的文件说明链接。
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
ap_scan=1
network={
ssid="Dami"
scan_ssid=1
key_mgmt=WPA-PSK
pairwise=CCMP
group=CCMP
psk="7777"
priority=5
}
9.4 创建一个socket文件用于通信
路径和上面一样,递归创建文件夹
mkdir -p /var/run/wpa_supplicant
9.5 连接
关于wpa_supplicant工具使用方法在这里,可以用于管理你的WIFI。
直接终端输入命令
wpa_supplicant -B -c /etc/wpa_supplicant.conf -i wlan0
也可以这样连接
wpa_passphrase Dami 7777 > /etc/wpa_supplicant.conf
它会直接生成帐号密码文件,其中的wlan0是你使用的网卡,123456则是密码,后面的是把文件放在哪里。
连接成功后
Successfully initialized wpa_supplicant
nl80211: kernel reports: Match already configured
nl80211: kernel reports: Match already configured
[root@luckfox run]$ [ 3156.336733] RTL8723BS: rtw_set_802_11_connect(wlan0) fw_state = 0x00000008
[ 3156.517431] RTL8723BS: start auth
[ 3156.527800] RTL8723BS: auth success, start assoc
[ 3156.541675] RTL8723BS: rtw_cfg80211_indicate_connect(wlan0) BSS not found !!
[ 3156.541739] RTL8723BS: assoc success
[ 3156.573936] RTL8723BS: send eapol packet
[ 3156.587526] RTL8723BS: send eapol packet
[ 3156.597907] RTL8723BS: set pairwise key camid:4, addr:be:64:59:2e:6e:4a, kid:0, type:AES
[ 3156.605711] RTL8723BS: set group key camid:5, addr:be:64:59:2e:6e:4a, kid:1, type:AES
9.6 配置动态IP
udhcpc -i wlan0
终端输出信息
udhcpc: started, v1.36.1
udhcpc: broadcasting discover
udhcpc: broadcasting select for 192.168.191.198, server 192.168.191.76
udhcpc: lease of 192.168.191.198 obtained from 192.168.191.76, lease time 3599
deleting routers
adding dns 192.168.191.76
9.7 查看连接状态
wpa_cli -iwlan0 status
可以看到上面wpa_state=COMPLETED,意思就是连接成功,并且输出了ip地址。
bssid=be:64:59:2e:6e:4a
freq=2437
ssid=222
id=0
mode=station
pairwise_cipher=CCMP
group_cipher=CCMP
key_mgmt=WPA2-PSK
wpa_state=COMPLETED
ip_address=192.168.143.198
address=ac:35:ee:c7:a1:8f
uuid=27f25e1f-acda-534e-843c-2e76fbc60de8
9.8 ping一下网络
最后ping一下百度测试一下网络,可以看到成功ping通,丢包率0%。
ping www.baidu.com
PING www.baidu.com (36.155.132.76): 56 data bytes
64 bytes from 36.155.132.76: seq=0 ttl=51 time=33.591 ms
64 bytes from 36.155.132.76: seq=1 ttl=51 time=51.233 ms
64 bytes from 36.155.132.76: seq=2 ttl=51 time=44.949 ms
^C
--- www.baidu.com ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 33.591/43.257/51.233 ms
10.调试问题
在调试WIFI的时候发生了很多问题,第一个是加载完了驱动之后,找不到网卡,我这里显示只有一个以太网一个本地环回。
- 在排查的时候应该首先注意去排查硬件,因为这里是我自己打的板子,后来发现板子上的WIFI使能引脚那里没有接上3.3V,实际上是悬空的,是板子画错了。
- 硬件没有问题了,再去排查软件驱动部分,软件部分可以先测一下SDIOICLK引脚,看看有没有时钟的输出,如果是没有的话,驱动肯定是有问题的,可能是设备树节点没有配置对或者别的原因。
- 如果有时钟的输出,但是还是无法连接,我这里是
ifconfig wlan0 up
总是提示ifconfig: SIOCSIFFLAGS: Operation not permitted
,有可能是内核配置的问题或者是buildroot工具包没有加载,这个部分就要根据情况慢慢排查。用示波器测SDIOCMD线,发现在WIFI开启的时候,CPU给WIFI发送信息,而WIFI是没有回应的,正常情况下是要有一个回复,CPU才能够正确识别SDIO设备。后来发现是在写的时候不小心把使能引脚注释掉了,才导致没有收到回应的消息。
11.SDK下载
最后配置好WIFI的SDK链接如下,克隆主分支直接编译SDK并烧录即可使用。
gitee链接:
https://gitee.com/whisper-la/RV1103_RTL8723BS.git
github链接
https://github.com/whisper-la/RV1103_RTL8723BS.git