物联网设备WIFI模块实现
创始人
2024-03-18 07:46:08
0

问题

如何在设备上进行 Wifi 编程?

LwIp (Light Weight IP) 简介

LwIp 是轻量化的 TCP/IP,是一个小型开源的 TCP/IP 协议栈

LwIp 的设计目标是用较少的资源实现较完整的 TCP/IP 协议栈

LwIp 能在操作系统中运行,也能在无操作系统的情况下独立运行

LwIp 提供了 Socket API 和 Netconn API

LwIp 的主要特性

支持 ARP,ICMP,IGMP

支持 UDP,TCP,IP (可移植网络通信框架)

支持 DNS,PPP,SNMP

支持 DHCP,可动态分配 IP 地址 (WIFI 支持)

BearPi-Nano 联网能力

BearPi-Nano 基于 Hi3861 芯片构造,而 Hi3861 自身具备 Wifi 能力

AP 模式

  • 工作于 Wifi 热点模式,可被其他设备以 Wifi 方式连接

STA 模式

  • 工作于 Wifi 连接模式,可连接到指定 Wifi 热点

Wifi 模块接口设计

涉及的 OH 系统接口

Wifi 热点连接流程

Wifi 联网关键函数实现

 

 

 

 

Wifi 模块实现

wifi_connect.h

#ifndef WIFI_CONNECT_H
#define WIFI_CONNTCE_Hint Wifi_Init(void);
int Wifi_Connect(const char* ssid, const char* password);
int Wifi_Start(void);
void Wifi_Stop(void);
int Wifi_IsOk(void);
char* Wifi_IpAddr(void);#endif

wifi_connect.c

#include 
#include 
#include #include "wifi_connect.h"
#include "wifi_device.h"
#include "lwip/netif.h"
#include "lwip/netifapi.h"
#include "lwip/ip4_addr.h"
#include "lwip/api_shell.h"
#include "lwip/dhcp.h"#define WIFI_TIMMEOUT  20
#define WLAN_PORT      "wlan0"static WifiEvent g_WifiEventHandler = {0};
static int g_WaitResult = 0;
static struct netif* g_LwipNeif = NULL;void ClearWaitResult(void)
{g_WaitResult = 0;
}void SetWaitResult(int result)
{g_WaitResult = result;
}int GetWaitResult(void)
{return g_WaitResult;
}void ToWait(int timeout)
{while((GetWaitResult() == 0) && timeout--){sleep(1);}
}void OnWifiConnectionChanged(int state, WifiLinkedInfo* info)
{(void)info;g_WaitResult = state;
}void OnWifiScanStateChanged(int state, int size)
{(void)state;(void)size;
}void OnHotspotStateChanged(int state)
{(void)state;
}void OnHotspotStaJoin(StationInfo* info)
{(void)info;
}void OnHotspotStaLeave(StationInfo* info)
{(void)info;
}int Wifi_Init(void)
{g_WifiEventHandler.OnWifiScanStateChanged = OnWifiScanStateChanged;g_WifiEventHandler.OnWifiConnectionChanged = OnWifiConnectionChanged;g_WifiEventHandler.OnHotspotStaJoin = OnHotspotStaJoin;g_WifiEventHandler.OnHotspotStaLeave = OnHotspotStaLeave;g_WifiEventHandler.OnHotspotStateChanged = OnHotspotStateChanged;return RegisterWifiEvent(&g_WifiEventHandler);}int Wifi_Connect(const char* ssid, const char* password)
{int ret = WIFI_SUCCESS;if(!Wifi_IsOk()){ret = (ssid && password) ? EnableWifi() : ERROR_WIFI_UNKNOWN;if(ret == WIFI_SUCCESS){WifiDeviceConfig config = {0};int result = 0;config.securityType = WIFI_SEC_TYPE_PSK;strcpy(config.ssid, ssid);strcpy(config.preSharedKey, password);ret += AddDeviceConfig(&config, &result);ret += ConnectTo(result);if(ret == WIFI_SUCCESS){ClearWaitResult();ToWait(WIFI_TIMMEOUT);ret = (GetWaitResult() != 0) ? WIFI_SUCCESS : ERROR_WIFI_UNKNOWN;}else{ret = ERROR_WIFI_UNKNOWN;}}}return ret;
}int Wifi_Start(void)
{int ret = WIFI_SUCCESS;if(!Wifi_IsOk()){g_LwipNeif = netifapi_netif_find(WLAN_PORT);if(g_LwipNeif != NULL){if(dhcp_start(g_LwipNeif) == ERR_OK){int i = WIFI_TIMMEOUT;while(((ret = dhcp_is_bound(g_LwipNeif)) != ERR_OK) && i--){usleep(200 * 1000);}}if(ret != WIFI_SUCCESS){Wifi_Stop();}}else{ret = ERROR_WIFI_UNKNOWN;}}return ret;
}void Wifi_Stop(void)
{dhcp_stop(g_LwipNeif);g_LwipNeif = NULL;
}int Wifi_IsOk(void)
{return !!g_LwipNeif;
}char* Wifi_IpAddr(void)
{char* ret = NULL;if(Wifi_IsOk()){ip4_addr_t addr = {0};ip4_addr_t mask = {0};ip4_addr_t gw = {0};netif_get_addr(g_LwipNeif, &addr, &mask, &gw);if((addr.addr != 0) && (addr.addr != -1)){ret = ip4addr_ntoa(&addr);}else{Wifi_Stop();}}return ret;
}

main_entry.c

#include 
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "wifi_connect.h"static void* Task_Iniit(const char* arg)
{Wifi_Init();Wifi_Connect("wifi_test", "12345678");Wifi_Start();if(Wifi_IsOk){printf("addr = %s\n", Wifi_IpAddr());}return arg;
}static void Main_Entry(void)
{osThreadAttr_t attr = {0};attr.name = "Task_Iniit";attr.stack_size = 4 * 1024;attr.priority = 20;if(osThreadNew((osThreadFunc_t)Task_Iniit, NULL, &attr) == NULL){printf("failed to create task!\n");}
}SYS_RUN(Main_Entry);

测试结果如下图所示

Hi3861成功连上 Wifi, IP 为192.168.137.48

课后思考

有了 Wifi 模块后,接下来应该干啥? 

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...