【实战经验分享】一劳永逸的解决网线随意热插拔问题
说明:网线热插拔是实际项目中经常会遇到的问题,热插拔又有各种各样的情况要具体处理,这里分享一种实用性方案。
static/image/hrline/4.gif
热插拔的问题种类:
1、上电前,网线还没有插入,上电后插入如何处理。
2、服务器模式使用时,检测到断开网线了,重新插入如何处理。
3、客户端模式时,检测到网线断开了,重新插入如何处理。
4、长时间断开,比如1个小时以上,重新插入后协议栈无法正常运行如何处理。
5、将网线从一个网络环境切换到另一个网络环境。
这几个问题,如果具体问题都配一个具体的解决方案就太繁琐了。而且逻辑关系不容易捋顺。
解决办法:
这里为大家分享一种解决办法,以新版的RL-TCPnet V7.X为例。
1、有个专门的网络插拔通知函数,通过这个函数可以方便的了解网络插拔信息。
2、然后还有个初始化函数netInitialize()和复位初始化函数netUninitialize(),其中这个复位初始化函数尤其好用,在检测到网线被拔掉后,调用此函数会释放所有用户使用的网络资源,并删除以太网接口任务和协议栈内核任务。
3、最后就是用户自己创建的各种应用任务,我们这里在检测到网线拔掉后直接将其删除即可(优先调用网络复位任何后再删),检测到网线插入后重新创建。
具体处理:
网络插拔消息函数,这里直接设置一个全局变量来标识插拔状态。
当然,追求执行效率,也可以采用任务信号量,事件标志等方式,这里没有采用的原因是大家自己移植的时候很容易出现没有创建任务组件就去使用了。
专门开辟一个网络初始化和检测任务来处理插拔问题:
实际测试效果比较满意,这样就不用具体情况具体分析了,直接所有问题全部被处理了。
我也用了这个回调函数,反应很快,用的也是全局变量,很好用!:lol 实测,即使在网络高速通信期间,重新插拔网线,也不会有问题了。 以前用LWIP 就遇到这个问题。 当时是直接复位···· 使用 lwip 有没有什么方法也可以解决这些问题呀 ? hpdell 发表于 2019-10-23 14:25
使用 lwip 有没有什么方法也可以解决这些问题呀 ?
也可以采用类似的方法。直接重新初始化网络,删除之前的网络应用任务。 非常有用。 hpdell 发表于 2019-10-23 14:25
使用 lwip 有没有什么方法也可以解决这些问题呀 ?
lwip请看 这里 不需要 删除任务 ,更新 PHY 协商的 参数 到MAC 层 即可
https://github.com/suoZhangEmbedded/stm32h7_freertos suozhang 发表于 2019-10-24 13:10
lwip请看 这里 不需要 删除任务 ,更新 PHY 协商的 参数 到MAC 层 即可
https://github.com/suoZh ...
这种的方式还不够彻底,比如客户端长时间断开,重连接次数达到最大值就停止重连了,插上后要重新连接。
这种方式最大的一个问题,如果几分钟内重新连接,一般都没有问题。如果长时间,比如几个小时,很容易内核无法正常运行了。 eric2013 发表于 2019-10-24 13:29
这种的方式还不够彻底,比如客户端长时间断开,重连接次数达到最大值就停止重连了,插上后要重新连接。
...
哦 还有 这种 bug ,多谢硬汉 eric2013 发表于 2019-10-24 13:29
这种的方式还不够彻底,比如客户端长时间断开,重连接次数达到最大值就停止重连了,插上后要重新连接。
...
分析的比较透彻啊 本帖最后由 oneV 于 2019-10-26 10:23 编辑
请教楼主 STM32H7 LWIP UDP通信 裸机编程遇到这个问题如何解决
平时都是OK的插交换机也是OK的
PHY出来后直连的交换机芯片 通信OK 拔掉交换机上的网线 插回去也是OK的
拔掉网线太久比如几个小时再插回去就不能工作了 如何解决这个问题 oneV 发表于 2019-10-26 10:19
请教楼主 STM32H7 LWIP UDP通信 逻辑编程遇到这个问题如何解决
平时都是OK的插交换机也是OK的
PHY ...
看看LWIP是否也方便做重新初始化操作,可以的话,应该也可以解决的。 eric2013 发表于 2019-10-26 10:21
看看LWIP是否也方便做重新初始化操作,可以的话,应该也可以解决的。
@硬汉 netETH_Notify()函数是不是只有在7.x版本上有呢?目前V6 的TCPnet例程中没有找到 萌军总司令 发表于 2019-11-5 17:16
@硬汉 netETH_Notify()函数是不是只有在7.x版本上有呢?目前V6 的TCPnet例程中没有找到
对,V7.X才有的。 eric2013 发表于 2019-10-23 14:35
也可以采用类似的方法。直接重新初始化网络,删除之前的网络应用任务。
尝试了关闭服务器连接、执行tcp_close,以及释放网卡相关内存(ETH_MEM_FREE(),lwip_comm_mem_free()),然后检测到网线连接后,重新初始化网卡(申请内存、ETH_MACDMA_config()以后的所有操作,包括lwip_init,添加网卡等)。
上述操作均为实现预期功能,拔掉网线再接上,服务器和客户端就连不上了。
卡死在err_t
ip_input(struct pbuf *p, struct netif *inp)函数里面。
请大神指点,检测到断线时,该执行哪些操作,检测到连接时,初始化哪些配置,不胜感激! 记录学习一下,马上就上项目了,学习了 pjzmj2012 发表于 2020-9-17 18:27
尝试了关闭服务器连接、执行tcp_close,以及释放网卡相关内存(ETH_MEM_FREE(),lwip_comm_mem_free()),然 ...
lwip比较麻烦些,要花点心思研究下。 V6板UDP例程中,以太网连接状态变量已经是封装好的,为啥我用下面这个语句他不会进入呢?
if(g_ucEthLinkStatus==0) ,不管网线插没插都不行。
if(g_ucEthLinkStatus==1) ,反而是==1的时候,不管网线插没插都会进去,是要设置什么吗? white9336 发表于 2021-12-24 14:34
V6板UDP例程中,以太网连接状态变量已经是封装好的,为啥我用下面这个语句他不会进入呢?
if(g_ucEthLinkS ...
老版的TCPnet没有这个,这个是TCPnet V7,X新设计的。 有时候行有时候不行,不行的时候网线插入后不能进入netETH_Notify函数。 smilingfrog 发表于 2022-2-15 14:56
有时候行有时候不行,不行的时候网线插入后不能进入netETH_Notify函数。
这个跟你的驱动和硬件复位设计有很大关系,一定要保证正常复位后再去操作就可以了,我们这个方案已经布局到产品中了,效果不错。 eric2013 发表于 2022-2-15 15:09
这个跟你的驱动和硬件复位设计有很大关系,一定要保证正常复位后再去操作就可以了,我们这个方案已经布局 ...
找到原因了,在这个贴子
https://www.armbbs.cn/forum.php?mod=viewthread&tid=103362&page=1
第136的
PHY.bcr =BCR_POWER_DOWN;
return (PHY.reg_wr(ETH_PHY_ADDR, REG_BCR, PHY.bcr));
这两句注释掉,改用
return ARM_DRIVER_OK;
替代。
感谢 smilingfrog 发表于 2022-2-15 15:35
找到原因了,在这个贴子
https://www.armbbs.cn/forum.php?mod=viewthread&tid=103362&page=1
第136的
...
那你的应该是8720。 eric2013 发表于 2022-2-15 16:25
那你的应该是8720。
8742A,ST的官方板 最好是通过心跳信号来维持链接。 smilingfrog 发表于 2022-2-15 16:48
8742A,ST的官方板
LAN8xxx这一家子都有这个问题。 我自己用STM32H750VBT6画的板子,用STM32CubeMX配置出来的管脚。
用的是V7-1007_RL-TCPnet V7.X实验_TCP服务器(FreeRTOS)这个历程的基础上,适配我板子的管脚。我想,750和743外设相差不大,应该就是改一下管脚配置就好了。
我用的phy芯片是LAN8720A。
适配完管脚和更换了LAN8720.c的驱动文件之后,已经能够正常的ping通,也能用网络测试工具连接板子,以及发数据。
然后我就想着测试一下热拔插的功能。能够检测到网线的拔出与插入,但是拔插之后,就ping不通了,网络调试工具也连接不了板子了。
不知道哪里的问题。
后面,我觉得都重新初始化了,应该没有别的东西占用了吧,要不再来一次,所以就在检测到拔出网线的那里,调用了两次netInitialize(); 就可以了。
不知道你们有没有遇到过这种情况。 ldqmcu 发表于 2022-4-28 11:36
我自己用STM32H750VBT6画的板子,用STM32CubeMX配置出来的管脚。
用的是V7-1007_RL-TCPnet V7.X实验_TCP服 ...
分享修正版RL-TCPnet V7.X和LwIP的LAN8720驱动,符合CMSIS-Driver驱动规范,适用于所有STM32系列(V1.1修正版)
https://www.armbbs.cn/forum.php?mod=viewthread&tid=103359&fromuid=58
(出处: 硬汉嵌入式论坛)
我用的是NetXDUO,没有netUninitialize,您的netUninitialize可否借鉴一下?谢谢
我也是使用NetXDUO,上电不插网线,上完电再插就connect不上了,请问有没有针对NetXDUO的一劳永逸的解决网线随意热插拔办法呢 NetXDUO 是否也能使用这种方法呢? way2888 发表于 2022-6-26 14:41
我也是使用NetXDUO,上电不插网线,上完电再插就connect不上了,请问有没有针对NetXDUO的一劳永逸的解决网线随 ...
同问呀,请问是否有同样的方法呢 lyricpoem 发表于 2023-6-30 15:16
同问呀,请问是否有同样的方法呢
NetXDUO还没有做这个方案 有lwip的改动例程吗 yuanzhongda 发表于 2024-1-11 15:42
有lwip的改动例程吗
lwip暂时没有这种方案。 eric2013 发表于 2019-10-23 10:58
实测,即使在网络高速通信期间,重新插拔网线,也不会有问题了。
硬汉哥,请教个问题,网线热插拔后如果复位协议站,那么之前的连接不都不存在了吗,那么tcp的keep-alive机制和重传机制不就没有作用了吗?不理解这里 yelu 发表于 2024-1-12 18:18
硬汉哥,请教个问题,网线热插拔后如果复位协议站,那么之前的连接不都不存在了吗,那么tcp的keep-alive ...
对,全部都复位了,然后重新启动连接即可。
页:
[1]