当前位置: 首页 > news >正文

LWIP热插拔功能实现

0 工具准备

1.lwip 1.4.1
2.RTOS(本文使用rt-thread)

1 使能连接变化回调功能

打开lwipopts.h,将宏定义LWIP_NETIF_LINK_CALLBACK的值设为1,如下:

#define LWIP_NETIF_LINK_CALLBACK        1

这个宏定义被使能后会将void ethernetif_update_config(struct netif *netif)函数加入工程中进行编译。这个函数的功能就是检查当前连接情况,进行不同的处理。
该函数如下:

void ethernetif_update_config(struct netif *netif)
{__IO uint32_t tickstart = 0;uint32_t regvalue = 0;if (netif_is_link_up(netif)){/* Restart the auto-negotiation */if (heth.Init.AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE){/* Enable Auto-Negotiation */HAL_ETH_WritePHYRegister(&heth, PHY_BCR, PHY_AUTONEGOTIATION);/* Get tick */tickstart = HAL_GetTick();/* Wait until the auto-negotiation will be completed */do{HAL_ETH_ReadPHYRegister(&heth, PHY_BSR, &regvalue);/* Check for the Timeout ( 1s ) */if ((HAL_GetTick() - tickstart) > 1000){/* In case of timeout */goto error;}} while (((regvalue & PHY_AUTONEGO_COMPLETE) != PHY_AUTONEGO_COMPLETE));/* Read the result of the auto-negotiation */HAL_ETH_ReadPHYRegister(&heth, PHY_SR, &regvalue);if ((regvalue & PHY_DUPLEX_STATUS) != (uint32_t)RESET){heth.Init.DuplexMode = ETH_MODE_FULLDUPLEX;}else{heth.Init.DuplexMode = ETH_MODE_HALFDUPLEX;}if (regvalue & PHY_SPEED_STATUS){/* Set Ethernet speed to 10M following the auto-negotiation */heth.Init.Speed = ETH_SPEED_10M;}else{/* Set Ethernet speed to 100M following the auto-negotiation */heth.Init.Speed = ETH_SPEED_100M;}}else /* AutoNegotiation Disable */{error:/* Check parameters */assert_param(IS_ETH_SPEED(heth.Init.Speed));assert_param(IS_ETH_DUPLEX_MODE(heth.Init.DuplexMode));/* Set MAC Speed and Duplex Mode to PHY */HAL_ETH_WritePHYRegister(&heth, PHY_BCR,((uint16_t)(heth.Init.DuplexMode >> 3) |(uint16_t)(heth.Init.Speed >> 1)));}/* ETHERNET MAC Re-Configuration */HAL_ETH_ConfigMAC(&heth, (ETH_MACInitTypeDef *)NULL);/* Restart MAC interface */HAL_ETH_Start(&heth);}else{/* Stop MAC interface */HAL_ETH_Stop(&heth);}ethernetif_notify_conn_changed(netif);
}

2 完善连接状态变化回调函数

在ethernetif_update_config函数的最后有一个名为ethernetif_notify_conn_changed的函数需要用户自定义功能,由于我们这里使用的是固定IP,因此自定义的状态变化回调函数如下:

void ethernetif_notify_conn_changed(struct netif *netif)
{if(netif_is_link_up(netif)){printf("\r\nLan link up!\r\n");netif_set_up(netif);}else{printf("\r\nLan link down!\r\n");netif_set_down(netif);}
}

如果需要启用了DHCP功能,可以在发现网线插上后等待路由器分配IP。

3 绑定回调函数

前面我们已经编辑好了自定义的回调函数,接下来需要绑定回调函数,在我们的网线连接状态改变时执行回调函数。绑定回调函数只需要添加netif_set_link_callback(&gnetif, ethernetif_update_config)语句到LWIP初始化函数内即可。如下:

    netif_set_default(&gnetif);if (netif_is_link_up(&gnetif)){/* When the netif is fully configured this function must be called */netif_set_up(&gnetif);}else{/* When the netif link is down this function must be called */netif_set_down(&gnetif);}netif_set_link_callback(&gnetif, ethernetif_update_config);

4 轮询网口连接状态

前面我们已经完成了回调函数编写,同时绑定了回调函数。由于lwip 1.4.1原生没有轮询网口连接状态,因此这部分需要我们来编写。这里我们使用RTOS,将轮询网口连接状态的函数放到软件定时器内执行:

void lan_state_check(void)
{uint32_t regvalue = 0;HAL_ETH_ReadPHYRegister(&heth, PHY_BSR, &regvalue);if ((regvalue & PHY_LINKED_STATUS) == PHY_LINKED_STATUS){netif_set_flags(&gnetif, NETIF_FLAG_LINK_UP);if (netif_is_up(&gnetif) != 1){gnetif.link_callback(&gnetif);}}else{netif_clear_flags(&gnetif, NETIF_FLAG_LINK_UP);if (netif_is_up(&gnetif) != 0){gnetif.link_callback(&gnetif);}}
}

这个函数主要功能就是读取PHY的BSR寄存器查看连接状态,如果当前连接状态的物理状态和LWIP软件连接状态不一致则执行回调函数。
其中物理连接状态由软件定时器周期性设置,设置的bit为NETIF_FLAG_LINK_UP,软件连接状态由LWIP内核设置,设置的bit为NETIF_FLAG_UP。

5 优化启动速度

上电阶段有时网卡还未建立有效连接,ETH初始化函数会一直阻塞等待连接建立直至超时,默认的超时时间为5000ms,也就是说如果上电后网卡没有建立有效连接会一直阻塞等待5000ms,体验感非常差。为了解决这一问题,将以下2个宏定义修改成2000即可:

#define ETH_TIMEOUT_LINKED_STATE          2000U
#define ETH_TIMEOUT_AUTONEGO_COMPLETED    2000U

6 插拔测试

(1)上电后再插上网线,随后ping路由器
在这里插入图片描述
可以看到打印了“Lan link up!”,程序识别到了这一变化同时执行了回调函数,ping路由器正常。
(2)将网线拔下
在这里插入图片描述
可以看到打印了“Lan link down!”,程序识别到了这一变化同时执行了回调函数。
(3)反复执行(1)(2)查看是否正常。
在这里插入图片描述
反复执行也能保证稳定,测试结果正常。

7 总结

(1)LWIP实现热插拔的关键在于识别物理网口连接状态和软件连接状态是否一致,当二者不一致时则将软件连接状态设置为和物理网口连接状态一致。
(2)需要根据实际情况自定义回调函数。
(3)超时时间不要设置太短,实测2000ms有效。

相关文章:

LWIP热插拔功能实现

0 工具准备 1.lwip 1.4.1 2.RTOS(本文使用rt-thread)1 使能连接变化回调功能 打开lwipopts.h,将宏定义LWIP_NETIF_LINK_CALLBACK的值设为1,如下: #define LWIP_NETIF_LINK_CALLBACK 1这个宏定义被使能后会将…...

android下的app性能测试应主要针对那些方面,如何开展?

如何开展安卓手机下的App性能测试,对于优秀的测试人员而言,除了要懂得性能测试的步骤流程外,还应该懂的性能测试的一些其他知识,比如性能测试指标、各指标的意义,常用的性能测试工具、如何查看结果分析等等知识。所以本…...

【深度学习】注意力机制(二)

本文介绍一些注意力机制的实现,包括EA/MHSA/SK/DA/EPSA。 【深度学习】注意力机制(一) 【深度学习】注意力机制(三) 目录 一、EA(External Attention) 二、Multi Head Self Attention 三、…...

学习黑马vue

项目分析 项目下载地址:vue-admin-template-master: 学习黑马vue 项目下载后没有环境可参考我的篇文章,算是比较详细:vue安装与配置-CSDN博客 安装这两个插件可格式化代码,vscode这个软件是免费的,官网:…...

gdb本地调试版本移植至ARM-Linux系统

移植ncurses库 本文使用的ncurses版本为ncurses-5.9.tar.gz 下载地址:https://ftp.gnu.org/gnu/ncurses/ncurses-5.9.tar.gz 1. 将ncurses压缩包拷贝至Linux主机或使用wget命令下载并解压 tar-zxvf ncurses-5.9.tar.gz 2. 解压后进入到ncurses-5.9目录…...

《Linux C编程实战》笔记:实现自己的ls命令

关键函数的功能及说明 1.void display_attribute(struct stat buf,char *name) 函数功能:打印文件名为name的文件信息,如 含义分别为:文件的类型和访问权限,文件的链接数,文件的所有者,文件所有者所属的组…...

Python个人代码随笔(观看无益,请跳过)

异常抛错:一般来说,在程序中,遇到异常时,会从这一层逐层往外抛错,一直抛到最外层,由最外层把错误显示在用户终端。 try:raise ValueError("A value error...") except ValueError:print("V…...

Unity中实现ShaderToy卡通火(总结篇)

文章目录 前言一、把卡通火修改为后处理效果1、在Shader属性面板定义属性接收帧缓存纹理2、在片元着色器对其纹理采样后,与卡通火相加输出请添加图片描述 二、我们自定义卡通火1、修改 _CUTOFF 使卡通火显示在屏幕两侧2、使火附近屏幕偏红色 前言 在之前的文章中&a…...

等保2.0的变化

1法律地位得到确认 《中华人民共和国网络安全法》第21条规定“国家实行网络安全等级保护制度”,要求“网络运营者应当按照网络安全等级保护制度要求,履行安全保护义务”;第31条规定“对于国家关键信息基础设施,在网络安全等级保护…...

漏洞复现-网神SecGate3600防火墙敏感信息泄露漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复,敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…...

ArkTS入门

代码结构分析 struct Index{ } 「自定义组件:可复用的UI单元」 xxx 「装饰器:用来装饰类结构、方法、变量」 Entry 标记当前组件是入口组件(该组件可被独立访问,通俗来讲:它自己就是一个页面)Component 用…...

JS中for循环之退出循环

我为大家介绍一下退出循环的两种方法 1.continue 退出本次循环&#xff0c;一般用于排除或者跳过某一个选项的时候&#xff0c;可以使用continue for(let i 0;i<5;i){if(i 3){continue}// 跳过了3console.log(i) //0 1 2 4}2.break 退出整个for循环&#xff0c;一般用于…...

《Global illumination with radiance regression functions》

总结一下最近看的这篇结合神经网络的全局光照论文。 论文的主要思想是利用了神经网络的非线性特性去拟合全局光照中的间接光照部分&#xff0c;采用了基础的2层MLP去训练&#xff0c;最终能实现一些点光源、glossy材质的光照渲染。为了更好的理解、其输入输出表示如下。 首先…...

华南理工C++试卷

诚信应考 , 考试作弊将带来严重后果&#xff01; 《C程序设计试卷》 注意事项&#xff1a;1. 考前请将密封线内填写清楚&#xff1b; 2. 所有答案请答在试卷的答案栏上&#xff1b; 3&#xff0e;考试形式&#xff1a;闭卷 4. 本试卷共 五 大题&#xff0c;满分100分&#xff…...

0001.WIN7(64位)安装ADS1.2出现L6218错误

用了十多年的笔记本电脑系统出现问题&#xff0c;硬件升级重装以后安装ADS1.2。在编译代码的时候出现L6218错误。如下&#xff1a; 图片是从网上找的&#xff0c;我编译出错的界面没有保留下来。 首先&#xff0c;代码本身没有任何问题 &#xff0c;代码在win7(32位)下编译没有…...

HBuilderX 配置 夜神模拟器 详细图文教程

在电脑端查看App的效果&#xff0c;不用真机调试&#xff0c;下载一个模拟器就可以了 --- Nox Player&#xff0c;夜神模拟器&#xff0c;是一款 Android 模拟器。他的使用非常安全&#xff0c;最重要的是完全免费。 一. 安装模拟器 官网地址&#xff1a; (yeshen.com) 二.配…...

10、神秘的“位移主题”

神秘的“位移主题” 1、什么是位移主题2、位移主题的消息格式3、位移主题是怎么被创建的4、什么地方会用到位移主题5、位移主题的删除机制 本章主题是&#xff1a;Kafka 中的内部主题&#xff08;Internal Topic&#xff09;__consumer_offsets。 __consumer_offsets 在 Kafka …...

【Linux】dump命令使用

dump命令 dump命令用于备份文件系统。使用dump命令可以检查ext2/3/4文件系统上的文件&#xff0c;并确定哪些文件需要备份。这些文件复制到指定的磁盘、磁带或其他存储介质保管。 语法 dump [选项] [目录|文件系统] bash: dump: 未找到命令... 安装dump yum -y install …...

使用 TensorFlow 创建生产级机器学习模型(基于数据流编程的符号数学系统)——学习笔记

资源出处&#xff1a;初学者的 TensorFlow 2.0 教程 | TensorFlow Core (google.cn) 前言 对于新框架的学习&#xff0c;阅读官方文档是一种非常有效的方法。官方文档通常提供了关于框架的详细信息、使用方法和示例代码&#xff0c;可以帮助你快速了解和掌握框架的使用。 如…...

vue实现悬浮窗拖动的自定义指令

首先在自己的项目根目录下建一个 src --> config --> drag.js 然后在main.js中全局引入 //鼠标拖动 import drag from /config/drag; Vue.use(drag); drag.js文件相关代码 import Vue from vue; //使用Vue.directive()定义一个全局指令 //1.参数一&#xff1a;指令的…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中&#xff0c;网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时&#xff0c;开发者迫切需要一套高效、可靠且跨平台的调试方案。过去&#xff0c;我们或多或少使用过 Chrome DevTools、Remote Debug…...

API网关Kong的鉴权与限流:高并发场景下的核心实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中&#xff0c;API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关&#xff0c;Kong凭借其插件化架构…...

React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构

React 实战项目&#xff1a;微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇&#xff01;在前 29 篇文章中&#xff0c;我们从 React 的基础概念逐步深入到高级技巧&#xff0c;涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...