搜索
bottom↓
回复: 10

rt-thread lwip组件PHY中断的添加

[复制链接]

出0入0汤圆

发表于 2012-11-16 16:14:10 | 显示全部楼层 |阅读模式
RT-Thread官网的wiki页面上说:
在网口驱动中,最好添加上PHY中断相关通知,这样当网线因为松动或被断开时,lwIP能够知道网口已经断开。

我使用的是LWIP 1.0.3 版本,在代码中是按照如下方式添加了PHY中断
void PHY_IRQ(void)
{
    /* enter interrupt */
    rt_interrupt_enter();

        //检查中断源
        //清除中断标志
        ...

        if (链路状态发生变化,比如网线拔出或者插上)
        {
            if (netif_is_link_up(netif))
            {
                tcpip_callback((void (*)(void *))netif_set_link_down, netif);
            }
            else
            {
                tcpip_callback((void (*)(void *))netif_set_link_up, netif);
            }
        }

    /* leave interrupt */
    rt_interrupt_leave();
}

上面的代码经过了一番简化,netif_is_link_up、netif_set_link_down、netif_set_link_up是lwip/tcpip.h中声明的函数。
我遇到的问题是:程序第一次进入中断后,就在中断中永远无法跳出了。
经过debug,发现问题出在tcpip_callback(这是一个宏,实际的函数是tcpip_callback_with_block,这个函数最终会调用内存分配函数rt_malloc),而rt_malloc是不能在中断中调用的(在rt-malloc函数中会执行RT_DEBUG_NOT_IN_INTERRUPT),然后程序就死在这了。

请问PHY中断的添加是应该按照这种方式还是有其他的方法,比如直接调用netif_set_link_up而不是tcpip_callback(netif_set_link_up)?

阿莫论坛20周年了!感谢大家的支持与爱护!!

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

发表于 2012-11-16 16:30:17 | 显示全部楼层
PHY中断里面只发事件,由线程去通知LWIP。

参考作法:
建立一个link_change标致。
PHY中断里面设置这个标致并通知RX来处理(当收到一个包来通知)。
RX线程里面检查 link_change 标致并更新PHY的状态。

出0入0汤圆

 楼主| 发表于 2012-11-16 18:15:15 | 显示全部楼层
aozima 发表于 2012-11-16 16:30
PHY中断里面只发事件,由线程去通知LWIP。

参考作法:

谢谢楼上。刚刚照你的方法去改代码,才发现原来rt-thread已经提供相应的函数了,只要在中断中调用eth_device_linkchange函数就可以了。

之前自己折腾了很久的uC/OS+LwIP,在网线拔出很长时间后,再插上,应用线程就一直死在等待一个信号量上了,无法恢复。今天小试了一下rt-thread和自带的lwip组件,稳定性真不错。

出0入0汤圆

发表于 2012-11-21 21:48:50 | 显示全部楼层
sisai 发表于 2012-11-16 18:15
谢谢楼上。刚刚照你的方法去改代码,才发现原来rt-thread已经提供相应的函数了,只要在中断中调用eth_dev ...

MDIO是低速设备,一般不建议直接在中断里面读取PHY的状态。

建议PHY中断通知线程去处理PHY的状态更新。
或把PHY中断的优先级降低,不然会有比较大的中断延迟。

出0入0汤圆

发表于 2012-11-21 23:44:02 | 显示全部楼层
if (链路状态发生变化,比如网线拔出或者插上)
是"ETH_DMA_IT_FBE"吗?

出0入0汤圆

 楼主| 发表于 2012-11-22 21:06:07 | 显示全部楼层
aozima 发表于 2012-11-21 21:48
MDIO是低速设备,一般不建议直接在中断里面读取PHY的状态。

建议PHY中断通知线程去处理PHY的状态更新。

嗯,我之后就会这样去改

出0入0汤圆

 楼主| 发表于 2012-11-22 21:14:16 | 显示全部楼层
coolhorse 发表于 2012-11-21 23:44
if (链路状态发生变化,比如网线拔出或者插上)
是"ETH_DMA_IT_FBE"吗?

我用的PHY是DP83848C,它在链路发生变化的时候会给MCU一个中断信号,我是在中断处理函数中读取DP83848C的状态寄存器(BSR)来获知这个变化究竟是link up还是link down的(调用stm32的以太网库函数ETH_ReadPHYRegister(PHYAddress, PHY_BSR))。

但是如楼上上所说,这样会影响系统的实时性,所以可能后面会把PHY的读取放到线程中进行。虽然我的系统对实时性没有苛刻的要求,但当是养成好的习惯吧

出0入0汤圆

 楼主| 发表于 2012-11-22 21:20:02 | 显示全部楼层
coolhorse 发表于 2012-11-21 23:44
if (链路状态发生变化,比如网线拔出或者插上)
是"ETH_DMA_IT_FBE"吗?

PHY芯片给MCU的中断可能有多个中断源,读取MISR寄存器可以确知中断是否是链路状态的变化引起的。那么加上软件中保存链路状态的变量的值,就可以知道是link up还是link down了。比如原来软件中保存链路状态的变量的值是link up,那么发生了链路状态变化引起的中断之后,链路的状态就是link down了。这个和上面两个方法都可以,我之前都试过,不过目前我使用的是这个回复里面的方法。
头像被屏蔽

出0入0汤圆

发表于 2012-12-8 16:26:38 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

发表于 2012-12-10 14:57:22 | 显示全部楼层
好的处理方法啊,我还发现一个问题,拔网线再插上,TCP连接竟然没断

出0入0汤圆

发表于 2013-4-22 12:01:28 | 显示全部楼层
您好!看到你的帖子:rt-thread lwip组件PHY中断的添加
目前我也碰到这个问题:stm32f107+lwip在上电时,如果不插网线,则10无秒后网络不通,请求你修改的源码,供我参考,谢谢!邮箱:8316499@qq.com
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-10-3 03:21

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表