WLAN框架应用笔记
WLAN框架应用笔记
1本文的目的和结构
1.1本文的目的和背景
随着物联网快速发展,越来越多的嵌入式设备上搭载了WIFI无线网络设备。为了能够管理WIFI网络设备,RT-线程引入了WLAN设备管理框架。这套框架具备控制和管理WIFI的众多功能,为开发者使用WIFI设备提供许多便利。
本文将帮助开发者学会使用这套框架控制管理WIFI。将从概念,示例等多方面介绍WLAN框架的相关知识,通过壳及代码两种方式展示WIFI相关的功能,如控制WIFI扫描,连接,断开等。
1.2本文的结构
WLAN框架介绍
WLAN框架配置
WLAN框架使用
2问题阐述
本应用笔记主要围绕下面几个问题来介绍WLAN框架
WLAN框架是什么,具有什么功能?
如何配置WLAN框架?
如何使用WLAN框架?
想要解决上诉问题,就要了解WLAN框架的组成原理,学会使用WLAN框架中的各种功能,下面将逐步开始介绍WLAN框架的组成及相关功能的使用。
3问题解决
3.1 WLAN框架介绍
WLAN框架是RT-螺纹开发的一套用于管理WIFI的中间件。对下连接具体的WIFI驱动,控制WIFI的连接断开,扫描等操作。对上承载不同的应用,为应用提供WIFI控制,事件,数据导流等操作,为上层应用提供统一的WIFI控制接口.WLAN框架主要由三个部分组成.DEV驱动接口层,为WLAN框架提供统一的调用接口。管理管理层为用户提供WIFI扫描,连接,断线重连等具体功能.Protocol协议负责处理WIFI上产生的数据流,可根据不同的使用场景挂载不同通讯协议,如LWIP等。具有使用简单,功能齐全,对接方便,兼容性强等特点。
3.2 WLAN框架组成
下图是WIFI框架的结构框架
第一部分应用为应用层。是基于WLAN框架的具体应用,如无线网络相关的外壳命令。
第二部分airkiss,语音为配网层,提供无线配网和声波配网等功能。
第三部分WLAN管理器为WLAN管理层。能够对WLAN设备进行控制和管理。具备设置模式,连接热点,断开热点,启动热点,扫描热点等WLAN控制相关的功能。还提供断线重连,自动切换热点等管理功能。
第四部分WLAN协议为协议层。将数据流递交给具体协议进行解析,用户可以指定使用不同的协议进行通信。
第五部分WLAN配置为参数管理层。管理连接成功的热点信息及密码,并写入非易失的存储介质中。
第六部分WLAN dev为驱动接口层。对接具体WLAN硬件,为管理层提供统一的调用接口。
3.3 WLAN框架功能
自动连接打开自动连接功能后,只要WIFI处在断线状态,就会自动读取之前连接成功的热点信息,连接热点。如果一个热点连接失败,则切换下一个热点信息进行连接,直到连接成功为止。自动连接使用的热点信息,按连接成功的时间顺序,依次尝试,优先使用最近连接成功的热点信息。连接成功后,将热点信息缓存在最前面,下次断线优先使用。
参数存储存储连接成功的WIFI参数,WIFI参数会在内存中缓存一份,如果配置外部非易失存储接口,则会在外部存储介质中存储一份。用户可根据自己的实际情况,实现
struct rt_wlan_cfg_ops
这个结构体,将参数保存任何地方。缓存的参数主要给自动连接提供热点信息,无线网络处在未连接状态时,会读取缓存的参数,尝试连接。WIFI控制提供完备的WIFI控制接口,扫描,连接,热点等。提供WIFI相关状态回调事件,断开,连接,连接失败等。为用户提供简单易用的WIFI管理接口。
Shell命令可在Msh中输入命令控制WIFI执行扫描,连接,断开等动作。打印WIFI状态等调试信息。
3.4 WLAN框架配置及初始化
本文将基于正点原子 STML4 IOT board
开发板,该开发板板载一颗AP6181 WiFi芯片,且WiFi驱动已经实现。适合用来学习WLAN管理框架。
WLAN框架配置主要包括以下几个方面
开启WLAN框架,并配置
初始化WLAN设备,并指定使用的协议
3.4.1 WLAN框架配置
这里将介绍WIFI框架相关的配置,使用ENV展示进入工具 IOT board
目录,在ENV命令的行中输入侧 menuconfig
命令,打开图形配置界面
- 在
menuconfig
配置界面依次选择,RT-Thread Components -> Device Drivers -> Using WiFi ->
如下图所示
下面将介绍这些配置项
使用Wi-Fi框架:使用WLAN管理框架
车站的WiFi设备名称:Station设备默认名字
ap:ap设备默认名字的WiFi设备名称
默认传输协议:默认协议
扫描超时时间:扫描结果超时时间
connect timeout time:连接超时时间
SSID名称最大长度:SSID最大长度
最大密码长度:密码最大长度
扫描结果的自动排序:扫描结果自动排序
自动保存的最大WiFi信息数量:自动保存最多条目数
WiFi工作队列线程名称:WIFI后台线程名字
wifi工作队列线程大小:WIFI后台线程栈大小
WiFi工作队列线程优先级:WIFI后台线程优先级
最大驱动程序事件数:dev layer一种事件最大注册数
强制使用PBUF传输:强行使用PBUF交换数据
启用WLAN调试选项:打开调试日志
按照上图配置好后,保存然后退出
3.4.2 WLAN设备初始化
WLAN框架需要指定一个初始化WLAN设备的工作模式,这些需要写代码实现,所以需要以下代码进行初始化代码如下:
int wifi_init(void)
{rt_wlan_set_mode(RT_WLAN_DEVICE_STA_NAME, RT_WLAN_STATION); //配置WLAN设备工作模式return 0;
}
编写好上面的代码,一定要调用执行一次,即可使用使用WLAN框架管理设备了。
3.5 WLAN使用
注:进行下面操作之前,一定要先执行WLAN设备初始化,查看详
WLAN设备初始化
部分
3.5.1 Shell操作WiFi
使用外壳命令,可以帮助我们快速调试无线网络相关功能。只需要在MSH中输入相应的命令,无线网络就执行相应的动作。下面将通过三条命令,展现使用外壳命令操作的WiFi。
无线网络相关的外壳命令如下:
wifi :打印帮助
wifi help :查看帮助
wifi join SSID [PASSWORD] :连接wifi,SSDI为空,使用配置自动连接
wifi ap SSID [PASSWORD] :建立热点
wifi scan :扫描全部热点
wifi disc :断开连接
wifi ap_stop :停止热点
wifi status :打印wifi状态 sta + ap
wifi smartconfig :启动配网功能
3.5.1.1 WIFI扫描
执行无线扫描命令后,会将周围的热点信息打印在终端上。通过打印的热点信息,可以看到SSID,MAC地址等多项属性。
- wifi扫描命令格式如下
wifi scan
命令说明
字段 | 描述 |
---|---|
无线上网 | 有关无线网络命令都以无线开头 |
扫描 | 无线网络执行扫描动作 |
在msh中输入该命令,即可进行wifi命令扫描,扫描结果如下图所示
wifi scan
SSID MAC security rssi chn Mbps
------------------------------- ----------------- -------------- ---- --- ----
rtt_test_ssid_1 c0:3d:46:00:3e:aa OPEN -14 8 300
test_ssid 3c:f5:91:8e:4c:79 WPA2_AES_PSK -18 6 72
rtt_test_ssid_2 ec:88:8f:88:aa:9a WPA2_MIXED_PSK -47 6 144
rtt_test_ssid_3 c0:3d:46:00:41:ca WPA2_MIXED_PSK -48 3 300
3.5.1.2 WIFI连接
执行无线网络连接命令后,如果热点存在,且密码正确,开发板会连接上热点,并获得IP地址。网络连接成功后,可使用插座套接字进行网络通讯。
- wifi连接命令格式如下
wifi join rtt-SSID0 12345678
- 命令解析
字段 | 描述 |
---|---|
无线上网 | 有关无线网络命令都以无线开头 |
加入 | 无线网络执行连接动作 |
SSID | 热点的名字 |
123456789 | 热点的密码,没有密码可不输入这一项 |
- 连接成功后,将在终端上打印获得的IP地址,如下图所示
wifi join ssid_test 12345678
[I/WLAN.mgnt] wifi connect success ssid:ssid_test
[I/WLAN.lwip] Got IP address : 192.168.1.110
3.5.1.3 WIFI断开
执行无线网络连接断开命令后,开发板将断开与热点的连接。
- wifi断开命令格式如下
wifi disc
- 命令解析
字段 | 描述 |
---|---|
无线上网 | 有关无线网络命令都以无线开头 |
圆盘 | wifi的执行断开动作 |
- 断开成功后,将在终端上打印如下信息,如下图所示
wifi disc
[I/WLAN.mgnt] disconnect success!
3.5.2 WiFi扫描
下面这段代码将展示WiFi同步扫描,然后我们将结果打印在终端上。先需要执行WIFI初始化,然后执行WIFI扫描函数 rt_wlan_scan_sync
,这个函数是同步的,函数返回的扫描的数量和结果。在这个示例中,会将扫描的热点名字打印出来。
#include <rthw.h>
#include <rtthread.h>#include <wlan_mgnt.h>
#include <wlan_prot.h>
#include <wlan_cfg.h>void wifi_scan(void)
{struct rt_wlan_scan_result *result;int i = 0;/* Configuring WLAN device working mode */rt_wlan_set_mode(RT_WLAN_DEVICE_STA_NAME, RT_WLAN_STATION);/* WiFi scan */result = rt_wlan_scan_sync();/* Print scan results */rt_kprintf("scan num:%d\n", result->num);for (i = 0; i < result->num; i++){rt_kprintf("ssid:%s\n", result->info[i].ssid.val);}
}int scan(int argc, char *argv[])
{wifi_scan();return 0;
}
MSH_CMD_EXPORT(scan, scan test.);
运行结果如下:
3.5.3 WiFi连接与断开
下面这段代码将展示无线同步连接。
先需要执行WIFI初始化,常见然后一个用于等待 RT_WLAN_EVT_READY
事件的信号量。注册需要关注的事件的回调函数,执行 rt_wlan_connect
无线连接函数,函数返回表示是否已经连接成功。但是连接成功还不能进行通信,还需要等待网络获取IP,使用事先创建的信号量等待网络准备好,网络准备好后,就能正常通信了。
连接上WIFI后,等待一段时间后,执行 rt_wlan_disconnect
函数断开连接。断开操作是阻塞的,返回值表示是否断开成功。
#include <rthw.h>
#include <rtthread.h>#include <wlan_mgnt.h>
#include <wlan_prot.h>
#include <wlan_cfg.h>#define WLAN_SSID "SSID-A"
#define WLAN_PASSWORD "12345678"
#define NET_READY_TIME_OUT (rt_tick_from_millisecond(15 * 1000))static rt_sem_t net_ready = RT_NULL;static void
wifi_ready_callback(int event, struct rt_wlan_buff *buff, void *parameter)
{rt_kprintf("%s\n", __FUNCTION__);rt_sem_release(net_ready);
}static void
wifi_connect_callback(int event, struct rt_wlan_buff *buff, void *parameter)
{rt_kprintf("%s\n", __FUNCTION__);if ((buff != RT_NULL) && (buff->len == sizeof(struct rt_wlan_info))){rt_kprintf("ssid : %s \n", ((struct rt_wlan_info *)buff->data)->ssid.val);}
}static void
wifi_disconnect_callback(int event, struct rt_wlan_buff *buff, void *parameter)
{rt_kprintf("%s\n", __FUNCTION__);if ((buff != RT_NULL) && (buff->len == sizeof(struct rt_wlan_info))){rt_kprintf("ssid : %s \n", ((struct rt_wlan_info *)buff->data)->ssid.val);}
}static void
wifi_connect_fail_callback(int event, struct rt_wlan_buff *buff, void *parameter)
{rt_kprintf("%s\n", __FUNCTION__);if ((buff != RT_NULL) && (buff->len == sizeof(struct rt_wlan_info))){rt_kprintf("ssid : %s \n", ((struct rt_wlan_info *)buff->data)->ssid.val);}
}rt_err_t wifi_connect(void)
{rt_err_t result = RT_EOK;/* Configuring WLAN device working mode */rt_wlan_set_mode(RT_WLAN_DEVICE_STA_NAME, RT_WLAN_STATION);/* station connect */rt_kprintf("start to connect ap ...\n");net_ready = rt_sem_create("net_ready", 0, RT_IPC_FLAG_FIFO);rt_wlan_register_event_handler(RT_WLAN_EVT_READY,wifi_ready_callback, RT_NULL);rt_wlan_register_event_handler(RT_WLAN_EVT_STA_CONNECTED,wifi_connect_callback, RT_NULL);rt_wlan_register_event_handler(RT_WLAN_EVT_STA_DISCONNECTED,wifi_disconnect_callback, RT_NULL);rt_wlan_register_event_handler(RT_WLAN_EVT_STA_CONNECTED_FAIL,wifi_connect_fail_callback, RT_NULL);/* connect wifi */result = rt_wlan_connect(WLAN_SSID, WLAN_PASSWORD);if (result == RT_EOK){/* waiting for IP to be got successfully */result = rt_sem_take(net_ready, NET_READY_TIME_OUT);if (result == RT_EOK){rt_kprintf("networking ready!\n");}else{rt_kprintf("wait ip got timeout!\n");}rt_wlan_unregister_event_handler(RT_WLAN_EVT_READY);rt_sem_delete(net_ready);rt_thread_delay(rt_tick_from_millisecond(5 * 1000));rt_kprintf("wifi disconnect test!\n");/* disconnect */result = rt_wlan_disconnect();if (result != RT_EOK){rt_kprintf("disconnect failed\n");return result;}rt_kprintf("disconnect success\n");}else{rt_kprintf("connect failed!\n");}return result;
}int connect(int argc, char *argv[])
{wifi_connect();return 0;
}
MSH_CMD_EXPORT(connect, connect test.);
运行结果如下
3.5.4 WiFi开启自动重连
先开启自动重连功能,使用命令行连接上一个热点甲后,在连接上另一个热点B.等待几秒后,将热点乙断电,系统会自动重试连接乙热点,此时乙热点连接不上,系统自动切换热点阿进行连接。连接成功甲后,系统停止连接。
#include <rthw.h>
#include <rtthread.h>#include <wlan_mgnt.h>
#include <wlan_prot.h>
#include <wlan_cfg.h>static void
wifi_ready_callback(int event, struct rt_wlan_buff *buff, void *parameter)
{rt_kprintf("%s\n", __FUNCTION__);
}static void
wifi_connect_callback(int event, struct rt_wlan_buff *buff, void *parameter)
{rt_kprintf("%s\n", __FUNCTION__);if ((buff != RT_NULL) && (buff->len == sizeof(struct rt_wlan_info))){rt_kprintf("ssid : %s \n", ((struct rt_wlan_info *)buff->data)->ssid.val);}
}static void
wifi_disconnect_callback(int event, struct rt_wlan_buff *buff, void *parameter)
{rt_kprintf("%s\n", __FUNCTION__);if ((buff != RT_NULL) && (buff->len == sizeof(struct rt_wlan_info))){rt_kprintf("ssid : %s \n", ((struct rt_wlan_info *)buff->data)->ssid.val);}
}static void
wifi_connect_fail_callback(int event, struct rt_wlan_buff *buff, void *parameter)
{rt_kprintf("%s\n", __FUNCTION__);if ((buff != RT_NULL) && (buff->len == sizeof(struct rt_wlan_info))){rt_kprintf("ssid : %s \n", ((struct rt_wlan_info *)buff->data)->ssid.val);}
}int wifi_autoconnect(void)
{/* Configuring WLAN device working mode */rt_wlan_set_mode(RT_WLAN_DEVICE_STA_NAME, RT_WLAN_STATION);/* Start automatic connection */rt_wlan_config_autoreconnect(RT_TRUE);/* register event */rt_wlan_register_event_handler(RT_WLAN_EVT_READY,wifi_ready_callback, RT_NULL);rt_wlan_register_event_handler(RT_WLAN_EVT_STA_CONNECTED,wifi_connect_callback, RT_NULL);rt_wlan_register_event_handler(RT_WLAN_EVT_STA_DISCONNECTED,wifi_disconnect_callback, RT_NULL);rt_wlan_register_event_handler(RT_WLAN_EVT_STA_CONNECTED_FAIL,wifi_connect_fail_callback, RT_NULL);return 0;
}int auto_connect(int argc, char *argv[])
{wifi_autoconnect();return 0;
}
MSH_CMD_EXPORT(auto_connect, auto connect test.);
运行结果如下:
4参考
4.1本文相关API
4.2 API列表
API | 位置 |
---|---|
rt_wlan_set_mode | wlan_mgnt.c |
rt_wlan_prot_attach | wlan_prot.c |
rt_wlan_scan_sync | wlan_mgnt.c |
rt_wlan_connect | wlan_mgnt.c |
rt_wlan_disconnect | wlan_mgnt.c |
rt_wlan_config_autoreconnect | wlan_mgnt.c |
4.3核心API详解
4.3.1 rt_wlan_set_mode()
4.4函数功能
注册WLAN设备到WLAN设备框架
4.5函数原型
rt_err_t rt_wlan_set_mode(const char *dev_name, rt_wlan_mode_t mode);
4.6函数参数
参数 | 描述 |
---|---|
的dev_name | WLAN设备名 |
模式 | WLAN设备工作模式 |
4.7返回值
返回值 | 描述 |
---|---|
-RT_EINVAL | 参数错误 |
-RT_EIO | 设备未找到 |
-RT_ERROR | 执行失败 |
RT_EOK | 执行成功 |
wlan模式可取以下值之一RT_WLAN_NONE清空工作模式RT_WLAN_STATION工作在STATION模式RT_WLAN_AP工作在AP模式
4.7.1 rt_wlan_prot_attach()
4.8函数功能
指定WLAN设备使用的协议
4.9函数原型
rt_err_t rt_wlan_prot_attach(const char *dev_name, const char *prot_name);
4.10函数参数
参数 | 描述 |
---|---|
名称 | WLAN设备名 |
prot_name | 协议名 |
4.11返回值
返回值 | 描述 |
---|---|
-RT_ERROR | 执行失败 |
RT_EOK | 执行成功 |
类型可取以下值之一RT_WLAN_PROT_LWIP协议类型为LWIP
4.11.1 rt_wlan_scan_sync()
4.12函数功能
同步扫描热点
4.13函数原型
struct rt_wlan_scan_result *rt_wlan_scan_sync(void);
4.14函数参数
无
4.15返回值
返回值 | 描述 |
---|---|
rt_wlan_scan_result | 扫描结果 |
扫描结果是一个结构体,成员如下
num:info数量信息:info指针
struct rt_wlan_scan_result
{rt_int32_t num;struct rt_wlan_info *info;
};
4.15.1 rt_wlan_connect()
4.16函数功能
同步连接热点
4.17函数原型
rt_err_t rt_wlan_connect(const char *ssid, const char *password);
4.18函数参数
参数 | 描述 |
---|---|
SSID | WIFI名字 |
密码 | WIFI密码 |
4.19返回值
返回值 | 描述 |
---|---|
-RT_EINVAL | 参数错误 |
-RT_EIO | 未注册设备 |
-RT_ERROR | 连接失败 |
RT_EOK | 连接成功 |
4.19.1 rt_wlan_disconnect()
4.20函数功能
同步断开热点
4.21函数原型
rt_err_t rt_wlan_disconnect(void);
4.22函数参数
无
4.23返回值
返回值 | 描述 |
---|---|
-RT_EIO | 未注册设备 |
-RT_ENOMEM | 内存不足 |
-RT_ERROR | 断开失败 |
RT_EOK | 断开成功 |
4.23.1 rt_wlan_config_autoreconnect()
4.24函数功能
配置自动重连模式
4.25函数原型
void rt_wlan_config_autoreconnect(rt_bool_t enable);
4.26函数参数
参数 | 描述 |
---|---|
启用 | enanle /禁用自动重连 |
4.27返回值
无
WLAN框架应用笔记相关推荐
- SSH框架搭建 笔记 (含spring注解驱动)
分类: web 开发2014-04-27 12:33 354人阅读 评论(0) 收藏 举报 框架springinterface注解 好久没有搭建框架了,今天整理下以前的知识,整合下SSH,没想到手生了 ...
- .net框架读书笔记---引用参数(ref/out)
接上一篇.net框架读书笔记---方法(类型造器) 默认情况下,CLR假设所有的方法参数都是按值传递参数的.当参数为引用类型的对象时,参数的传递是通过传递对象的引用(或)指针来完成的.这意味着方法可以 ...
- SpringMVC框架--学习笔记(下)
接上篇:SpirngMVC框架--学习笔记(上):https://blog.csdn.net/a745233700/article/details/81038382 17.全局异常处理: 系统中异常包 ...
- SpringMVC框架--学习笔记(上)
1.SpringMVC入门程序: (1)导入jar包:spring核心jar包.spring-webmvc整合Jar包 (2)配置前端控制器:web.xml文件中 <?xml version=& ...
- mybatis框架--学习笔记(下)
上篇:mybatis框架--学习笔记(上):https://blog.csdn.net/a745233700/article/details/81034021 8.高级映射: (1)一对一查询: ①使 ...
- mybatis框架--学习笔记(上)
使用JDBC操作数据库的问题总结: (1)数据库连接,使用时创建,不使用时立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响数据库性能. 设想:使用数据库连接池管理数据库连接. (2) ...
- .net框架读书笔记---通用对象操作(一)
接上一篇.net框架读书笔记---基础类型,这节主要学习这样正确实现所有对象都必须提供的一组通用操作---对象的等值性和唯一性: System.Object类型提供了一个名为Equals的虚方法,其目 ...
- .net框架读书笔记---类型成员及其访问限定(一)
接上一篇.net框架读书笔记---通用对象操作(三),开始学习类型以及每个类型的所有实例都具有的一组通用操作. 一.类型成员 一个类型可以定义零个或多个以下成员 常数,常数是一个表示恒定不变的数值的符 ...
- .net框架读书笔记---基础类型
接上一篇.net框架读书笔记---值类型的装箱与拆箱, 一.Object CLR要求每个类型都最终集成自System.Object类型,这意味着以下两种定义是相同的: //隐式继承自Object cl ...
最新文章
- centos7.9 配置nginx实现前后端分离
- Markdown简单语法
- tensorflow2版本学习教程1-mnist数据集手写字体
- css点击a标签显示下划线_好程序员HTML5培训教程-html和css基础知识
- 线性代数 第四章 向量组的线性相关性
- 小小一招解决“INSERT EXEC 语句不能嵌套”的问题
- Loj#6485. LJJ 学二项式定理
- 暑期训练日志----2018.8.17
- 经济实惠:组建P2P电影服务器
- 现代信号处理——自适应滤波器(LMS自适应滤波器)
- 在小米R1D 中,为 Advanced Tomato 添加菜单
- 第十五届全国大学生智能车全国总决赛获奖信息-创意组获奖信息
- VR和AR将如何发展下去?哪个更有前景?
- SpringBoot整合activeMQ消息队列手动签收(Session.CLIENT_ACKNOWLEDGE)为什么失效啊?
- 高精度地图-黑客又要开始装逼了!
- 标准差计算机怎么按,如何使用计算机计算平均值及禁标准差
- 达梦数据库导入dmp文件
- ringbuffer的特别之处
- 区块链技术加持下的社交软件又能玩出什么新花样
- 极市直播丨严彬-Unicorn:走向目标跟踪的大一统(ECCV2022 Oral)
热门文章
- 最新各大CMS采集资源站解析网址合集
- 详解-脏读、幻读与不可重复读
- 郭忆:网易数据库高可用架构最新进展!
- 【黑苹果教程】ELAN,FocalTech 以及 Synaptics 触控板驱动
- 统计学习方法——K近邻模型
- List转Map思想的妙用
- 我想给他拿给他拿台计算机的英文,NO-BOOK 傻瓜机英语口语中级版The machine can do the work of ten men.这机器...
- 夯实JAVA基本之一 —— 泛型详解(1):基本使用
- 『网易实习』周记(三)
- 【滴水三期】--公开课