正点原子嵌入式Linux驱动实战:RTL8723DS SDIO WIFI驱动移植与联网全解析
1. RTL8723DS SDIO WIFI驱动移植概述
在嵌入式Linux开发中,无线网络功能的实现往往需要经历驱动移植这一关键环节。正点原子STM32MP157开发板搭载的RTL8723DS芯片是一款集成了WIFI和蓝牙功能的二合一模块,采用SDIO接口与主控通信。相比USB接口的WIFI模块,SDIO接口在稳定性和性能上更具优势,特别适合对网络质量要求较高的嵌入式应用场景。
我第一次接触这个驱动移植项目时,发现整个过程看似复杂,但只要抓住几个关键点就能事半功倍。RTL8723DS的驱动移植主要包含三大步骤:首先是驱动源码的获取和内核配置,其次是设备树的修改,最后是固件和工具的准备工作。Realtek官方已经提供了完整的驱动源码,这大大降低了我们的工作难度,不需要从零开始编写驱动代码。
这里有个小技巧分享给大家:在开始移植前,建议先检查开发板的硬件连接。正点原子开发板上RTL8723DS模块的SDIO接口引脚已经固定连接到了STM32MP1的PF0、PF1、PF4、PF5、PG15等引脚上。确认硬件连接正常可以避免后续调试时走弯路。
2. 驱动源码添加与内核配置
2.1 驱动源码准备
Realtek官方提供的RTL8723DS驱动源码通常以压缩包形式发布。我建议创建一个专门的目录来存放这些第三方驱动,比如在Linux内核源码的drivers/net/wireless/realtek/目录下新建rtl8723ds文件夹。将下载的驱动源码解压到这个目录,保持源码目录结构清晰很重要。
实际操作中我遇到过一个问题:不同版本的驱动源码可能对内核版本有要求。比如某些新版本驱动可能需要较新的内核支持。如果遇到编译错误,可以尝试换用其他版本的驱动源码。正点原子提供的资料包里通常包含经过验证的驱动版本,这是最稳妥的选择。
2.2 修改Kconfig和Makefile
要让内核编译系统识别新添加的驱动,需要修改两个关键文件。首先是drivers/net/wireless/realtek/Kconfig文件,在其中添加一行:
source "drivers/net/wireless/realtek/rtl8723ds/Kconfig"这行代码告诉内核配置系统,rtl8723ds目录下有自己的Kconfig配置选项。
接着修改同目录下的Makefile,添加:
obj-$(CONFIG_RTL8723DS) += rtl8723ds/这个修改使得内核可以根据CONFIG_RTL8723DS配置选项决定是否编译该驱动。
2.3 内核图形化配置
完成上述修改后,就可以通过make menuconfig命令进入内核配置界面了。RTL8723DS驱动的配置路径为:
-> Device Drivers -> Network device support -> Wireless LAN -> Realtek devices -> Realtek 8723D SDIO or SPI WiFi这里建议将驱动编译为模块(.ko文件),而不是直接编译进内核。模块化的方式更灵活,方便调试和更新。同时还需要确保以下配置项被启用:
- USB支持(虽然我们用SDIO接口,但部分依赖需要USB支持)
- Wireless LAN支持
- IEEE 802.11协议栈(配置为模块)
- STAGING驱动支持
配置完成后,保存退出。这时候可以先用make modules命令单独编译驱动模块,验证是否配置正确。我在第一次尝试时漏选了STAGING驱动支持,导致编译失败,这个坑大家要注意避开。
3. 设备树配置与硬件接口使能
3.1 SDMMC3接口配置
STM32MP157有三个SDMMC控制器,RTL8723DS使用的是SDMMC3接口。在设备树中需要正确配置这个接口。打开stm32mp15-pinctrl.dtsi文件,可以看到SDMMC3的默认引脚配置:
sdmmc3_b4_pins_a: sdmmc3-b4-0 { pins { pinmux = <STM32_PINMUX('F', 0, AF9)>, /* SDMMC3_D0 */ <STM32_PINMUX('F', 1, AF9)>, /* SDMMC3_CMD */ <STM32_PINMUX('F', 4, AF9)>, /* SDMMC3_D1 */ <STM32_PINMUX('F', 5, AF9)>, /* SDMMC3_D2 */ <STM32_PINMUX('D', 7, AF10)>, /* SDMMC3_D3 */ <STM32_PINMUX('G', 15, AF10)>; /* SDMMC3_CK */ slew-rate = <1>; drive-push-pull; bias-pull-up; }; };正点原子开发板的引脚连接与官方参考设计一致,所以不需要修改这个默认配置。
3.2 使能SDMMC3控制器
在stm32mp157d-atk.dts文件中,我们需要追加SDMMC3节点的配置。这里有个关键点需要注意:STM32MP1的三个SDMMC控制器初始化顺序是根据物理地址决定的,依次是SDMMC3→SDMMC1→SDMMC2。这个顺序会影响设备节点名称(/dev/mmcblkX的编号)。
添加以下内容到设备树:
&sdmmc3 { pinctrl-names = "default", "opendrain", "sleep"; pinctrl-0 = <&sdmmc3_b4_pins_a>; pinctrl-1 = <&sdmmc3_b4_od_pins_a>; pinctrl-2 = <&sdmmc3_b4_sleep_pins_a>; non-removable; st,neg-edge; bus-width = <4>; vmmc-supply = <&v3v3>; status = "okay"; keep-power-in-suspend; };这些配置中特别要注意的是non-removable属性,因为RTL8723DS是板载设备,不是可插拔的SD卡。另外keep-power-in-suspend可以确保在休眠状态下WIFI模块不掉电。
4. 驱动编译与固件准备
4.1 驱动模块编译
完成内核配置和设备树修改后,就可以开始编译了。建议按以下顺序执行编译命令:
make dtbs # 先编译设备树 make modules -j$(nproc) # 编译驱动模块编译完成后,可以在以下路径找到生成的驱动模块:
- cfg80211.ko: net/wireless/cfg80211.ko
- 8723ds.ko: drivers/net/wireless/realtek/rtl8723ds/8723ds.ko
将这些模块拷贝到开发板文件系统的/lib/modules/$(uname -r)/目录下。我习惯使用NFS挂载根文件系统,拷贝命令如下:
sudo cp net/wireless/cfg80211.ko ~/linux/nfs/rootfs/lib/modules/5.4.31/ sudo cp drivers/net/wireless/realtek/rtl8723ds/8723ds.ko ~/linux/nfs/rootfs/lib/modules/5.4.31/4.2 固件文件准备
WIFI驱动正常工作需要配套的固件文件。主要需要以下两个文件:
- regulatory.db
- regulatory.db.p7s
这些文件需要放置到开发板文件系统的/lib/firmware/目录下。可以通过以下命令创建目录并拷贝文件:
sudo mkdir -p ~/linux/nfs/rootfs/lib/firmware sudo cp regulatory.db regulatory.db.p7s ~/linux/nfs/rootfs/lib/firmware/如果没有这些固件文件,驱动仍然可以加载,但会报警告信息,可能影响部分功能。
5. WIFI驱动测试与联网配置
5.1 驱动加载测试
在开发板上,按顺序加载驱动模块:
depmod -a # 首次加载时需要建立模块依赖关系 modprobe cfg80211 # 先加载协议栈 modprobe 8723ds # 再加载WIFI驱动加载成功后,使用ifconfig -a命令应该能看到wlan0网络接口。如果看不到,可以检查dmesg输出的内核日志,常见问题有:
- 固件文件缺失或路径不正确
- SDIO接口通信失败(检查硬件连接)
- 设备树配置错误
5.2 WIFI工具配置
要实现WIFI联网,还需要一些用户态工具的支持。通过Buildroot配置以下工具:
-> Target packages -> Networking applications -> [*] wireless tools -> [*] wpa_supplicant配置时注意启用以下选项:
- Enable nl80211 support
- Install wpa_cli binary
- Install wpa_passphrase binary
重新编译文件系统后,就可以使用iwlist和wpa_supplicant等工具了。
5.3 联网实战操作
首先扫描周围的WIFI网络:
ifconfig wlan0 up # 启用网卡 iwlist wlan0 scan # 扫描网络确认能看到目标WIFI热点后,创建/etc/wpa_supplicant.conf配置文件:
ctrl_interface=/var/run/wpa_supplicant ctrl_interface_group=0 update_config=1 network={ ssid="Your_WiFi_SSID" psk="Your_WiFi_Password" }然后创建必要的目录并启动连接:
mkdir -p /var/run/wpa_supplicant wpa_supplicant -Dnl80211 -c/etc/wpa_supplicant.conf -iwlan0 &最后通过DHCP获取IP地址:
udhcpc -i wlan0至此,RTL8723DS SDIO WIFI应该已经成功连接到网络。可以通过ping命令测试网络连通性:
ping -I wlan0 www.baidu.com6. 常见问题与调试技巧
在实际项目中,我遇到过不少驱动移植的问题。这里分享几个典型问题的解决方法:
问题1:驱动加载失败,提示"sdio_register_driver failed"这通常是因为SDIO控制器没有正确初始化。检查步骤:
- 确认设备树中SDMMC3节点已启用(status = "okay")
- 检查硬件连接,特别是SDIO_CLK信号
- 测量3.3V电源是否正常
问题2:能扫描到WIFI热点但无法连接可能原因:
- 密码错误(可以通过wpa_passphrase生成正确的PSK)
- 加密方式不匹配(尝试在wpa_supplicant.conf中明确指定proto和pairwise参数)
- 信号太弱(确保天线已正确连接)
问题3:传输速度慢或不稳定解决方法:
- 检查SDIO总线速度设置(设备树中的bus-width和st,neg-edge等参数)
- 尝试调整驱动参数,如rtw_ips_mode(电源管理模式)
- 检查是否有其他设备占用SDIO总线资源
调试时,这些命令很有用:
dmesg | grep 8723 # 查看驱动日志 iwconfig wlan0 # 查看无线网卡状态 iw dev wlan0 station dump # 查看连接状态信息对于需要长期运行的应用,建议配置系统服务自动加载驱动和连接WIFI。可以创建一个systemd服务文件,实现开机自动连接。
