背景
一台运行嵌入式 Linux(内核 3.14.38)的仪器,原本仅支持 2.4GHz WiFi(WIFI芯片为rtl8723BU)。为扩展 5GHz 频段,外接了一款 Realtek 8821CU 芯片的 USB WiFi 模块。本文将记录从驱动加载、冲突模块处理,到最终成功扫描并连接 5GHz 网络的完整过程。
环境约束
-
操作系统:精简嵌入式 Linux,无
sudo、iw、iwpriv等现代工具。 -
仅具备基础命令:
ifconfig、iwconfig、iwlist、lsmod、dmesg等。 -
内核模块需手动加载,无自动固件加载机制。
步骤 1:确认硬件及驱动状态
插上 USB WiFi 模块后,首先检查系统是否识别设备:
bash
lsusb
发现两个设备 ID 0bda:c820(Realtek 8821CU)。查看内核日志:
bash
dmesg | tail -30

出现大量 LeaveAllPowerSaveMode(wlan1): bSurpriseRemoved=_TRUE Skip! 错误,说明驱动已加载但射频部分未正常工作。
查看已加载模块:
bash
lsmod
发现系统同时加载了 8723bu 和 8821cu 两个模块,可能造成冲突。
(8821cu .ko驱动编译及移植见我上一篇文章:网卡驱动RTL8821CU移植_tl8821cub移植-CSDN博客)
步骤 2:卸载冲突模块
移除疑似占用旧接口的 8723bu 模块:
bash
rmmod 8723bu
此时只剩下 8821cu。但接口仍未出现,需要重新插拔 USB 模块或强制重新加载驱动。

步骤 3:重新加载 8821cu 驱动
bash
insmod /lib/modules/3.14.38-6UL_ga+ge4944a5/kernel/drivers/net/wireless/realtek/rtl8821CU/8821cu.ko
再次检查:
bash
lsmod
ip link show
出现 wlan0 接口(状态 DOWN),且 iwlist wlan0 channel 显示完整的 5GHz 信道列表(36~140),证明硬件支持 5GHz。


步骤 4:解决扫描无结果问题
执行扫描:
bash
ifconfig wlan0 up
iwlist wlan0 scanning

返回 No scan results。内核日志再次出现 bSurpriseRemoved 错误,表明 USB 电源管理或接触不良导致设备被误判为拔出。
解决措施:
-
物理重新插拔 USB 模块(建议直连主机,勿用无源 HUB)。
-
禁用 USB 自动挂起:
bash
echo -1 > /sys/module/usbcore/parameters/autosuspend或针对设备路径写入
on:bash
echo 'on' > /sys/bus/usb/devices/1-1.1/power/control
重新激活接口后,扫描成功,发现大量 2.4GHz 与 5GHz 信号。

步骤 5:连接指定 5GHz 网络
由于没有 iw 工具,无法主动设置国家码,但可利用 wpa_supplicant 的配置实现。
5.1 编写配置文件
创建 /etc/wpa_supplicant.conf:
ini
ctrl_interface=/var/run/wpa_supplicant
update_config=1
country=CN
network={
ssid="WIFIname-5G"
psk="your_password"
key_mgmt=WPA-PSK
}
country=CN 是关键,它让 supplicant 启动时自动设置监管域为中国,解锁 5GHz 信道。
5.2 启动连接
bash
killall wpa_supplicant
wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf
udhcpc -i wlan0

遇到无害警告 rfkill: Cannot open RFKILL control device 和 ioctl[SIOCSIWAP]: Operation not permitted,不影响连接。
5.3 验证连接
bash
iwconfig wlan0

成功关联 5GHz 信道 48,速率 434 Mbps,连接质量可用。
最后ping一下百度能ping通,说明数据链路正常。

附录:常用辅助调试命令
在适配过程中,以下命令可帮助快速定位驱动、硬件、网络状态等问题。
1. 查看 USB 设备及驱动绑定
bash
lsusb # 列出所有 USB 设备
lsusb -t # 树形显示,可看到每个设备的 Driver=
用途 :确认模块是否被正确识别,驱动是否绑定成功。若 Driver= 为空或显示 hub,说明未被目标驱动认领。
2. 查看接口与驱动的对应关系
bash
for iface in $(ls /sys/class/net/); do
driver=$(readlink /sys/class/net/$iface/device/driver 2>/dev/null | xargs basename)
[ -n "$driver" ] && echo "$iface -> $driver"
done
用途 :当存在多个无线接口时,快速判断哪个接口对应哪个驱动(如 wlan0 -> 8821cu)。
3. 查看模块详细信息
bash
modinfo 8821cu # 查看模块依赖、参数、版本等
用途 :确认模块路径、依赖关系,或查看可传递给模块的参数(如 rtw_country_code 等)。
4. 查看已加载模块及被依赖关系
bash
lsmod # 简洁列表
cat /proc/modules # 底层信息,无 lsmod 时的替代
用途:检查模块是否加载、占用内存、被其他模块依赖。
5. 追踪内核日志(驱动加载、固件错误、USB 事件)
bash
dmesg | tail -30 # 最近 30 行
dmesg | grep -i firmware # 搜索固件相关提示
dmesg | grep -i "usb disconnect\|new high-speed USB" # USB 插拔记录
用途 :这是定位 bSurpriseRemoved、FW doesn't exit 等错误的终极手段。
6. 查看网卡支持的频段与信道
bash
iwlist wlan0 channel
用途:显示网卡支持的所有信道,若仅出现 2.4GHz 信道,说明驱动或国家码限制。
7. 查看当前连接的状态
bash
iwconfig wlan0 # 信号、速率、频段、关联的 AP
iwlist wlan0 channel | grep Current # 只看当前频段
ifconfig wlan0 # IP 地址、数据包统计
用途:快速确认是否成功关联到 5GHz,连接质量如何。
8. 扫描周围 WiFi(含过滤)
bash
iwlist wlan0 scanning | grep -E "Address|ESSID|Frequency"
iwlist wlan0 scanning | grep -A1 "freq: [5]" # 仅显示 5GHz 网络(需支持 gawk 等情况)
iwlist wlan0 scan freq 5180 5200 5240 5745 # 指定信道扫描(某些老驱动支持)
用途:快速找出 5GHz 信号,避免在 2.4GHz 海洋里翻找。
9. 强制绑定或解绑 USB 驱动
bash
# 解除旧绑定
echo "1-1.1:1.0" > /sys/bus/usb/drivers/8723bu/unbind
# 绑定到新驱动
echo "1-1.1:1.0" > /sys/bus/usb/drivers/8821cu/bind
用途 :当驱动冲突或需要切换驱动时使用,路径需从 ls -l /sys/class/net/wlan0/device 获取。
10. 绕过扫描直接连接已知网络
bash
wpa_passphrase "SSID" "password" > /tmp/wpa.conf
wpa_supplicant -B -i wlan0 -c /tmp/wpa.conf
udhcpc -i wlan0 # 或 dhclient wlan0
用途:扫描不可靠时的备用连接手段,可验证网卡射频是否正常。
11. 检查 RF-Kill 状态
bash
rfkill list
cat /sys/class/rfkill/*/state
用途 :某些平台会有软/硬开关阻止无线发射,状态必须为 0(解除阻塞)。
12. 网络连通性测试
bash
ping -c 4 192.168.2.1 # 网关
ping -c 4 114.114.114.114 # 公网 DNS(若路由器允许)
用途:确认连接后数据链路正常。
13. 查看系统所有网络接口
bash
ip link show # 现代方式
ifconfig -a # 传统方式,显示包含 DOWN 状态的接口
用途 :定位无线接口的确切名称(可能是 wlan0、wlan1、ra0 等)。
这些命令组合在一起,覆盖了从硬件识别、驱动调试、网络连接到性能验证的完整链路。根据现场情况灵活选用,可以快速定位并解决大部分外接 WiFi 模块的适配问题。