1. WLAN 驱动框架概述
WLAN 是基于 HDF(Hardware Driver Foundation)驱动框架开发的模块,该模块可实现跨操作系统迁移、自适应器件差异、模块化拼装编译等功能。从而降低 WLAN 驱动开发的难度,减少 WLAN 驱动移植和开发的工作量。
本文主要分析 WLAN 驱动架构的组成和各部件的功能,以及快速适配方法。
2. WLAN 驱动框架
WLAN 驱动框架组成:
驱动架构主要由 Module、NetDevice、NetBuf、BUS、HAL、Client 和 Message 这七个部分组成。
Module
Module 基于 HDF 驱动框架实现 WLAN 框架的启动加载、配置文件的解析、设备驱动的初始化和芯片驱动的初始化等功能,根据 WLAN 的功能特性,划分 Base、AP、STA 等部件,对控制流的命令和事件进行统一管理。
NetDevice
NetDevice 用于建立专属网络设备,屏蔽不同 OS 的差异,对 WIFI 驱动提供统一接口,提供统一的 HDF NetDevice 数据结构,及其统一管理、注册、去注册能力;对接富设备上的 Linux 的网络设备层;对接轻设备上的 Linux 的网络设备层。
NetBuf
NetBuf 部件为 WLAN 驱动提供 Linux 或者 LiteOS 原生的网络数据缓冲的统一数据结构的封装以及对网络数据的操作接口的封装,框架如下图所示:
BUS
BUS 驱动模块向上提供统一的总线抽象接口。通过向下调用 Platform 层提供的 sdio 接口和封装适配 usb、pcie 接口,屏蔽不同操作系统的差异;通过对不同类型的总线操作进行统一封装,屏蔽不同芯片差异,能够对不同芯片厂商提供完备的总线驱动功能,不同厂商共用此模块接口,从而使厂商的开发更为便捷和统一,框架如下图所示:
HAL
HAL 部件对 WiFiService 模块提供标准的 WIFI-HDI 接口和数据格式定义,提供能力如下:设置 MAC 地址、设置发射功率、获取设备的 MAC 地址等。
Client
Client 部件实现用户态与内核态的交互,通过对 sbuf 及 nl80211 做不同适配,根据产品做配置化编译,从而实现对上提供统一的接口调用,框架如下图所示:
Message
Message 部件为每个服务单独提供业务接口,每个服务也可依赖其他服务形成组合业务接口,此模块支持在用户态、内核态和 MCU 环境运行,实现了组件间的充分解耦。
3. WLAN 驱动适配
目前快速适配 wlan 的方法都是基于 WPA 三方框架直接 CONFIG_DRIVER_NL80211 走的 nl80211 协议,直接连接到芯片驱动上,也就是 Client 流程中走的灰色流程。
3.1 WiFi 适配文件介绍
在 3.1beta 中 devicehihopehardwarewifi 目录中可以看到 ap6xxx、bin、etc、lib、proc 和 BUILD.gn 文件
1)ap6xxx 文件中存放的是驱动相关的文件;
2)bin 文件中存放着 wpa_cli 和 wpa_supplicantion 二进制文件;(3.1release 版本中无此目录)
3) etc 中存放着 resolv.cof 文件;
4)lib 中存放着 libwpa_client.z.so 和 libwpa.z.so 文件;(3.1release 版本中无此目录)
5)proc 中存放着 ping_group_range 文件,定义着 ping 的变化范围;
6)Build.gn 为编译脚本文件;
3.2 WiFi 适配方法
以 Firefly 的 RK 系列为例,适配方法如下步骤
本方法已在以下 Firefly 产品验证,在 3.1beta 和 3.1release 上 WiFi 都能正常运行。
- ROC-RK3568-PC,芯片为 rk3568
- AIO-3399J,芯片为 rk3399
3.2.1 准备基础环境
下载 WiFi 芯片的驱动,从 Firefly 官网下载对应产品的 WiFi 驱动文件。
ROC-RK3568-PC WiFi 芯片(AP6275S)驱动下载链接:https://gitlab.com/firefly-linux/external/rkwifibt/-/tree/firefly/firmware/broadcom/AP6275S/wifi
AIO-3399J WiFi 芯片(AP6356S)驱动下载链接:https://gitlab.com/firefly-linux/external/rkwifibt/-/tree/firefly/firmware/broadcom/AP6356/wifi
3.2.2 修改 WiFi 驱动文件
在 devicehihopehardwarewifiap6xxx 中的驱动文件为润和 rk3568 开发板中的 WiFi 芯片的,存在与其他开发板不适配的情况,所以需要更改替换。
比如 ROC-RK3568-PC,修改如下
- 把 3.2.1 中下载的驱动文件,依次替换掉 devicehihopehardwarewifiap6xxx 中 clm_bcm43752a2_ag.blob、fw_bcm43752a2_ag_apsta.bin、fw_bcm43752a2_ag.bin、nvram_ap6275s.txt
- AIO-3399J 同样的方法删除掉 devicehihopehardwarewifiap6xxx 下的文件,拷贝相应的 4 个文件到此目录下;
- 修改 devicehihopehardwarewifiBUILD.gn 文件;
import("//build/ohos.gni")
AP6XXX_ETC_DIR = "//device/hihope/hardware/wifi/ap6xxx"
DNS_CONFIG_DIR = "//device/hihope/hardware/wifi"
WIFI_LIB_DIR = "//device/hihope/hardware/wifi/lib"
WIFI_BIN_DIR = "//device/hihope/hardware/wifi/bin"
ohos_prebuild_etc("fw_bcm4356a2_ag_mfg.bin") {
source = "$AP6XXX_ETC_DIR/fw_bcm4356a2_ag_mfg.bin"
install_images = ["vendor"]
relative_install_dir = "firmware"
part_name = "rockchip_products"
install_enable = true
}
ohos_prebuild_etc("fw_bcm4356a2_ag.bin") {
source = "$AP6XXX_ETC_DIR/fw_bcm4356a2_ag.bin"
install_images = ["vendor"]
relative_install_dir = "firmware"
part_name = "rockchip_products"
install_enable = true
}
ohos_prebuild_etc("nvram.txt") {
source = "$AP6XXX_ETC_DIR/nvram.tx"
install_images = ["vendor"]
relative_install_dir = "firmware"
part_name = "rockchip_products"
install_enable = true
}
ohos_prebuild_etc("resolv.conf") {
source = "$DNS_CONFIG_DIR/etc/resolv.conf"
install_images = ["system"]
part_name = "rockchip_products"
install_enable = true
}
ohos_prebuild_executable("wpa_cli") {
install_enable = true
source = "$WIFI_BIN_DIR/wpa_cli"
module_install_dir = "bin"
install_images = ["system"]
part_name = "rockchip_products"
}
ohos_prebuild_executable("wpa_supplicant") {
install_enable = true
source = "$WIFI_BIN_DIR/wpa_supplicant"
module_install_dir = "bin"
install_images = ["system"]
part_name = "rockchip_products"
}
ohos_prebuild_share_library("libwpa.z.so") {
source = "$WIFI_LIB_DIR/libwpa.z.so"
module_install_dir = "lib"
install_images = ["system"]
part_name = "rockchip_products"
}
ohos_prebuild_share_library("libwpa_client.z.so") {
source = "$WIFI_LIB_DIR/libwpa_client.z.so"
module_install_dir = "lib"
install_images = ["system"]
part_name = "rockchip_products"
}
group("ap6xxx") {
deps = [
":fw_bcm4356a2_ag_mfg.bin",
":fw_bcm4356a2_ag.bin",
":nvram.txt",
":resolv.conf",
":wpa_cli",
":wpa_supplicant",
":libwpa_client.z.so",
":libwpa.z.so",
]
}
上述 BUILD.gn 修改方法为 3.1beta 版本中的,在 3.1release 中则不需要 wpa_cli、wpa_supplicant、libwpa_client.z.so 和 libwpa.z.so 文件的配置。
3.3 WiFi 连网常用指令
WiFi 使能
代码语言:txt复制$ ifconfig wlan0 up
成功后 ifconfig 能看到 wlan0 节点
启动 wpa_supplicant 进程
代码语言:txt复制$ wpa_supplicant -i wlan0 -c /etc/wifi/wpa_supplicant -B
通过 wpa_cli 配置 WiFi
代码语言:txt复制$ wpa_cli
localhost/wla0> scan
localhost/wla0> scan_result
添加网络
1)如果要连接加密方式是 WPA-PSK-CCMP TKIP ESS,wifi 名称是 name,wifi 密码是:psk。操作如下:
代码语言:txt复制$ wpa_cli -i wlan0 set_network 0 ssid '"name"
$ wpa_cli -i wlan0 set_network 0 psk '"psk"'
$ wpa_cli -i wlan0 enable_network 0 //使能WiFi
2)如果要连接加密方式是 WEP (wep 加密),wifi 名称是 name,wifi 密码是 psk。操作如下:
代码语言:txt复制$ wpa_cli -i wlan0 set_network 0 ssid '"name"'
$ wpa_cli -i wlan0 set_network 0 key_mgmt NONE
$ wpa_cli -i wlan0 set_network 0 wep_key0 '"psk"'
$ wpa_cli -i wlan0 enable_network 0
3)如果要连接加密方式是ESS,wifi 名称是 name。操作如下:
代码语言:txt复制$ wpa_cli -i wlan0 set_network 0 ssid '"name"'
$ wpa_cli -i wlan0 set_network 0 key_mgmt NONE
$ wpa_cli -i wlan0 enable_network 0
保存 WIFI 连接信息
代码语言:txt复制$ wpa_cli -i wlan0 save_config
连接已有的连接
代码语言:txt复制$ wpa_cli -i wlan0 list_network // 列举所有保存的连接
$ wpa_cli -i wlan0 select_network 1 // 连接第1个保存的连接
$ wpa_cli -i wlan0 enable_network 1 // 使能第1个保存的连接
断开连接
代码语言:txt复制$ wpa_cli -i wlan0 disable_network 0
关闭 WiFi
代码语言:txt复制$ ifconfig wlan0 down
写在最后
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
- 关注小编,同时可以期待后续文章ing