本文来源电子发烧友社区,作者:ouxiaolong, 帖子地址:https://bbs.elecfans.com/jishu_2287628_1_1.html
开发环境:
开发环境:
开发系统:Ubuntu 20.04
MCU:Hi3861
OpenHarmony版本:3.0.1-LTS
HI3861默认已经初始化了WiFi,因此这里讲解如何使用WiFi联网。
串口终端上执行相应的AT命令,即可使Hi3861 WLAN模组联网,依次执行如下AT命令,启动STA模式,连接指定路由器,并开启DHCP功能配置IP地址。
AT+STARTSTA # 启动STA模式
AT+SCAN # 扫描周边AP
AT+SCANRESULT # 显示扫描结果
AT+CONN="SSID",,2,"PASSWORD" # 连接指定AP,其中SSID/PASSWORD为待连接的热点名称和密码
AT+STASTAT # 查看连接结果
AT+DHCP=wlan0,1 # 通过DHCP向AP请求wlan0的IP地址
查看Hi3861 WLAN模组与网关联通是否正常,如下所示。
AT+IFCFG # 查看模组接口IP
AT+PING=X.X.X.X # 检查模组与网关的联通性,其中X.X.X.X需替换为实际的网关地址
下面具体演示:
有上图可知Hi3861 WLAN模组联网成功。
当然也可在同一个局域网中ping HI3861。
说明网络是连通的。
关于Wifi联网的AT命令有很多,所有的AT指令都是通过函数hi_at_sys_cmd_register()函数注册的,其中调用了hi_at_register_cmd()函数注册AT。
重点介绍三个函数。
1.启动WiFi STA模式, AT+STARTSTA
hi_u32 cmd_sta_start_adv(hi_s32argc, const hi_char *argv[])
{
hi_s32 ret;
hi_wifi_bw bw = HI_WIFI_BW_LEGACY_20M;
return HI_ERR_FAILURE;
}
ret = (hi_s32)sta_start_adv_param(argc,argv, &bw);
if (ret != HI_ERR_SUCCESS) {
return HI_ERR_FAILURE;
}
#ifndef CONFIG_FACTORY_TEST_MODE
hi_char ifname[WIFI_IFNAME_MAX_SIZE + 1] ={0};
hi_s32 len = sizeof(ifname);
ret = hi_wifi_sta_start(ifname, &len);
if (ret != HISI_OK) {
return HI_ERR_FAILURE;
}
#endif
ret =hi_wifi_set_bandwidth(DEFAULT_IFNAME_STA, strlen(DEFAULT_IFNAME_STA) + 1, bw);
if (ret != HI_ERR_SUCCESS) {
#ifndef CONFIG_FACTORY_TEST_MODE
hi_wifi_sta_stop();
#endif
return HI_ERR_FAILURE;
}
hi_at_printf("OKrn");
return HI_ERR_SUCCESS;
}
该函数的核心就是hi_wifi_sta_start()函数。
2.连接WiFi ,AT+CONN
/*****************************************************************************
* Func description: stationconnect network
* example:AT+CONN="hisilicon",,3,"123456789"
*****************************************************************************/
hi_u32 cmd_sta_connect(hi_s32argc, const hi_char *argv[])
{
hi_wifi_assoc_request assoc_req = {0};
if ((argc < 3) || (argc > 4)) { /* argc 3/4 */
return HI_ERR_FAILURE;
}
/* get ssid */
if ((argv[0] != HI_NULL) &&(cmd_sta_connect_get_ssid(argv, &assoc_req, HI_NULL, 0) != HI_ERR_SUCCESS)){
return HI_ERR_FAILURE;
}
/* get bssid */
if (argv[1] == HI_NULL) {
memset_s(assoc_req.bssid,sizeof(assoc_req.bssid), 0, sizeof(assoc_req.bssid));
} else if (strlen(argv[1]) ==HI_WIFI_TXT_ADDR_LEN) {
if (cmd_strtoaddr(argv[1],assoc_req.bssid, HI_WIFI_MAC_LEN) != HISI_OK) {
return HI_ERR_FAILURE;
}
} else {
return HI_ERR_FAILURE;
}
/* get auth_type */
if ((integer_check(argv[2]) !=HI_ERR_SUCCESS) || (atoi(argv[2]) < HI_WIFI_SECURITY_OPEN) || /* argc 2 */
(atoi(argv[2]) == HI_WIFI_SECURITY_WPA)|| (atoi(argv[2]) == HI_WIFI_SECURITY_WPA2) || /* argc 2 */
(atoi(argv[2]) ==HI_WIFI_SECURITY_WPAPSK) || (atoi(argv[2]) >= HI_WIFI_SECURITY_UNKNOWN) ||/* argc 2 */
((atoi(argv[2]) ==HI_WIFI_SECURITY_OPEN) && (argc != 3)) || /* argc 2/3/4 */
((atoi(argv[2]) !=HI_WIFI_SECURITY_OPEN) && (argc != 4))) { /* argc 2/3/4 */
return HI_ERR_FAILURE;
}
assoc_req.auth = (hi_wifi_auth_mode)atoi(argv[2]);/* 2 */
assoc_req.pairwise =HI_WIFI_PARIWISE_UNKNOWN;
/* get key */
if (argc == 4) { /* argc 4 */
const hi_char *buf = argv[3]; /* argc 3 */
if (buf == HI_NULL) {
return HI_ERR_FAILURE;
}
size_t len = strlen(argv[3]); /* 3:key*/
if ((atoi(argv[2]) ==HI_WIFI_SECURITY_WEP) && (len != 9) && (len != 17) &&/* argc 2, len 9/17 */
(len != 12) && (len !=28)){ /* 12 28: password len */
return HI_ERR_FAILURE;
} else if ((atoi(argv[2]) !=HI_WIFI_SECURITY_WEP) && ((len > HI_WIFI_AP_KEY_LEN_MAX + 2) || /* argc 2 */
(len < HI_WIFI_AP_KEY_LEN_MIN +2))) { /* len plus 2 */
return HI_ERR_FAILURE;
}
if ((*buf != '"') || (*(buf +strlen(argv[3]) - 1) != '"') || /* argc 3 */
(memcpy_s(assoc_req.key,HI_WIFI_MAX_KEY_LEN + 1, buf + 1, strlen(argv[3]) - 2) != EOK)) { /* 3 2 */
return HI_ERR_FAILURE;
}
}
if (hi_wifi_sta_connect(&assoc_req) !=HISI_OK) {
return HI_ERR_FAILURE;
}
hi_at_printf("OKrn");
return HI_ERR_SUCCESS;
}
该函数主要用于解析AT+CONN指令,核心是hi_wifi_sta_connect()函数。
3.获取IP地址, AT+DHCP
hi_u32 at_setup_dhcp(hi_s32argc, const hi_char **argv)
{
hi_s32 ret = 0;
if (at_param_null_check(argc, argv) ==HI_ERR_FAILURE) {
return HI_ERR_FAILURE;
}
if (argc != 2) { /* at+dhcp cmd length equl2 */
return HI_ERR_FAILURE;
}
#ifndef CONFIG_FACTORY_TEST_MODE
struct netif *netif_p = netifapi_netif_find(argv[0]);
if (netif_p == NULL) {
return HI_ERR_FAILURE;
}
if (strcmp(argv[1], "1") == 0) {
ret = netifapi_dhcp_start(netif_p);
} else if (strcmp(argv[1], "0")== 0) {
ret = netifapi_dhcp_stop(netif_p);
} else if (strcmp(argv[1], "2")== 0) {
ret = netifapi_netif_common(netif_p,dhcp_clients_info_show, NULL);
} else {
return HI_ERR_FAILURE;
}
#endif
if (ret == LOS_OK) {
hi_at_printf("OKrn");
}
return ret;
}
其中netifapi_netif_find()函数通过DHCP向AP请求wlan0的IP地址,然后就调用netifapi_dhcp_start()函数获取IP。
使用AT比较麻烦,接下来笔者将通过程序来联网。
编程自动联网,其本质和使用AT指令一样,最终都是调用了相同的API,只是通过加载应用的方式去实现了,联网流程和使用AP一样的,编写应用的方式参看上一章内容,本文将在wifi-iot目录下新建应用,这样可以简化步骤。
1.新建目录
在./applications/sample/wifi-iot/app路径下新建一个目录,用于存放WiFi应用的源码文件。
在app下新增业务wifi_connect,其中wifi_app.c为应用代码,BUILD.gn为编译脚本,目录结构如下:
2.编写应用代码
新建./applications/sample/wifi-iot/app/wifi_app下的wifi_app.c文件,在wifi_app.c中新建映月宫入口函数wifi_task,并实现业务逻辑。并在代码最下方,使用OpenHarmony启动模块接口SYS_RUN()启动业务。
从上一节内容得到,连接WiFi核心就三个:启动STA模式,连接WiFi,设置IP。
因此,最终的wifi_app.c的函数代码如下:
/**
******************************************************************************
*@file wifi_app.c
*@author BruceOu
*@version V1.0
* @date 2022-06-18
*@blog https://blog.bruceou.cn/
******************************************************************************
*/
#include
#include
#include "ohos_init.h"
#include "cmsis_os2.h"
#include
#include"hi_wifi_api.h"
#include"lwip/ip_addr.h"
#include "lwip/netifapi.h"
#define SSID "media"
#define PASSWORD"12345678"
static struct netif*g_lwip_netif = NULL;
/**
* @briefSet netif's ip, gatewayand netmask
*@parampst_lwip_netif
* @retval None
*/
void hi_sta_set_addr(structnetif *pst_lwip_netif)
{
ip4_addr_t st_gw;
ip4_addr_t st_ipaddr;
ip4_addr_t st_netmask;
if (pst_lwip_netif == NULL)
{
printf("hisi_reset_addr::Nullparam of netdevrn");
return;
}
IP4_ADDR(&st_gw, 192, 168, 101, 1);
IP4_ADDR(&st_ipaddr, 192, 168, 101,100);
IP4_ADDR(&st_netmask, 255, 255, 255,0);
netifapi_netif_set_addr(pst_lwip_netif,&st_ipaddr, &st_netmask, &st_gw);
}
/**
* @briefWifi connect
* @paramNone
* @retval None
*/
int hi_wifi_start_connect(void)
{
int ret;
errno_t rc;
hi_wifi_assoc_request assoc_req = {0};
// Copy SSID to assoc_req
rc = memcpy_s(assoc_req.ssid,HI_WIFI_MAX_SSID_LEN + 1, SSID, strlen(PASSWORD));
if (rc != EOK)
{
printf("[Wifi Connnect]hi_wifi_sta_connect fail");
printf("%s %d rn",__FILE__, __LINE__);
return -1;
}
//Set encryption method
assoc_req.auth = HI_WIFI_SECURITY_WPA2PSK;
// Wifi password
memcpy(assoc_req.key, PASSWORD,strlen(PASSWORD));
ret = hi_wifi_sta_connect(&assoc_req);
if (ret != HISI_OK)
{
printf("[WifiConnnect] hi_wifi_sta_connect fail");
printf("%s %d rn",__FILE__, __LINE__);
return -1;
}
return0;
}
/**
* @briefwifi task
* @paramNone
* @retval None
*/
void wifi_task(void)
{
int ret;
char ifname[WIFI_IFNAME_MAX_SIZE + 1] ={0};
int len = sizeof(ifname);
unsigned intnum = WIFI_SCAN_AP_LIMIT;
//Step 1: Start STA mode, AT+STARTSTA
ret = hi_wifi_sta_start(ifname, &len);
if (ret != HISI_OK)
{
printf("[Wifi Connnect]hi_wifi_sta_start fail");
printf("%s %d rn",__FILE__, __LINE__);
return;
}
// Step 2: Connect to the specified AP:,AT+CONN="SSID", ,2,"PASSWORD"
ret = hi_wifi_start_connect();
if (ret != 0)
{
printf("[Wifi Connnect]hi_wifi_start_connect fail");
printf("%s %d rn",__FILE__, __LINE__);
return ;
}
// Step 3: DHCP requests the IP address ofwlan0 from the AP, AT+DHCP=wlan0,1
g_lwip_netif = netifapi_netif_find(ifname);
if(NULL == g_lwip_netif)
{
printf("[Wifi Connnect]netifapi_netif_find fail");
printf("%s %d rn",__FILE__, __LINE__);
return;
}
//DHCP automatically assigns IP
if(ret !=netifapi_dhcp_start(g_lwip_netif))
{
printf("[Wifi Connnect]netifapi_dhcp_start fail");
return;
}
printf("[Wifi Connnect] Connect towifi successfullyn");
}
SYS_RUN(wifi_task);
3.新建编译组织文件
新建./applications/sample/wifi-iot/app/wifi_connect/BUILD.gn文件,内容如下所示:
static_library(wifiapp") {
sources = [
"wifi_app.c"
include_dirs = [
"//utils/native/lite/include"
}
static_library中指定业务模块的编译结果,为静态库文件libwifiapp.a,开发者根据实际情况完成填写。
sources中指定静态库.a所依赖的.c文件及其路径,若路径中包含"//"则表示绝对路径(此处为代码根路径),若不包含"//"则表示相对路径。
include_dirs中指定source所需要依赖的.h文件路径。
最后,编译下载固件,我们就可以自动连接Wifi了。
接下来ping下网络:
说明自动连接网络成功。
官网手册:
https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-ide-lite-steps-hi3861-netconfig.md
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
wi-fi
+关注
关注
14文章
2144浏览量
124524 -
HarmonyOS
+关注
关注
79文章
1977浏览量
30216 -
HiSpark
+关注
关注
1文章
156浏览量
6934
发布评论请先 登录
相关推荐
华为海思正式进入Wi-Fi FEM赛道?
产品和技术交流。
2017年是国产Wi-Fi FEM元年,锐迪科(RDA)是中国大陆第一家推出和量产Wi-Fi5 FEM的公司,也是第一家导入H公司的Wi-Fi FEM厂商。
也是在这一年,我频繁地跟H
发表于 12-11 17:42
摩尔斯微电子发布Wi-Fi HaLow评估套件,加速物联网开发
近日,全球领先的Wi-Fi HaLow解决方案提供商摩尔斯微电子正式推出一款开创性的评估套件——MM6108-EKH05。这款完全整合的开发平台,旨在推动各行业物联网解决方案的快速发展
IR615如何配置Wi-Fi STA模式联网?
1)选择网络》WLAN模式切换》选择模式为sta
2)重启系统(系统>>重启系统),重启后选择网络》wan(sta)端口
3)配置wan(
发表于 07-25 07:27
IR900 Wi-Fi联网的配置过程
例如上图,IR900 通过Wi-Fi接口连接公司办公无线网络 inhand-office (SSID为无线网络的名称) 首先将Wi-Fi接口与WLAN接口解绑
登陆IR900后,进入
发表于 07-25 06:09
使用Arduino 1.6.8在AT STA模式下运行Wi-Fi,“WiFi强制休眠开始”功能后未调用延迟功能是怎么回事?
我使用 Arduino 1.6.8 在 AT STA 模式下运行 Wi-Fi。ESP-8266 固件基于 SDK1.5
我想将 wifi AP 置于调制解调器睡眠
发表于 07-22 06:48
全方位性能对比 | 远距离Wi-Fi VS 传统Wi-Fi
Wi-Fi通信技术当前已成为无线局域网(WLAN)最常见、应用非常广泛的通信技术。从Wi-Fi4、Wi-Fi5和Wi-Fi6,传统的WiFi
WI-FI基础知识及飞易通SOC模块
“WiFi”或“Wifi”,但是这些写法并没有被Wi-Fi联盟认可。 一、通常说的WI-FI几: 第一代:以IEEE 802.11为准,工作频段为2.4GHz, 最高速率半双工2Mbi
Wi-Fi HaLow和传统Wi-Fi的区别
Wi-Fi HaLow和传统Wi-Fi的区别 Wi-Fi是一种无线网络技术,可以连接到互联网或局域网,为用户提供无线上网的便利。随着科技的发展和互
全志R128基础组件开发指南-WiFi Manager②
_STATION);wifi_sta_connect(&cn_para);wifi_sta_disconnect();1.以station模式打开Wi-Fi Manager2.
发表于 01-25 14:28
全志R128基础组件开发指南-WiFi Manager
WIFI_STA_DISCONNECTED:station 模式处于已取消连接状态
定义Wi-Fi Manager station 模式在连接过程中的事件结构体描述:该结构体主要用于
发表于 01-24 10:11
BT Wi-Fi模式是否可以通过ModustoolBox对套件进行编程来实现?
想配置用于分析 CYW43439 的 CY8CPROTO-062S2-43439 原型开发套件。
浏览文档我无法弄清楚如何在不同的 Wi-Fi 和蓝牙模式(电源模式、连接
发表于 01-22 06:19
评论