

OpenHarmony 设备开发一WIFI连接
source link: https://www.51cto.com/article/718148.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

OpenHarmony 设备开发一WIFI连接

wifi在我们的日常开发中必不可少,想要开发鸿蒙小车联网操作,想要使开发板不再局限于终端串口操作,更离不开wifi,本篇文章将详细介绍hi3861的wifi开发步骤及介绍。
本文主要介绍如何令hi3861开机自动连接wifi。
第一步先在applications\sample\wifi-iot\下路径创建WIFI_demo业务代码文件夹,在文件夹内创建业务代码和BUILD.gn编译脚本。

业务代码中的头文件引用
hi_wifi_api.h和netifapi.h保存了一些wifi的API接口,ip_addr.h则是存放了wifi需使用到的一些宏定义。
ohos_init.h和cmsis_os2.h是应用初始化和线程创建必不可少的头文件,当我们使用到线程和SYS_RUN()都要包括这两个头文件。
#include <unistd.h>
#include "hi_wifi_api.h"
#include "lwip/ip_addr.h"
#include "lwip/netifapi.h"
#include "ohos_init.h"
#include "cmsis_os2.h"
编译脚本代码
编译脚本将目标名为Xu_WIFI.c打包成名为Xu_WIFI_demo的静态库,随后在app路径下的BUILD.gn调用该库,调用格式为"业务代码文件夹名:静态库名"。
include_dirs为头文件的存放地址,我们在使用ubuntu开发时,遇到不知道存放路径的头文件或者宏定义时,可以使用指令grep 头文件名 -* nR find . -name 头文件名进行搜索。
业务代码文件夹内的BUILD.gn代码:
static_library("Xu_WIFI_demo") {
sources = [
"Xu_WIFI.c"
]
include_dirs = [
"//utils/native/lite/include",
"//kernel/liteos_m/components/cmsis/2.0",
"//base/iot_hardware/peripheral/interfaces/kits",
"//ohos_bundles/@ohos/device_soc_hisilicon/hi3861v100/sdk_liteos/include",
"//ohos_bundles/@ohos/device_soc_hisilicon/hi3861v100/sdk_liteos/third_party/lwip_sack/include",
]
}
app路径下的BUILD.gn代码:


在业务代码中主要由主函数、连接函数、线程函数三大函数构成,在主函数中编写WIFI初始化、WIFI扫描等操作,连接函数中可以确认需要连接的WIFI的账号密钥以及加密方式。
主函数代码:
WIFI开启的流程:
- WIFI初始化。
- 使能注册回调函数。
- 获取网络接口进行IP的操作。
- 扫描WIFI。
- 获取WIFI扫描结果。
- 连接WiFi。
#define APP_INIT_VAP_NUM 2
#define APP_INIT_USR_NUM 2
static struct netif *g_lwip_netif = NULL;
int hi_wifi_start_sta(void)
{
int ret;
char ifname[WIFI_IFNAME_MAX_SIZE + 1] = {0};
int len = sizeof(ifname);
const unsigned char wifi_vap_res_num = APP_INIT_VAP_NUM;
const unsigned char wifi_user_res_num = APP_INIT_USR_NUM;
unsigned int num = WIFI_SCAN_AP_LIMIT;
// ret = hi_wifi_init(wifi_vap_res_num, wifi_user_res_num); // WiFi初始化
// if (ret != HISI_OK)
// {
// return -1;
// }
ret = hi_wifi_sta_start(ifname, &len); // sta初始化
if (ret != HISI_OK)
{
return -1;
}
/* 注册回调函数接口*/
ret = hi_wifi_register_event_callback(wifi_wpa_event_cb);
if (ret != HISI_OK)
{
printf("register wifi event callback failed\n");
}
/* 获取网络接口进行IP的操作 */
g_lwip_netif = netifapi_netif_find(ifname);
if (g_lwip_netif == NULL)
{
printf("%s: get netif failed\n", __FUNCTION__);
return -1;
}
/* 扫描WIFI */
ret = hi_wifi_sta_scan();
if (ret != HISI_OK)
{
return -1;
}
sleep(5); /* sleep 5s, waiting for scan result. */
//创建pst_results存放WiFi扫描结果
hi_wifi_ap_info *pst_results = malloc(sizeof(hi_wifi_ap_info) * WIFI_SCAN_AP_LIMIT);
if (pst_results == NULL)
{
return -1;
}
//获取station扫描结果
ret = hi_wifi_sta_scan_results(pst_results, &num);
if (ret != HISI_OK)
{
free(pst_results);
return -1;
}
//打印WIFI扫描结果
for (unsigned int loop = 0; (loop < num) && (loop < WIFI_SCAN_AP_LIMIT); loop++)
{
printf("SSID: %s\n", pst_results[loop].ssid);
}
free(pst_results);
/* 进行WIFI连接 */
ret = hi_wifi_start_connect();
if (ret != 0)
{
return -1;
}
return 0;
}
注册回调函数:
/* 清理IP,网关和子网掩码 */
void hi_sta_reset_addr(struct netif *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::Null param of netdev\r\n");
return;
}
IP4_ADDR(&st_gw, 0, 0, 0, 0);
IP4_ADDR(&st_ipaddr, 0, 0, 0, 0);
IP4_ADDR(&st_netmask, 0, 0, 0, 0);
netifapi_netif_set_addr(pst_lwip_netif, &st_ipaddr, &st_netmask, &st_gw);
}
//注册回调函数
void wifi_wpa_event_cb(const hi_wifi_event *hisi_event)
{
if (hisi_event == NULL)
return;
switch (hisi_event->event)
{
case HI_WIFI_EVT_SCAN_DONE: //STA扫描完成
printf("WiFi: Scan results available\n");
break;
case HI_WIFI_EVT_CONNECTED:
printf("WiFi: Connected\n"); //wifi已连接
netifapi_dhcp_start(g_lwip_netif); //接口功能启动网络接口的DHCP协商
break;
case HI_WIFI_EVT_DISCONNECTED:
printf("WiFi: Disconnected\n");
netifapi_dhcp_stop(g_lwip_netif); //关闭wifi
hi_sta_reset_addr(g_lwip_netif); //清理IP,网关和子网掩码
break;
case HI_WIFI_EVT_WPS_TIMEOUT:
printf("WiFi: wps is timeout\n"); //WPS事件超时
break;
default:
break;
}
}
连接函数:
连接的步骤:
- 创建hi_wifi_assoc_request结构体变量。
- hi_wifi_assoc_request结构体成员初始化:ssid,加密方式,密钥。
- 使用hi_wifi_sta_connect连接WiFi,其中的实参为hi_wifi_assoc_request变量的地址。
int hi_wifi_start_connect(void)
{
int ret;
errno_t rc;
hi_wifi_assoc_request assoc_req = {0};
/* copy SSID to assoc_req */
//第三参数为ssid,第四参数为ssid数据长度
rc = memcpy_s(assoc_req.ssid, HI_WIFI_MAX_SSID_LEN + 1, "M20P", 4);
if (rc != EOK)
{
return -1;
}
//开放WIFI
// assoc_req.auth = HI_WIFI_SECURITY_OPEN;
// WIFI加密方式
assoc_req.auth = HI_WIFI_SECURITY_WPA2PSK;
/* WIFI密钥 */
memcpy(assoc_req.key, "12345678", 8);
// WIFI连接
ret = hi_wifi_sta_connect(&assoc_req);
if (ret != HISI_OK)
{
return -1;
}
return 0;
}
线程任务创建:
我们需要创建线程时,首先需要创建osThreadAttr_t结构体变量,下一步便是初始化该结构体变量,在此步初始化中的关键是线程名称、任务栈大小和线程优先级,再下一步便使用osThreadNew()将该结构体变量注册,最后SYS_RUN()运行该线程。
//线程代码段
void *hi_wifi_text(const char *arg)
{
printf("******************************\n");
hi_wifi_start_sta();
printf("******************************\n");
}
//创建线程
void wifi_demo(void)
{
osThreadAttr_t attr;
attr.name = "WIFITask"; //线程名称
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = 4096; //任务栈大小
attr.priority = 25; //线程优先级
//第一参数为线程代码段函数的名称
if (osThreadNew((osThreadFunc_t)hi_wifi_text, NULL, &attr) == NULL)
{
printf("[LedExample] Falied to create LedTask!\n");
}
}
//运行wifi_demo线程
SYS_RUN(wifi_demo);


</article
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK