物联网设备WIFI模块实现

news2024/9/21 14:12:08

问题

如何在设备上进行 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_H

int 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 <stdio.h>
#include <string.h>
#include <unistd.h>

#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 <stdio.h>
#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 模块后,接下来应该干啥? 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/61723.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java—异常体系

文章目录异常和错误java异常的分类&#xff1a;非运行时异常运行时异常受检异常&#xff08;非运行时异常&#xff09;如何处理&#xff1f;1、try catch finally为什么要用try catch finally2、throwsThrow和Throws的区别JVM是如何处理异常的try-catch-finally中哪个部分可以省…

项目管理逻辑:项目经理如何掌控项目生命周期, 才能避免身心俱疲?

目录 1.项目生命周期 2.预测型项目周期 3.迭代型项目周期 3.1.初始阶段 3.2.精化阶段 3.3.构建阶段 3.4.交付阶段 4.增量型生命周期 5.敏捷开发 5.根据具体项目使用合理的开发方式 1.项目生命周期 2.预测型项目周期 预测型项目周期就是软件开发领域的瀑布流模型&…

【Python自然语言处理】概率上下文无关文法(PCFG)及神经网络句法分析讲解(图文解释 超详细)

觉得有帮助或有疑问麻烦点赞关注收藏后评论区私信留言~~~ 一、句法分析 句法分析&#xff08;syntactic parsing或者parsing&#xff09;是识别句子包含的句法成分要素以及成分之间的内在关系&#xff0c;一般以句法树来表示句法分析的结果。实现该过程的应用称作句法分析器&a…

三维模型的简化算法研究(任务书+lunwen+外文翻译+源码+查重报告)

目 录 第1章 绪论 1 1.1 研究背景 1 1.2 内存网格简化算法 1 1.2.1 顶点聚类 1 1.2.2 区域合并 2 1.2.3 迭代式消除 4 1.2.4 随机重采样 5 1.3 三维模型简化算法 6 1.3.1 分片简化 6 1.3.2 使用外部数据结构 7 1.3.3 网格批处理 9 1.3.4 流式简化 10 1.3.5 小结 11 1.4 自适应等…

【前沿技术RPA】 一文了解UiPath Orchestrator的触发器和监听器

&#x1f40b;作者简介&#xff1a;博主是一位.Net开发者&#xff0c;同时也是RPA和低代码平台的践行者。 &#x1f42c;个人主页&#xff1a;会敲键盘的肘子 &#x1f430;系列专栏&#xff1a;UiPath &#x1f980;专栏简介&#xff1a;UiPath在传统的RPA&#xff08;Robotic…

公众号接口免费调用

公众号接口免费调用 本平台优点&#xff1a; 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a; 题库&#xff1a;题库后台&#xff08;点击跳转&#xff09;…

Express:CORS 跨域资源共享

CORS 跨域资源共享 Staticfile CDN 1. 接口的跨域问题 刚才编写的 GET 和 POST接口&#xff0c;存在一个很严重的问题&#xff1a;不支持跨域请求。 解决接口跨域问题的方案主要有两种&#xff1a; 1.CORS&#xff08;主流的解决方案&#xff0c;推荐使用&#xff09; 2.J…

Excel - 选择性粘贴和单元格引用规则

最基本的功能&#xff0c;才是最重要的功能&#xff0c;一定好好好理解。 最常用的复制、粘贴功能&#xff0c;在Excel里赋予了更多的选项&#xff0c;也变得更加强大。Excel里一般可复制的内容都是只单元格区域&#xff0c;其组成包括数据(文本或数值)、格式、公式、有效性验证…

FileZilla Server.xml 如何配置

要从xp.cn说起&#xff0c;因为它自带了一个ftp服务器。我点击配置后&#xff0c;就会直接用记事本打开FileZilla Server.xml让配置。我就很懵。不知道如何下手。 弹出的配置界面如下&#xff1a; 如何配置FileZilla Server.xml 我一开始想到去xp.cn找文档&#xff0c;可惜…

初探基因组组装——生信原理第四次实验报告

初探基因组组装——生信原理第四次实验报告 文章目录初探基因组组装——生信原理第四次实验报告实验目的实验内容实验题目第一题题目用SOAPdenovo 进行基因组组装评估组装质量第二题题目Canu组装Hifiasm组装基于nucmer的基因组比对过滤比对结果转换为可读性强的tab键分隔的文件…

期末论文LaTeX模板

简介 这学期的其中一门课程结束了&#xff0c;考核形式是写一篇中文的课程论文。于是&#xff0c;我使用了Elegant LaTeX 系列的模板。 小编已经把最新版本的三份模板放到公众号&#xff0c;后台回复[课程论文模板]即可获取。也欢迎大家去 GitHub 给贡献者点 star&#xff01;…

【从零开始玩量化13】quantstats:分析你的量化策略

背景 之前总结了一些获取量化数据的途径&#xff0c;数据是一个量化策略的“原材料”&#xff0c;接下来要考虑的问题就是如何使用这些数据。 本文&#xff0c;介绍一个量化指标分析工具quantstats&#xff0c;利用它可以很方便的分析你的策略。 Github地址&#xff1a;https…

[附源码]计算机毕业设计校园帮平台管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【5G MAC】随机接入流程中的 Msg3 —— Scheduled UL (PUSCH) Transmission

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

机器学习數據降維之主成分分析(PCA)

文章目录前言数据降维是什么&#xff1f;维度灾难与降维作用主成分分析PCA原理PCA算法小例實戰總結前言 例如&#xff1a;随着人工智能的不断发展&#xff0c;机器学习这门技术也越来越重要&#xff0c;很多人都开启了学习机器学习&#xff0c;本文就介绍了机器学习的基础内容…

cubeIDE开发,结合汉字取模工具,在LCD输出各种字体

一、汉字取模工具 嵌入式LCD屏显示无非就是不间断刷新LCD宽度*LCD高度的像素矩阵&#xff0c;并为每个像素指定特定颜色。对于LCD屏幕显示汉字&#xff0c;无非就是将字体形状转换为字体宽度*字体高度的像素矩阵&#xff0c;及指定每个字体像素的颜色&#xff0c;然后在LCD屏幕…

点击试剂Methyltetrazine-PEG4-NHS ester,甲基四嗪-PEG4-琥珀酰亚胺酯,CAS:1802907-9

An English name&#xff1a;Methyltetrazine-PEG4-NHS ester Chinese name&#xff1a;甲基四嗪-四聚乙二醇-琥珀酰亚胺酯 Item no&#xff1a;X-CL-1328 CAS&#xff1a;1802907-92-1 Formula&#xff1a;C24H31N5O9 MW&#xff1a;533.54 Purity&#xff1a;95% Avai…

基于MCMC的交通量逆建模(Matlab代码实现)

&#x1f352;&#x1f352;&#x1f352;欢迎关注&#x1f308;&#x1f308;&#x1f308; &#x1f4dd;个人主页&#xff1a;我爱Matlab &#x1f44d;点赞➕评论➕收藏 养成习惯&#xff08;一键三连&#xff09;&#x1f33b;&#x1f33b;&#x1f33b; &#x1f34c;希…

《人类简史》笔记四—— 想象构建的秩序

目录 一、盖起金字塔 1、未来的来临 2、 由想象构建的秩序 3、如何维持构建的秩序 二、 记忆过载 三、亚当和夏娃的一天 一、盖起金字塔 1、未来的来临 原始社会&#xff1a; 人口少&#xff1b; 狩猎和采集&#xff1b; 整体活动范围大&#xff08;有几十甚至上百平方…

【怎么理解回流与重绘?以及触发场景】

一、是什么 在HTML中&#xff0c;每个元素都可以理解成一个盒子&#xff0c;在浏览器解析过程中&#xff0c;会涉及到回流与重绘&#xff1a; 回流&#xff1a;布局引擎会根据各种样式计算每个盒子在页面上的大小与位置 重绘&#xff1a;当计算好盒模型的位置、大小及其他属性…