K230 SDK IoT WiFi AiW4211LV10驱动开发指南#

功能介绍#

AiW4211LV10是一款低功耗IoT WiFi芯片,我司采用该芯片平台设计了一款AiW4211LV10开发板,该开发板可插入K230 EVB板的TF卡插槽实现接入。K230 EVB加载AiW4211LV10驱动之后,可以生成wlan0无线网卡,实现网络数据通信。

模块依赖#

硬件上依赖AiW4211LV10开发板,依赖K230 EVB开发板,K230 EVB为WiFi提供电源及中断检测连线。

软件上依赖于K230 SDIO主控驱动,依赖GPIO驱动的完备,需要emmc引导启动实现。

操作系统#

当前驱动支持linux 4.9、linux 4.17和linux 5.10.4

硬件环境#

K230 EVB开发板设置emmc启动,空出TF卡插槽用于AiW4211LV10开发板接入。

K230 EVB开发板飞线到AiW4211LV10开发板排针。连接关系如下:

表 2-1 飞线关系

Link1

Link2

Link3

Link4

Link5

K230排针

J5 PIN16 (5V)

J8 PIN9 (GPIO34)

WiFi排针

J6 PIN1 (5V)

J2 PIN3 (SDIO_INT_OUT)

J2 PIN4 (TX)

J2 PIN5 (RX)

J2 PIN6 (GND)

TTL-USB

RX

TX

GND

备注:TTL-USB与WiFi的连线主要是为了观察WiFi的固件输出,可以不连接

模块配置#

设备树修改#

配置引脚function#

修改uboot设备树arch/riscv/dts/k230_evb.dts,配置K230 EVB IO52引脚功能为GPIO,方向为input:

&iomux {
pinctrl-names = "default";
pinctrl-0 = <&pins>;
pins: iomux_pins {
pinctrl-single,pins = <

......

(IO52) ( 0 <<SEL | 0<<SL | BANK_VOLTAGE_IO50_IO61<<MSC | 1<<IE | 0<<OE | 0<<PU | 1<<PD | 7<<DS | 0<<ST )
}
}

配置GPIO控制器#

修改linux设备树arch/riscv/boot/dts/kendryte/gpio_provider.dtsi,配置K230 EVB GPIO52控制器:

/ {

......

gpio52: gpio52@9140c000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "canaan,k230-apb-gpio";
reg = <0x0 0x9140c000 0x0 0x1000>;
interrupt-controller;
interrupt-parent = <&intc>;
#interrupt-cells = <2>;
interrupts = <84 IRQ_TYPE_EDGE_RISING>;

port52: gpio-controller@0 {
gpio-controller;
#gpio-cells = <2>;
nr-gpios = <1>;
reg-bank = <0>;
id = <52>;
};
};
};

配置SDHCI1参数#

修改linux设备树arch/riscv/boot/dts/kendryte/k230_evb.dtsi,配置对应sdio主控参数:

sdcard: sdhci1@91581000 {
compatible = "snps,dwcmshc-sdhci";
reg = <0x0 0x91581000 0x0 0x1000>;
interrupt-parent = <&intc>;
interrupts = <144>;
interrupt-names = "sdhci1irq";
clocks = <&dummy_sd>,<&dummy_sd>;
clock-names = "core", "bus";
max-frequency = <50000000>;
bus-width = <4>;
//cd-gpios = <>;
no-1-8-v;
cap-sd-highspeed;
sdhci,auto-cmd12;
status = "okay";
};

内核配置项#

通过内核配置将AiW4211LV10驱动编译为内核模块,并将必要的协议及驱动编入内核。

使能kprobes:

> General architecture-dependent options

|| [*] Kprobes

将cfg80211编入内核注意需要选中 cfg80211 wireless extensions compatibility

> Networking support > Wireless

 --- Wireless  

  <*> cfg80211 - wireless configuration API  

  [ ] nl80211 testmode command  

  [ ] enable developer warnings  

  [ ] cfg80211 certification onus  

  [*] enable powersave by default  

  [ ] cfg80211 DebugFS entries  

  [*] support CRDA  

  [*] cfg80211 wireless extensions compatibility  

  [ ] lib80211 debugging messages  

  < > Generic IEEE 802.11 Networking Stack (mac80211)

将AiW4211LV10驱动编译成内核模块,注意需要选中 IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP):

> Device Drivers > Network device support > Wireless LAN

 --- Wireless LAN  

  [ ] mac80211-based legacy WDS support  

  [ ] ADMtek devices  

  [*] Aich devices  

  <M> Aich AiW4211LV10 (SDIO) support 

  [ ] Atheros/Qualcomm devices  

  [ ] Atmel devices  

  [ ] Broadcom devices  

  [ ] Cisco devices  

  [ ] Intel devices  

  [*] Intersil devices  

  <*> IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)

  [ ] Support downloading firmware images with Host AP driver  

  [ ] Marvell devices  

  [ ] MediaTek devices  

  [ ] Microchip devices

SDIO主控增加扫描接口#

AiW4211LV10驱动需要依据WiFi所接入的槽位发起SDIO扫描,因此特封装plat_sdio_rescan接口函数。修改drivers/mmc/host/sdhci-of-dwcmshc.c文件如下:

static unsigned int slot_index = 0;
static struct mmc_host \*__mmc__host[3] = {NULL};
int plat_sdio_rescan(int slot)
{
struct mmc_host \*mmc = \__mmc__host[slot];
if (mmc == NULL) {
pr_err("invalid mmc, please check the argument\\n");
return -EINVAL;
}

mmc_detect_change(mmc, 0);
return 0;
}

static int dwcmshc_probe(struct platform_device \*pdev)
{

......

priv->bus_clk = devm_clk_get(&pdev-\>dev, "bus");
if (!IS_ERR(priv->bus_clk))
clk_prepare_enable(priv->bus_clk);
__mmc__host[slot_index++] = host->mmc;
err = mmc_of_parse(host->mmc);
if (err)
goto err_clk;

......

}

模块编译#

在SDK顶层执行make linux,随内核一同编译,ko临时存储在output/k230_evb_defconfig/little/linux/drivers/net/wireless/aich/aiw4211lv10/目录。

模块启动#

WiFi固件#

在K230 SDK当中WiFi固件AiW4211L_demo_allinone.bin以二进制文件形式提供,如需源码请联系我们。

固件存储路径:k230_sdk/src/little/utils/firmware/AiW4211L_demo_allinone.bin

驱动加载#

在硬件环境配置完成后上电启动,执行以下指令即可实现驱动加载:

modprobe aiw4211lv10 或者 modprobe aiw4211lv10 mmc=1 gpio=52

当前驱动支持传入mmc主控编号及用于中断检测的gpio编号,可以实现较为灵活的硬件配置,如果不传参则分别使用代码中规定的默认值1和52。

驱动加载完成后,使用ifconfig -a指令可以看到已经生成了无线网卡wlan0。

网络配置#

启动配置工具server端并置于后台运行:iotwifi_link &

该工具的功能角色类似于wpa_supplicant。iotwifi_link首先会将wlan0 up起来,然后从WiFi设备侧同步mac地址及ip地址到host端。

运行配置工具client端,控制WiFi接入AP及设置其他参数:iotwifi_cli –config /etc/wifi.conf

运行配置工具client端,控制WiFi进入深睡模式:iotwifi_cli –dirsleep

/etc/wifi.conf是WiFi工作参数配置文件,以json格式编写,基本上是对wifi_config_t结构体的映射,具体可参考6.1.2章节。

API参考#

AiW4211LV10驱动加载后生成的无线网卡与一般WiFi网卡无异,因此网络通信功能无特殊API需要说明。

除基本的网络通信外,K230与WiFi还存在两个消息通信接口,需要重点说明。

config接口#

API#

int kd_wifi_config(wifi_config_t *config)

配置WiFi工作参数:

  • 配置目标AP的名称、密码、认证及加密方式

  • 配置WiFi休眠等级,苏醒周期以及可唤醒的gpio

  • 配置tcp keepalive时间参数等

数据结构#

wifi_config_t#
typedef struct {
unsigned int config_mask;
#define CFG_MASK_SLEEP (1 << 0)
#define CFG_MASK_CONNECT (1 << 1)
#define CFG_MASK_KEEPALIVE (1 << 2)
wifi_sleep_t sleep;
wifi_connect_t conn;
wifi_keepalive_t keepalive;
} wifi_config_t;

表 6-1 wifi_config_t结构体成员

成员

说明

config_mask

配置目标项掩码,使能或屏蔽目标项,例如全部配置则:config_mask = CFG_MASK_SLEEP|CFG_MASK_CONNECT|CFG_MASK_KEEPALIVE; CFG_MASK_SLEEP:配置休眠参数,CFG_MASK_CONNECT:配置AP连接参数,CFG_MASK_KEEPALIVE:配置tcp keepalive参数

sleep

休眠参数

conn

AP连接参数

keepalive

tcp keepalive参数

wifi_sleep_t#

typedef struct
{
unsigned int level;
#define WIFI_SLEEP_LIGHT 1
#define WIFI_SLEEP_DEEP 2
#define WIFI_SLEEP_ULTRA 3
unsigned int period;
union
{
/*
* gpioX_wake: 0---disable, 1---enable
*/
struct {
unsigned int gpio0_wake:1;
unsigned int gpio1_wake:1;
unsigned int gpio2_wake:1;
unsigned int gpio3_wake:1;
unsigned int gpio4_wake:1;
unsigned int gpio5_wake:1;
unsigned int gpio6_wake:1;
unsigned int gpio7_wake:1;
unsigned int gpio8_wake:1;
unsigned int gpio9_wake:1;
unsigned int gpio10_wake:1;
unsigned int gpio11_wake:1;
unsigned int gpio12_wake:1;
unsigned int gpio13_wake:1;
unsigned int gpio14_wake:1;
};
unsigned int wake_gpios;
};
} wifi_sleep_t;

表 6-2 wifi_sleep_t结构体成员

成员

说明

level

休眠等级 WIFI_SLEEP_LIGHT:浅睡 WIFI_SLEEP_DEEP:深睡,主要休眠模式 WIFI_SLEEP_ULTRA:超深睡,只有3/5/7/14号gpio可唤醒,目前不使用

period

苏醒周期,有效数值33~~4000ms。WiFi周期性从休眠态醒来,检测AP是否有发给自己的数据缓存

wake_gpios

enable或disable可唤醒WiFi的gpio(WiFi侧gpio)

wifi_connect_t#

typedef struct
{
char ssid[EXT_WIFI_MAX_SSID_LEN + 1];
ext_wifi_auth_mode auth;
char key[EXT_WIFI_MAX_KEY_LEN + 1];
unsigned char bssid[EXT_WIFI_MAC_LEN];
ext_wifi_pairwise pairwise;
} wifi_connect_t;

表 6-3 wifi_connect_t结构体成元

ssid

AP名称

auth

认证类型 EXT_WIFI_SECURITY_OPEN EXT_WIFI_SECURITY_WEP EXT_WIFI_SECURITY_WPA2PSK EXT_WIFI_SECURITY_WPAPSK_WPA2PSK_MIX EXT_WIFI_SECURITY_WPAPSK EXT_WIFI_SECURITY_WPA EXT_WIFI_SECURITY_WPA2 EXT_WIFI_SECURITY_SAE EXT_WIFI_SECURITY_WPA3_WPA2_PSK_MIX EXT_WIFI_SECURITY_UNKNOWN

Key

AP密码

bssid

AP bssid,一般为AP mac地址

pairwise

加密类型 EXT_WIFI_PARIWISE_UNKNOWN EXT_WIFI_PAIRWISE_AES EXT_WIFI_PAIRWISE_TKIP EXT_WIFI_PAIRWISE_TKIP_AES_MIX

wifi_keepalive_t#

typedef struct
{
unsigned char svrip[16];
unsigned short svrport;
unsigned short tcp_keepalive_time;
unsigned short tcp_keepalive_intvl;
unsigned short tcp_keepalive_probes;
unsigned short heartbeat_intvl;
unsigned short heartbeat_probes;
} wifi_keepalive_t;

表 6-4 wifi_keepalive_t结构体成员

svrip

server端ip地址

svrport

server端端口号

tcp_keepalive_time

TCP层keepalive心跳包常规发送周期,秒

tcp_keepalive_intvl

TCP层keepalive心跳包无回应之后新的发送周期,秒

tcp_keepalive_probes

TCP层keepalive心跳包无回应计数超过该阈值之后,判断TCP连接异常,断开重连

heartbeat_intvl

应用层心跳包发送周期,秒

heartbeat_probes

应用层心跳包无回应计数超过该阈值之后,判断socket连接异常,断开重连

sleep接口#

int kd_wifi_sleep(void)

控制WiFi进入休眠,休眠相关参数在config API当中设置。

基本性能测试#

吞吐量测试#

在办公室环境使用iperf进行网络吞吐量测试,PC通过网线接入AP,K230 EVB通过AiW4211LV10接入同一AP,分别在两端启动iperf工具,交叉测试上行及下行吞吐量。

client:iperf -c xxx.xxx.xxx.xxx -i 2 -t 300

server:iperf -s -i 2

dual:iperf -c xxx.xxx.xxx.xxx -i 2 -t 300 -d

表 7-1 TCP吞吐量粗测数据

WiFi ROLE

Bandwidth(Mbits/sec)

client

12.2

server

20.3

client:iperf -c xxx.xxx.xxx.xxx -i 2 -t 300 -u -b 25M

server:iperf -s -i 2 -u

表 7-2 UDP吞吐量粗测数据

WiFi ROLE

Bandwidth(Mbits/sec)

Jitter(ms)

Lost/Total Datagrams

client

17.8

1.341

1571/455457 (0.34%)

server

21.0

1.064

1/534990 (0.00019%)

文件传输测试#

分别在PC与K230 EVB端架设nginx服务器,并分别使用wget拉取544MB大文件,并校验拉取文件的MD5值,测试150次无异常。

评论列表
条评论
登录