【星闪技术】WS63E模块的WiFi客户端测试
引言
我所计划的WS63E测试要实现MQTT联网,所以首先需要确保开发板连接WiFi。今天来测试一下WiFi功能。
程序分析
WiFi客户端的例子在src/application/samples/wifi/sta_sample目录下。这个例子看上去和hi3861的例子差不多。
这段程序是一个用于嵌入式设备的Wi-Fi Station(STA)模式的示例程序,它使用了LwIP网络堆栈和CMSIS-RTOS API。程序的主要目的是连接到一个指定的Wi-Fi网络,并获取IP地址。以下是对程序的分析:
-
头文件包含:程序包含了多个头文件,这些头文件提供了网络接口、Wi-Fi热点配置、基础类型定义、标准库、串口通信、操作系统服务、应用初始化和系统抽象层等功能的支持。
-
宏定义:定义了一些常量,如Wi-Fi接口名称的最大长度、SSID的最大长度、扫描AP的限制、MAC地址的长度等。
-
事件回调函数:定义了两个静态函数
wifi_scan_state_changed
和wifi_connection_changed
,它们分别在Wi-Fi扫描状态变化和连接状态变化时被调用。 -
Wi-Fi事件结构体:定义了一个
wifi_event_stru
结构体,用于注册Wi-Fi事件回调。 -
状态枚举:定义了一个枚举
wifi_state_enum
,用于跟踪STA模式下的不同状态。 -
全局变量:定义了一个全局变量
g_wifi_state
,用于保存当前的Wi-Fi状态。 -
扫描事件回调函数:
wifi_scan_state_changed
函数在扫描完成时被调用,它将全局状态设置为扫描完成。 -
关联事件回调函数:
wifi_connection_changed
函数在连接状态变化时被调用,它根据连接是否成功更新全局状态。 -
匹配目标AP函数:
example_get_match_network
函数用于在扫描结果中找到指定的网络,并填充连接请求信息。 -
关联状态查询函数:
example_check_connect_status
函数用于检查是否成功连接到AP。 -
DHCP状态查询函数:
example_check_dhcp_status
函数用于检查是否成功获取IP地址。 -
STA功能函数:
example_sta_function
函数是STA模式的主要逻辑,它按照状态枚举的顺序执行操作,包括启动扫描、连接到AP、获取IP地址等。 -
初始化函数:
sta_sample_init
函数用于初始化Wi-Fi事件回调、等待Wi-Fi初始化完成,并调用example_sta_function
函数。 -
任务入口函数:
sta_sample_entry
函数用于创建一个名为sta_sample_task
的线程,该线程运行sta_sample_init
函数。 -
程序入口:
app_run
函数调用sta_sample_entry
函数,启动STA模式的任务。
整体来看,这个程序是一个完整的Wi-Fi Station模式的示例,它展示了如何使用事件回调、状态机和网络接口来连接到一个Wi-Fi网络并获取IP地址。程序使用了CMSIS-RTOS API来创建线程和延时,以及LwIP API来处理网络相关的操作。
程序测试
编译程序之前,需要先修改程序中的SSID和密码设置。这个参数在example_get_match_network函数中。
td_s32 example_get_match_network(wifi_sta_config_stru *expected_bss)
{td_s32 ret;td_u32 num = 64; /* 64:扫描到的Wi-Fi网络数量 */td_char expected_ssid[] = "my_softAP";td_char key[] = "my_password"; /* 待连接的网络接入密码 */td_bool find_ap = TD_FALSE;td_u8 bss_index;/* 获取扫描结果 */td_u32 scan_len = sizeof(wifi_scan_info_stru) * WIFI_SCAN_AP_LIMIT;wifi_scan_info_stru *result = osal_kmalloc(scan_len, OSAL_GFP_ATOMIC);if (result == TD_NULL) {return -1;}memset_s(result, scan_len, 0, scan_len);ret = wifi_sta_get_scan_info(result, &num);if (ret != 0) {osal_kfree(result);return -1;}/* 筛选扫描到的Wi-Fi网络,选择待连接的网络 */for (bss_index = 0; bss_index < num; bss_index ++) {if (strlen(expected_ssid) == strlen(result[bss_index].ssid)) {if (memcmp(expected_ssid, result[bss_index].ssid, strlen(expected_ssid)) == 0) {find_ap = TD_TRUE;break;}}}/* 未找到待连接AP,可以继续尝试扫描或者退出 */if (find_ap == TD_FALSE) {osal_kfree(result);return -1;}/* 找到网络后复制网络信息和接入密码 */if (memcpy_s(expected_bss->ssid, WIFI_MAX_SSID_LEN, expected_ssid, strlen(expected_ssid)) != 0) {osal_kfree(result);return -1;}if (memcpy_s(expected_bss->bssid, WIFI_MAC_LEN, result[bss_index].bssid, WIFI_MAC_LEN) != 0) {osal_kfree(result);return -1;}expected_bss->security_type = result[bss_index].security_type;if (memcpy_s(expected_bss->pre_shared_key, WIFI_MAX_SSID_LEN, key, strlen(key)) != 0) {osal_kfree(result);return -1;}expected_bss->ip_type = 1; /* 1:IP类型为动态DHCP获取 */osal_kfree(result);return 0;
}
修改好SSID和密码,就可以编译并下载程序了。程序启动后扫描附近的所有WiFi热点,如果找到制定的热点,就自动连接。
从这段日志看,程序成功的连接到热点,并通过DHCP协议获得了IP地址。
完整的程序日志如下:
boot.
Flash Init Fail! ret = 0x80001341
verify_public_rootkey secure verify disable!
verify_params_key_area secure verify disable!
verify_params_area_info secure verify disable!
verify_image_key_area secure verify disable!
verify_image_code_info secure verify disable!
SSB Uart Init Succ!
SSB Flash Init Succ!
verify_image_key_area secure verify disable!
verify_image_code_info secure verify disable!
Flashboot Uart Init Succ!
Flashboot Malloc Init Succ!
Flash Init Succ!
No need to fix SR!
flashboot version : 1.10.101
[UPG] upgrade init OK!
No need to upgrade...
flash_encrypt disable.
verify_image_key_area secure verify disable!
verify_image_code_info secure verify disable!
APP|Debug uart init succ.
[UPG] upgrade init OK!
APP|init_dev_addr, mac_addr:0x80,0x 0,0x73,0xdb,0x**,0x**,
xo_trim_temp_comp val:0 0
APP|AT uart init succ.
los_at_plt_cmd_register EXCUTE
APP|WARNING: main_initialise::thread[11] func is null
APP|[WIFI_STA_SAMPLE]::Create sta_sample_task succ.
cpu 0 entering schedulerAPP|btc open
[RADAR_LOG] alg ctrl read from nv [1][2][0][0][1][1][20]
device_main_init: 0!
===hal_initialize_phy===225===
device_module_init:: succ!
cali_set_cali_mask:old[0x0] -> new[0x1fa2]fe_rf_initialize
cali_offline_cali_entry enter
cali_set_cali_done_flag:old[0x0] -> new[0x1]rf cali OK. time cost:22, ret:0
APP|[WIFI_STA_SAMPLE]::wifi_event_cb register succ.
APP|[WIFI_STA_SAMPLE]::wifi init succ.
drv_soc_ioctl ioctl_cmd->cmd=7.
drv_soc_ioctl ioctl_cmd->cmd=9.
drv_soc_ioctl ioctl_cmd->cmd=17.
drv_soc_ioctl ioctl_cmd->cmd=13.
drv_soc_ioctl ioctl_cmd->cmd=35.
drv_soc_ioctl ioctl_cmd->cmd=2.
drv_soc_ioctl ioctl_cmd->cmd=2.
drv_soc_ioctl ioctl_cmd->cmd=2.
drv_soc_ioctl ioctl_cmd->cmd=2.
drv_soc_ioctl ioctl_cmd->cmd=2.
drv_soc_ioctl ioctl_cmd->cmd=2.
drv_soc_ioctl ioctl_cmd->cmd=41.
APP|[WIFI_STA_SAMPLE]::STA enable succ.
APP|[WIFI_STA_SAMPLE]::Scan start!
drv_soc_ioctl ioctl_cmd->cmd=14.
hmac_single_hal_device_scan_complete:vap[1] time[761] chan_cnt[13] chan_0[1] back[0] event[6] mode[0]
Scan::vap[1] find bss_num[28] in regdomain, other bss_num[0]
Srv:548:recive event = 1
APP|[WIFI_STA_SAMPLE]::Scan done!.
Srv:1723:sta_scan_results cnt 28
APP|[WIFI_STA_SAMPLE]::Connect start.
Srv:find ssid[CU_fjGX] auth type[2] pairwise[1] ft_flag[0]
drv_soc_ioctl ioctl_cmd->cmd=47.
drv_soc_ioctl ioctl_cmd->cmd=47.
drv_soc_ioctl ioctl_cmd->cmd=47.
drv_soc_ioctl ioctl_cmd->cmd=16.
drv_soc_ioctl ioctl_cmd->cmd=6.
drv_soc_ioctl ioctl_cmd->cmd=6.
drv_soc_ioctl ioctl_cmd->cmd=47.
APP|Hello world!
drv_soc_ioctl ioctl_cmd->cmd=6.
drv_soc_ioctl ioctl_cmd->cmd=5.
drv_soc_ioctl ioctl_cmd->cmd=6.
drv_soc_ioctl ioctl_cmd->cmd=6.
drv_soc_ioctl ioctl_cmd->cmd=5.
drv_soc_ioctl ioctl_cmd->cmd=1.
drv_soc_ioctl ioctl_cmd->cmd=3.
drv_soc_ioctl ioctl_cmd->cmd=1.
+NOTICE:CONNECTED
drv_soc_ioctl ioctl_cmd->cmd=6.
Srv:548:recive event = 2
APP|[WIFI_STA_SAMPLE]::Connect succ!.
APP|[WIFI_STA_SAMPLE]::DHCP start.
xo update temp:4,diff:0,xo:0x3083c
APP|[WIFI_STA_SAMPLE]::STA DHCP success.
APP|[SYS INFO] mem: used:134448, free:229572; log: drop/all[0/0], at_recv 0.
APP|[SYS INFO] mem: used:134448, free:229572; log: drop/all[0/0], at_recv 0.
APP|[SYS INFO] mem: used:134448, free:229572; log: drop/all[0/0], at_recv 0.
结语
WS63E上实现WiFi比较容易,下一阶段将添加MQTT连接华为云的代码。
相关文章:

【星闪技术】WS63E模块的WiFi客户端测试
引言 我所计划的WS63E测试要实现MQTT联网,所以首先需要确保开发板连接WiFi。今天来测试一下WiFi功能。 程序分析 WiFi客户端的例子在src/application/samples/wifi/sta_sample目录下。这个例子看上去和hi3861的例子差不多。 这段程序是一个用于嵌入式设备的Wi-F…...

Android面试之5个Kotlin深度面试题:协程、密封类和高阶函数
本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点 面试题目1:Kotlin中的协程与线程的区别是什么?如何在Android中使用协程进行异步编程? 解答: 协…...

操作系统 和 初识进程
目录 操作系统(OS) 进程 操作系统(OS) 概念 操作系统即os,是一款软件。 任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)。 操作系统的本质是一种进行软硬件管理的软件 笼统的理解…...

QT--Qlabel学习、获取文本和设置文本、文本对齐方式、文本换行、显示图片
QLabel 是 Qt 中的标签类,通常用于显示提示性的文本,也可以显示图像 对齐方式 用于设置标签中的内容在水平和垂直两个方向上的对齐方式,比如左对齐、右对齐、上对齐、下对齐、水平居中、垂直居中等。 // 获取和设置文本的对齐方式 Qt::Ali…...

深度学习:终身学习(Life-Long Learning)详解
终身学习(Life-Long Learning)详解 终身学习(也称为持续学习或增量学习)是机器学习中的一个重要研究领域,它关注如何使机器学习模型在完成一系列任务后,能够持续学习新任务,而不会忘记之前学到…...

前端UI框架
组件UI类 1.Element-Plus 2.uView 3.Vant 4.TDesign 5.uni-app 6.Tuniao-vue3 7. 可视化图标类 1.可视化图标VUE Data UI 2.Echart 图标库ICON 1.yesicon 2.Flaticon 3.Google Fonts 4.fontawesome 5.阿里巴巴 其他 1.CSS布局 2.web前端样式布局 3.中国色-颜色合集 托管…...

最佳副屏串流解决方案:如何低成本打造电脑拓展副屏?
如何低成本打造电脑拓展副屏?如果你有一台平板和一台电脑,想要提高打游戏、办公或是学习的效率。那么,使用网易GameViewer远程,就能帮你低成本打造电脑拓展副屏。 简单来说,副屏串流就是能让你多出一块显示屏。在打游戏…...

SQL Injection | SQL 注入概述
关注这个漏洞的其他相关笔记:SQL 注入漏洞 - 学习手册-CSDN博客 0x01:SQL 注入漏洞介绍 SQL 注入就是指 Web 应用程序对用户输入数据的合法性没有判断,前端传入后端的参数是可控的,并且参数会带入到数据库中执行,导致…...

【Linux 从基础到进阶】磁盘I/O性能调优
磁盘I/O性能调优 1. 引言 磁盘I/O性能是决定服务器整体性能的关键因素之一。磁盘I/O性能的瓶颈常常会影响数据库、文件系统以及虚拟化平台等关键应用的响应时间。因此,磁盘I/O调优是系统管理员不可忽视的任务。 本文将介绍影响磁盘I/O性能的主要因素,…...

浅谈AGI时代的“数据枢纽”——向量数据库
一、前言 人工智能的关键,不只是构建好算力、算法、模型,更重要的是做好数据的清洗、处理、挖掘等问题。一定程度上,智能时代,企业数据处理能力有多强,决定了业务发展的天花板有多高。 在企业数智化转型过程中&#x…...

生成 Excel 表列名称
Excel 大家都用过,它的列名是用字母编号的,A 表示第一列,B 表示第二列,AA 表示第27列,AB 表示第28列等等。 现给定一个数字,如何得到列名称呢。比如输入28,输出 AB。 一开始以为就是一个简单的…...

基于yolov10的烟雾明火检测森林火灾系统python源码+pytorch模型+评估指标曲线+精美GUI界面+数据集
【算法介绍】 基于YOLOv10的烟雾明火检测森林火灾系统是一种先进的火灾预警系统,它结合了深度学习和计算机视觉技术,能够实时检测和分析森林中的烟雾和明火,从而有效预防和控制森林火灾的发生。 该系统主要基于YOLOv10模型进行构建…...

UltraISO(软碟通)制作U盘制作Ubuntu20.04启动盘
目录 一、启动盘制作 1、工具准备 2、打开UltraISO后,点击左上角的文件,在打开的下拉项中,选择打开准备好的Ubuntu系统20.04 LTS镜像文件(ubuntu-20.04-desktop-amd64.iso); 3、然后点击启动->写入硬盘映像 4、在弹出的窗…...

【EtherCAT实践篇一】TwinCAT 3安装、使用
TwinCAT 基于 PC 的开放式控制技术 倍福推出的基于 PC 的控制技术定义了自动化领域的全球标准。在软件方面,1996 年推出的 TwinCAT(The Windows Control and Automation Technology,基于 Windows 的控制和自动化技术)自动化套件是…...

4、CSS3笔记
文章目录 四、CSS3CSS3简介css3概述CSS3私有前缀什么是私有前缀为什么要有私有前缀常见浏览器私有前缀 CSS3基本语法CSS3新增长度单位CSS3新增颜色设置方式CSS3新增选择器CSS3新增盒模型相关属性box-sizing 怪异盒模型resize 调整盒子大小box-shadow 盒子阴影opacity 不透明度 …...

Docker无法拉取镜像解决办法
Docker 无法拉取镜像解决办法 一.现象描述 在docker拉取镜像的时候重复拉取镜像然后超时。 二.解决办法 1.配置国内镜像源地址加速 vi /etc/docker/daemon.json在文件中增加如下内容 { "registry-mirrors": ["https://docker.m.daocloud.io","h…...

Ubuntu 20.04安装Qt 5.15(最新,超详细)
Ubuntu 20.04安装Qt 5.15 1. 准备注册Qt账号安装依赖下载安装工具 2. 安装3. 测试参考 前言 Qt 是一个跨平台的应用程序框架,它支持开发 C 图形用户界面应用程序。Qt 可以用于开发运行在多种操作系统上的应用程序,包括 Windows、Linux、macOS 和各种移动…...

桂林旅游一点通:SpringBoot平台应用
3系统分析 3.1可行性分析 通过对本桂林旅游景点导游平台实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本桂林旅游景点导游平台采用SSM框架,JAVA作…...

【WPF】04 Http消息处理类
这里引入微软官方提供的HttpClient类来实现我们的目的。 首先,介绍一下官方HttpClient类的内容。 HttpClient 类 定义 命名空间: System.Net.Http 程序集: System.Net.Http.dll Source: HttpClient.cs 提供一个类,用于从 URI 标识的资源发送 HTTP 请…...

如何精准设置线程数,提升系统性能的秘密武器!
线程数设定多少更合适? 线程数的设定需要根据任务的类型、系统资源、以及并发需求来进行权衡。设定合适的线程数可以有效提升系统的性能,但设置过多或过少都会影响程序的效率。以下是一些关键因素和计算方法,用于帮助确定最合适的线程数。 …...

正则表达式:从入门到精通
正则表达式(Regular Expression,简称 regex)是一种强大的文本匹配和处理工具。它可以用于搜索、替换、验证和提取文本中的特定模式。本文将带您深入了解正则表达式的各个方面,从基础知识到高级技巧。 1. 基础知识 1.1 什么是正则表达式? 正则表达式是由一系列字符和特殊…...

CRMEB标准版Mysql修改sql_mode
数据库配置 1.宝塔控制面板-软件商店-MySql-设置 2.点击配置修改,查找sql-mode或sql_mode (可使用CtrlF快捷查找) 3.复制 NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION 然后替换粘贴,保存 注:MySQL8.0版本的 第三步用…...

linux驱动访问的地址为虚拟地址
在Linux驱动程序中,访问的内存地址通常是虚拟地址。这是因为Linux操作系统采用了虚拟内存管理机制,所有的用户空间和内核空间的内存地址都是虚拟地址。下面是一些关键点,以帮助更好地理解这个概念: 虚拟地址与物理地址࿱…...

基于SpringBoot+Vue+uniapp微信小程序的社区门诊管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念,提供了一套默认的配置,让开发者可以更专注于业务逻辑而不是配置文件。Spring Boot 通过自动化配置和约…...

使用WPF写一个简单的开关控件
<Window x:Class"WPF练习.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend/2008"xm…...

FPGA采集adc,IP核用法,AD驱动(上半部分)
未完结,明天补全 IP核:集成的一个现有的模块 串口写好后基本不会再修改串口模块内部的一些逻辑,将串口.v文件添加进来,之后通过他的上层的接口去对他进行使用,所以我们打包IP,之后就不用去添加源文件了&a…...

MongoDB 如何做mapreduce
以下是在MongoDB中使用MapReduce的详细步骤和相关说明: 1. MapReduce的概念 MapReduce是一种用于大规模数据处理的编程模型,它由两个主要阶段组成:Map阶段和Reduce阶段。在MongoDB中,MapReduce操作允许在服务器端对数据进行批量…...

Vue是一套构建用户界面的渐进式框架,常用于构建单页面应用
学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……) 2、学会Oracle数据库入门到入土用法(创作中……) 3、手把手教你开发炫酷的vbs脚本制作(完善中……) 4、牛逼哄哄的 IDEA编程利器技巧(编写中……) 5、面经吐血整理的 面试技…...

c++ 桶排序(看这一篇就够了)
1. 概述 桶排序(Bucket Sort)又称箱排序,是一种比较常用的排序算法。其算法原理是将数组分到有限数量的桶里,再对每个桶分别排好序(可以是递归使用桶排序,也可以是使用其他排序算法将每个桶分别排好序&…...

格点拉格朗日插值与PME算法
技术背景 在前面的一篇博客中,我们介绍了拉格朗日插值法的基本由来和表示形式。这里我们要介绍一种拉格朗日插值法的应用场景:格点拉格朗日插值法。这种场景的优势在于,如果我们要对整个实数空间进行求和或者积分,计算量是随着变量…...