搜索
bottom↓
回复: 29

调试STM32+ENC28J60环境下RTT+LWIP无响应的问题

[复制链接]

出0入0汤圆

发表于 2011-8-18 08:30:17 | 显示全部楼层 |阅读模式
这两天调试了一下STM32+ENC28J60环境下的LWIP

软件包是RTT论坛下的版本为RT-Thread-0.3.2

开始时都还好,连续PING 24小时都没有故障,

用NETIO测试了下网络速度,也能正常完成,

当我开了两个CMD窗口同时做这两个测试时,问题来了,ENC28J60不响应了,PING一直TIMEOUT,NETIO也死掉了,

但RTT仍在工作中

我在finsh察看ENC28J60的寄存器时发现ENC28J60的发送错误中断标志位置位了

finsh>>enc28j60()
-- enc28j60 registers:
HwRevID: 0x06
Cntrl: ECON1 ECON2 ESTAT  EIR  EIE
       0x0c  0x80  0x03  0x00  0xc8
MAC  : MACON1 MACON3 MACON4
       0x0d   0x33   0x40
Rx   : ERXST  ERXND  ERXWRPT ERXRDPT ERXFCON EPKTCNT MAMXFL
       0x0000 0x19fe 0x17e2  0x17e2  0xa1    0x00    0x05ee
Tx   : ETXST  ETXND  MACLCON1 MACLCON2 MAPHSUP
       0x19ff 0x1e36 0x0f     0x3f     0x10
        ',', 44, 0x0000002c
finsh>>

查了下论坛,好像一直有人在再说STM32+ENC28J60老有不稳定的现象

ffxz有提说是ENC28J60的驱动的问题,就这情况看了驱动文件

rt_err_t enc28j60_tx( rt_device_t dev, struct pbuf* p)
{
        struct pbuf* q;
        rt_uint32_t len;
        rt_uint8_t* ptr;
    rt_uint32_t level;

。。。

        // send the contents of the transmit buffer onto the network
        spi_write_op(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
        // Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12.
        if( (spi_read(EIR) & EIR_TXERIF) )
        {
                spi_write_op(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS);     <----这里看起来作了错误处理,但好像没有用
        }

    /* enable enc28j60 interrupt */
    enc28j60_interrupt_enable(level);
    rt_sem_release(&lock_sem);

    return RT_EOK;
}

于是翻了下中断服务
void enc28j60_isr()
{
        /* Variable definitions can be made now. */
        volatile rt_uint32_t eir, pk_counter;
        volatile rt_bool_t rx_activiated;

。。。


                /* TX Error handler */
                if ((eir & EIR_TXERIF) != 0)
                {
                        spi_write_op(ENC28J60_BIT_FIELD_CLR, EIR, EIR_TXERIF);     <----- 这里也有处理代码,为何还有问题呢?
                }

                eir = spi_read(EIR);
                // rt_kprintf("inner eir: 0x%08x\n", eir);
        } while ((rx_activiated != RT_TRUE && eir != 0));
}

再查ENC28J60的文档,在官方的Errata文档(文档编号cn532750.pdf)找到了这样一句话:

12. Module: Transmit Logic
In Half-Duplex mode, a hardware transmission
abort caused by excessive collisions, a late collision
or excessive deferrals, may stall the internal
transmit logic. The next packet transmit initiated by
the host controller may never succeed
(ECON1.TXRTS will remain set indefinitely).
Work around
Before attempting to transmit a packet (setting
ECON1.TXRTS), reset the internal transmit logic
by setting ECON1.TXRST and then clearing
ECON1.TXRST. The host controller may wish to
issue this Reset before any packet is transmitted
(for simplicity), or it may wish to conditionally reset
the internal transmit logic based on the Transmit
Error Interrupt Flag (EIR.TXERIF), which will
become set whenever a transmit abort occurs.
Clearing ECON1.TXRST may cause a new transmit
error interrupt event (EIR.TXERIF will become
set). Therefore, the interrupt flag should be cleared
after the Reset is completed.

Google是这样翻译的

在半双工模式下,硬件传输
过多的冲突所造成的中止,后期碰撞
或过度推迟,可能会停止内部
发送逻辑。下一个数据包发送开始
主机控制器可能永远不会得逞
(ECON1.&#8203;&#8203;TXRTS仍将无限期设置)。
解决
试图发送一个数据包之前(设置
ECON1.&#8203;&#8203;TXRTS),复位内部传输逻辑
通过设置ECON1.&#8203;&#8203;TXRST,然后清除
ECON1.&#8203;&#8203;TXRST。主机控制器不妨
任何数据包传输之前发出此复位
(简单),或者它可能希望有条件地复位
基于发送的内部传输逻辑
错误中断标志(EIR.TXERIF),这将
成为集时中止发送时。
结算ECON1.&#8203;&#8203;TXRST可能导致一个新的发射
错误中断事件(EIR.TXERIF将成为
设置)。因此,应清除中断标志
复位完成后。

---------------------------------------------------------------

哦,原来是这的毛病,ENC28J60的内部发送逻辑停止了

于是,在中断服务程序中加了几句话

                /* TX Error handler */
                if ((eir & EIR_TXERIF) != 0)
                {
//-------------------------------------------------------------------------------------------      添加开始
                        enc28j60_set_bank(ECON1);
                        spi_write_op(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST);
                        spi_write_op(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST);
                        enc28j60_set_bank(EIR);
//-------------------------------------------------------------------------------------------      添加结束
                        spi_write_op(ENC28J60_BIT_FIELD_CLR, EIR, EIR_TXERIF);
                }

再测,可以了

只是网络速度稍微降了点,但仍有响应,负载过重时PING有TIMEOUT的现象,但一旦负载减轻,响应时间仍小于1mS

这估计就是困扰过好多网友的BUG吧

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

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2011-8-18 08:39:44 | 显示全部楼层
单独测试网络速度(注,我SPI总线速度调成了18M)

C:\Documents and Settings\Jeames>win32-i386 -t 192.100.30.239

NETIO - Network Throughput Benchmark, Version 1.26
(C) 1997-2005 Kai Uwe Rommel

TCP connection established.
Packet size  1k bytes:  232 KByte/s Tx,  4800 Byte/s Rx.
Packet size  2k bytes:  232 KByte/s Tx,  332 KByte/s Rx.
Packet size  4k bytes:  232 KByte/s Tx,  332 KByte/s Rx.
Packet size  8k bytes:  233 KByte/s Tx,  332 KByte/s Rx.
Packet size 16k bytes:  234 KByte/s Tx,  332 KByte/s Rx.
Packet size 32k bytes:  237 KByte/s Tx,  140 KByte/s Rx.
Done.

C:\Documents and Settings\Jeames>

如果同时PING的情况

C:\Documents and Settings\Jeames>win32-i386 -t 192.100.30.239

NETIO - Network Throughput Benchmark, Version 1.26
(C) 1997-2005 Kai Uwe Rommel

TCP connection established.
Packet size  1k bytes:  232 KByte/s Tx,  4743 Byte/s Rx.
Packet size  2k bytes:  232 KByte/s Tx,  258 KByte/s Rx.
Packet size  4k bytes:  232 KByte/s Tx,  252 KByte/s Rx.
Packet size  8k bytes:  233 KByte/s Tx,  224 KByte/s Rx.
Packet size 16k bytes:  234 KByte/s Tx,  185 KByte/s Rx.
Packet size 32k bytes:  237 KByte/s Tx,  141 KByte/s Rx.
Done.

C:\Documents and Settings\Jeames>

速度也可以接受,

出0入0汤圆

发表于 2011-8-18 09:31:26 | 显示全部楼层
谢谢 反馈&给出方法。ENC28J60因为没固定的开发板,所以后续没怎么跟进(有个ENC28J60的模块,需要自己接线,每次都接太麻烦了,所以使用得不多)

我有空把你的补丁和现在的驱动仔细看看,如果没问题就加入到svn中,随着后续0.4.0 RC1版本发布出来。

出0入0汤圆

发表于 2011-8-18 15:38:53 | 显示全部楼层
楼主: 可以提供源程序吗? 谢谢!

出0入0汤圆

发表于 2011-8-18 18:43:50 | 显示全部楼层
MARK,回头试试~

出0入0汤圆

发表于 2011-8-18 20:12:07 | 显示全部楼层
mark。

出0入0汤圆

 楼主| 发表于 2011-8-18 21:54:39 | 显示全部楼层
回复【3楼】zhang..yb  
-----------------------------------------------------------------------

点击此处下载 ourdev_668931XSEMYF.zip(文件大小:4.76M) (原文件名:RT-Thread-0.3.2.zip)

这是官方论坛的代码

修改的部分请自行根据自己的板子解决吧,应该不难

出0入0汤圆

发表于 2011-8-19 10:11:20 | 显示全部楼层
谢六楼,我不用 OS
如果要去除 OS,怎么做?

出0入0汤圆

 楼主| 发表于 2011-8-20 13:25:59 | 显示全部楼层
回复【7楼】zhang..yb  
-----------------------------------------------------------------------

呃, ...

这个嘛,我没弄过

出0入0汤圆

发表于 2011-9-27 22:55:47 | 显示全部楼层
mark,mark....这次一定要mark...HOHO
以前看到过这个帖子,但没mark,现在碰到了这个问题,花10多分钟一个一个帖子看,终于找到了,不容易呀。

楼主真是好人!!!!

出0入0汤圆

发表于 2011-9-28 15:33:45 | 显示全部楼层
mark,mark....

出0入0汤圆

发表于 2011-10-11 09:40:12 | 显示全部楼层
果然有效,谢谢楼主!

出0入0汤圆

发表于 2011-10-11 11:00:40 | 显示全部楼层
已合并楼主提供的改动.谢谢分享.

出0入0汤圆

发表于 2011-11-21 20:16:00 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-11-23 00:10:10 | 显示全部楼层
总算找到了原因。

以前我也跟踪到了这里,但看手册没看到什么好办法(没看勘误表,汗)
后来想,既然是错误处理出了问题,我把芯片重新复位应该可以吧。
已是我加了
enc28j60_init(&enc28j60_dev_entry.parent.parent);
:(
幸好后来我测试速度也还可以,应该达到了楼主的速度。

出0入0汤圆

发表于 2011-11-23 08:37:53 | 显示全部楼层
STM32+ENC28J60环境下RTT+LWIP无响应的问题 谢谢lz

出0入0汤圆

发表于 2011-11-28 08:32:41 | 显示全部楼层
Mark

出0入0汤圆

发表于 2011-11-29 13:36:33 | 显示全部楼层
Mark

出0入0汤圆

发表于 2012-7-10 15:37:27 | 显示全部楼层
谢谢,在学lwip

出5入42汤圆

发表于 2012-9-18 13:50:31 | 显示全部楼层
在微芯官方的TCP/IP协议栈里面,其实已经修正了这个bug,大家因为使用的是第三方的协议栈,故这个bug肯定会出现。

顺便回答6楼的提问:“如果要去除 OS,怎么做?”

很简单,在数据包发送的函数里面添加如下代码:
   // Reset transmit logic if a TX Error has previously occured
    // This is a silicon errata workaround
    BFSReg(ECON1, ECON1_TXRST);
    BFCReg(ECON1, ECON1_TXRST);
    BFCReg(EIR, EIR_TXERIF | EIR_TXIF);

这就是勘误表里面提到的
"Before attempting to transmit a packet (setting ECON1.TXRTS), reset the internal transmit logic by setting ECON1.TXRST and then clearing
ECON1.TXRST. "

然后还有:
   // Start the transmission
    // After transmission completes (MACIsTxReady() returns TRUE), the packet
    // can be modified and transmitted again by calling MACFlush() again.
    // Until MACPutHeader() is called, the data in the TX buffer will not be
    // corrupted.
    BFSReg(ECON1, ECON1_TXRTS);

对于某些特定的硅片版本的ENC28J60还需要:
   // Revision B5 and B7 silicon errata workaround
    if(ENCRevID == 0x05u || ENCRevID == 0x06u)
    {
        WORD AttemptCounter = 0x0000;
        while(!(ReadETHReg(EIR).Val & (EIR_TXERIF | EIR_TXIF)) && (++AttemptCounter < 1000u));
        if(ReadETHReg(EIR).EIRbits.TXERIF || (AttemptCounter >= 1000u))
        {
            WORD_VAL ReadPtrSave;
            WORD_VAL TXEnd;
            TXSTATUS TXStatus;
            BYTE i;

            // Cancel the previous transmission if it has become stuck set
            BFCReg(ECON1, ECON1_TXRTS);
//……
//完成整个数据包发送过程……
//bug修复结束
//================================================
当前的ENC28J60的硅片版本可以通过如下函数获取:
ENCRevID = ReadETHReg((BYTE)EREVID).Val;

其实最好的解决办法是不要使用ENC28J60这个垃圾片子,有bug,也不支持自适应,还不如多加几块钱,上424J600或者642J600,都没这个问题。

出0入0汤圆

发表于 2013-3-30 18:38:38 | 显示全部楼层
学习了~~~~

出0入0汤圆

发表于 2013-7-18 22:10:42 | 显示全部楼层
神坛啊,我也遇到这个问题了,用的LWIP+STM32+UCOS,只要发送不出来,基本都会跳到  
if( (spi_read(EIR) & EIR_TXERIF) )
  {
                spi_write_op(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS);     <----这里看起来作了错误处理,但好像没有用
        }

我直接在这里加了中断中的代码,貌似还是没用,是不是一定要在中断才可处理?

出0入0汤圆

发表于 2013-8-13 00:27:12 | 显示全部楼层
mark            

出100入101汤圆

发表于 2013-11-1 19:50:57 | 显示全部楼层
LZ有没有碰到过ENC28J60能发送数据、不能接收数据情况?

出0入0汤圆

发表于 2013-11-1 20:10:37 | 显示全部楼层
LZ有没有测试过tcp client例程,怎么我的每次发出去的包都是重传包,tcp server则正常

出0入0汤圆

发表于 2014-7-25 17:43:32 | 显示全部楼层
kevin_me 发表于 2012-9-18 13:50
在微芯官方的TCP/IP协议栈里面,其实已经修正了这个bug,大家因为使用的是第三方的协议栈,故这个bug肯定会 ...

按这个修改后正在测试,之前电脑调试端连续发送数据接收再返回PC,接收到5至6M左右数据时就不接收了,让单片机主动向上发可以发送,过会主动发也不行。现在PC端10MS发送一次,接收再返回,接收到12M的数据了,还没卡死现象。。。。SPI跑10M,继续测试。。。。。。。

出0入36汤圆

发表于 2016-3-19 19:58:29 | 显示全部楼层
本帖最后由 redworlf007 于 2016-3-19 20:00 编辑
lixun00 发表于 2011-11-23 00:10
总算找到了原因。

以前我也跟踪到了这里,但看手册没看到什么好办法(没看勘误表,汗)


if ((eir & EIR_TXERIF) != 0)
                {
                enc28j60_init(&enc28j60_dev_entry.parent.parent);
                }


你是这么加的么?

出0入0汤圆

发表于 2016-3-24 23:22:18 | 显示全部楼层
是,重新初始化

出0入0汤圆

发表于 2016-7-19 16:28:23 | 显示全部楼层
STM32+ENC28J60+LWIP  楼主好银
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-27 00:06

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

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