1.wifi模块所需固件
将配套固件放在/lib/firmware目录下
上图中的两个文件.ini是wifi模块的校准文件,.bin文件根据.ini文件生成,是最后需要放到/lib/firmware下的。
RAM_RW_KERNEL_DRAM.bin
ROM_EXEC_KERNEL_IRAM.bin
上面两个固件是模块运行时所需要的固件。
2.驱动加载:
注:加载驱动前需确保wifi固件以放置到指定目录中。
编译驱动会生成两个skw_sdio_v20.ko 和skw6316.ko
先安装skw_sdio_v20
在安装skw6316.ko
3.sdio接口的速率配置
3.1 设备树配置
&sdio0 {
clock-frequency = <150000000>;
clock-freq-min-max = <200000 150000000>;
no-sd;
no-mmc;
bus-width = <4>;
disable-wp;
cap-sd-highspeed;
cap-sdio-irq;
keep-power-in-suspend;
mmc-pwrseq = <&sdio_pwrseq>;
non-removable;
num-slots = <1>;
pinctrl-names = "default";
pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>;
sd-uhs-sdr104;
status = "okay";
};
3.2 SDMMC操作模式
3.3 如何修改sdio频率
修改3.1设备树中 clock-frequency 和 clock-freq-min-max可更改sdio频率,但是 sd-uhs-sdr104这个参数的配置需要和3.2图中的模式匹配,sdio频率大于100Mhz时,需要配置sdr104,若配置成别的,就算clock-frequency 和 clock-freq-min-max配置成>100Mhz,实际也是不生效的。
如3.2中图片中所示,不同的速率对signal的电压也是有要求的,如果电压不对的话,软件上配置正常的话,也不会到达理想的速率
3.4 如何查看当前sdio的频率
3.4.1.法一:insmod skw_sdio_v20.ko log 查看
如下:安装skw_sdio_v20.ko时打印 clock=150000000
linaro@bionic:~/jie$ sudo insmod skw_sdio_v20.ko
[ 75.535396] [SKWSDIO INFO] skw_sdio_scan_card: sdio_scan_card
[ 75.535562] skw_sdio_probe: func->class=0, vendor=0x1ffe, device=0x6316, func_num=0x0001, clock=150000000 blksize=0x200 max_blkcnt 2048
3.4.2.法二:dmesg 查看
查看dmesg 打印如下,当前sdio clk 19800000Hz -------> 20Mhz
sudo dmesg | grep mmc
[ 2.120203] mmc0: SDHCI controller on fe2e0000.mmc [fe2e0000.mmc] using ADMA
[ 2.160145] mmc0: new HS400 Enhanced strobe MMC card at address 0001
[ 2.160803] mmcblk0: mmc0:0001 A3A561 57.6 GiB
[ 2.160990] mmcblk0boot0: mmc0:0001 A3A561 partition 1 4.00 MiB
[ 2.161184] mmcblk0boot1: mmc0:0001 A3A561 partition 2 4.00 MiB
[ 2.161437] mmcblk0rpmb: mmc0:0001 A3A561 partition 3 16.0 MiB, chardev (236: 0)
[ 2.165667] mmcblk0: p1 p2 p3 p4 p5 p6
[ 2.329873] dwmmc_rockchip fe2c0000.mmc: IDMAC supports 32-bit address mode.
[ 2.329900] dwmmc_rockchip fe2c0000.mmc: Using internal DMA controller.
[ 2.329908] dwmmc_rockchip fe2c0000.mmc: Version ID is 270a
[ 2.329929] dwmmc_rockchip fe2c0000.mmc: DW MMC controller at irq 81,32 bit h ost data width,256 deep fifo
[ 2.330095] dwmmc_rockchip fe2c0000.mmc: allocated mmc-pwrseq
[ 2.330102] mmc_host mmc1: card is non-removable.
[ 2.548241] mmc_host mmc1: Bus speed (slot 0) = 400000Hz (slot req 400000Hz, actual 400000HZ div = 0)
[ 2.580012] mmc_host mmc1: Bus speed (slot 0) = 19800000Hz (slot req 20000000 Hz, actual 19800000HZ div = 0)
[ 2.588317] dwmmc_rockchip fe2c0000.mmc: Successfully tuned phase to 242
4.驱动框架分析:
4.1. seekwaveplatform_v20分析:
以skw_sdio_v20.ko 驱动分析:
函数调用:
static int __init skw_sdio_io_init(void)
//填充struct skw_sdio_data_t结构体,及执行下列主要函数
skw_sdio_debugfs_init();
skw_sdio_log_level_init();
skw_sdio_launch_thread();
skw_sdio_scan_card();
ret = sdio_register_driver(&skw_sdio_driver); //注册sys/bus/sdio/drivers/skw_sdio驱动
seekwave_boot_init();
ret = sdio_register_driver(&skw_sdio_driver);
ret = sdio_register_driver(&skw_sdio_driver);
static int skw_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
skw_sdio_bind_platform_driver(skw_sdio->sdio_func[FUNC_1]);
//在这个函数中注册platform_device和wifi驱动匹配
这里需要明白,注册的sdio驱动,怎么才能匹配,进而执行其中的 probe函数。
skw_sdio_driver中有个sdio_device_id描述它能够支持的设备,告诉内核哪些设备与驱动程序匹配。
static const struct sdio_device_id skw_sdio_ids[] = {
//{ .compatible = "seekwave-sdio", },
{SDIO_DEVICE(0, 0)},
{SDIO_DEVICE(0xABCD, 0x1234)},
{SDIO_DEVICE(0x1FFE, 0x6316)},
{},
};
下图时设备中识别到的sdio_wifi设备,发现vid,pid和上面skw_sdio_ids 中匹配.
4.2.skw6316.ko分析
static int __init skw_module_init(void)
ret = platform_driver_register(&skw_drv);
static int skw_drv_probe(struct platform_device *pdev)
//需要分析 platform_device从哪里匹配的
这里注册的plateform_device驱动刚好和4.1中注册的platform_driver进行匹配,进而加载skw6316.ko中相关驱动。
4.3.固件加载流程分析
固件的加载是在skw_sdio_v20.ko中实现的。
设备树中固件相关定义如下:
drivers\seekwaveplatform_v20\skwutil\boot_config.h
#define SEEKWAVE_NV_NAME "SEEKWAVE_NV_SWT6652.bin"
#define SKW_IRAM_FILE_PATH "/data/ROM_EXEC_KERNEL_IRAM.bin"
#define SKW_DRAM_FILE_PATH "/data/RAM_RW_KERNEL_DRAM.bin"
platform_driver_register(&seekwave_driver); //实际并没有加载,使用的是设备树中生成的device
platform_driver_register(&seekwave_driver);
static struct platform_driver seekwave_driver ={
probe = seekwave_boot_probe;
};`
static int seekwave_boot_probe(struct platform_device *pdev)
seekwave_boot_parse_dt(pdev, boot_data); //解析设备树中的固件路径
skw_boot_init(boot_data);
ret = skw_request_firmwares(boot_data, "RAM_RW_KERNEL_DRAM.bin", "ROM_EXEC_KERNEL_IRAM.bin",boot_data->skw_nv_name);
//加载wifi固件
4.4.总结
上面只是分析了驱动的加载匹配过程,很多细节没有给出,如需详细了解,可细读代码。
5.wifi的使用
5.1连接wifi
5.1.1 使用 nmcli 连接 Wi-Fi
nmcli 是NetworkManager的命令行界面,适用于大多数现代Linux发行版。以下是使用 nmcli 连接Wi-Fi的步骤:
1.检查可用的Wi-Fi网络
nmcli device wifi list
这将列出所有可用的Wi-Fi网络。
2.连接到Wi-Fi网络
使用以下命令连接到特定的Wi-Fi网络,替换 <SSID> 和 <PASSWORD> 为实际的Wi-Fi网络名称和密码:
nmcli device wifi connect <SSID> password <PASSWORD>
例如:
nmcli device wifi connect "MyWiFiNetwork" password "MyWiFiPassword"
nmcli device disconnect wlan0 //断开wifi 链接
如何忘记网络:
nmcli connection show
nmcli connection delete MyWiFiNetwork
5.1.2 使用 wpa_supplicant 连接 Wi-Fi
1.创建wpa_supplicant.conf 文件
ctrl_interface=/var/run/wpa_supplicant
ap_scan=1
update_config=1
network={
ssid="MyWiFiNetwork"
psk="MyWiFiPassword"
key_mgmt=WPA-PSK
}
2.执行指令
wpa_supplicant -D nl80211 -i wlan0 -c $WorkDir/wpa_supplicant.conf -B 1
udhcpc -i wlan0 // 分配Ip地址
5.2 软ap配置
使用 hostapd 管理AP模式,并使用 dnsmasq 提供DHCP和DNS服务
下面是一个完整的步骤指南,使用 hostapd 配置软AP:
- 确认无线网卡支持AP模式
首先,确认你的无线网卡支持AP模式:
iw list | grep "Supported interface modes" -A 10
确保输出中包含 AP 模式。
- 安装 hostapd,dnsmasq
sudo apt-get install hostapd
sudo apt-get install dnsmasq
- 在进行配置前,停止 hostapd 和 dnsmasq 服务,以便手动配置:
sudo systemctl stop hostapd
sudo systemctl stop dnsmasq
- 配置 hostapd
创建虚拟接口 wlan0_ap 并设置为 AP 模式
sudo ip linkset wlan0 down
sudo iw dev wlan0 interface add wlan0_ap type __ap
sudo ip linkset wlan0_ap up
编辑或创建 hostapd 配置文件(例如 /etc/hostapd/hostapd.conf):
在实际使用时,把下面配置文件的注释去掉。 密码至少8位
interface=wlan0_ap
driver=nl80211
ssid=jie # YourSSID
hw_mode=g
channel=7
wmm_enabled=0
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=12345678 #ap密码
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
5.编辑 /etc/default/hostapd 文件,指定配置文件路径:
DAEMON_CONF="/etc/hostapd/hostapd.conf"
- 配置网络接口
为无线接口分配静态IP地址,并启用接口:
sudo ip addr add 192.168.1.1/24 dev wlan1
sudo ip link set wlan1 up
- 启用IP转发和配置NAT
启用IP转发:
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
配置NAT以允许连接的设备通过你的主机访问互联网:
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
将规则保存以便重启后生效(具体命令依赖于你的发行版,例如 iptables-save):
sudo iptables-save | sudo tee /etc/iptables/rules.v4
- 启动 hostapd
启动 hostapd 服务:
sudo systemctl start hostapd
如果下面报错:执行 sudo systemctl unmask hostapd
root@LPA3588:/# sudo systemctl start hostapd
Failed to start hostapd.service: Unit hostapd.service is masked.
并设置为开机自动启动:
sudo systemctl enable hostapd
6.wifi的速率测试:
6.1 iperf3工具
可以采用iperf3工具进行测试,下面时一个测试方法示例:
服务器端运行:
iperf3 -s
机器端运行:
iperf3 -c ipaddr -P 6 -b 1000M -t 30 -i 1 // 测试发送
iperf3 -c ipaddr -P 6 -b 1000M -t 30 -i 1 -R //测试接收
- -c ipaddr:指定 iperf3 服务器的 IP 地址(替换 ipaddr 为服务器的实际 IP 地址)。
- -P 6:使用 6 个并行的流来进行测试。并行流可以帮助测试在多连接情况下的网络性能。
- -b 1000M:设置带宽为 1000 Mbps(即 1 Gbps)。这个选项告诉 iperf3 客户端期望以 1 Gbps 的速度发送数据。
- -t 30:测试持续时间为 30 秒。
- -i 1:每秒报告一次测试结果。
- -R:反向测试模式,意味着测试将会从服务器到客户端进行。这将使 iperf3 在服务器端向客户端发送数据,而不是客户端向服务器发送数据