MC9S12NE64 - Ethernet interface stops reacting to incominhg frames

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

MC9S12NE64 - Ethernet interface stops reacting to incominhg frames

7,080 次查看
galn2511
Contributor I
I am using MC9S12NE64 with software developed using Codewarrior and based on OpenTCP.

My application opens a simple tcp client connection that maintains echo request/answer.

So far, everything worked well, but there is a vary wierd situation in which after few hours of work, the software seem to stop getting interrupts for incoming frames.

At this situation the software continues to operate normaly (sending SYN connection request) but it seems that it can't see incoming frames (SYN+ACK answers).

Although that through a sniffer i can see the connection requests and answers, by putting breakpoints inside recive procedure, i can see that the software doesn't even get there...

how is it possible, that this incoming frames are not treated?

Thanks,

Gal

标签 (1)
0 项奖励
回复
7 回复数

1,263 次查看
mjbcswitzerland
Specialist V

Hi Gal

Possibly a receive interrupt problem. If you have a DBM check that the received frames are being placed in SRAM at 0x2000 and 0x2000 + RX buffer size. Check the state of the receive registers and you may see that the two buffers are flagged as full but the interrupt has not processed them - therefore nothing more will happen.

It may be possible then to restart receive operation by resetting relevent bits in the EMAC registers and ensuring that the interrupts are free to operate again.

Unfortunately such problems can be quite difficult to pinpoint and solve, but I haven't heard of OpenTCP having driver difficulties before.

At my web site there are several on-line demos running on NE64s, wich you can control via a browser and see via web cam - inclduing dynamic http generation and control and FTP for web page updates. The NE64 is an extremely reliable part and some of these demos have been running for over 6 months without known problems.

I also have a demo project which can be downloaded at http://www.mjbc.ch/software/Demo/j8jdwk-ku7/uTaskerPingDemo.zip 
(instructions in directory applications\ping)
which includes the uTasker operating system and TCP/IP stack (only basic for the demo) and also runs as NE64 simulator on the PC. When the NE64 EMAC is used, data is sent over the PC's NIC and when LAN data is received by the PC, it is passed through the real NE64 interrupt code, driver routines, up the stack etc. You may find it of some use.

The uTasker environment is also free - including free support - to educational establishments and for non-commercial projects.

Cheers

Mark Butcher

www.mjbc.ch

 

0 项奖励
回复

1,263 次查看
williamskj
Contributor I
We seem to be experiencing the same thing. We can make it happen when we send messages at intervals of less than 250ms.

I've set-up debugging for the ethernet code over the serial port.
It seems that at intervals above 250ms, only the ISR for receive buffer A is being triggered (Debugger text=EMAC_RXA_GOOD_ISR). Once the intervals go below 250ms, the ISR for receive buffer B gets triggered too (Debugger text=EMAC_RXB_GOOD_ISR) and then new messages get ignored for 1,2,3 or 4 seconds. Then one message will be received and then new messages get ignored for 1,2,3 or 4 seconds again, etc.

I've also watched locations 0x2000+ and they freeze and then restart in the same way as the output from the serial terminal debugger session.

If it helps, I've also got test code which performs a repeating "connect, send one message, disconnect" cycle with 25ms between steps (so a 75ms cycle) and that works fine over thousands of cycles. Presumably the disconnect/reconnect resets some vital registers ???

As I'm no expert in ethernet comms, I'm reluctant to start changing code at this level to convince the thing that it really has got data coming in. If I do need to do this though, does anyone have any advice on what needs to be done ?

Thanks,

Karl
0 项奖励
回复

1,263 次查看
williamskj
Contributor I

For anyone still interested in this....

I've had a Freescale service request open for several weeks regarding this issue. Freescale managed to replicate the problem. The case was forwarded to the design centre so that the hardware could be checked. There was no fault found in the hardware. Freescale then tried a similar set of tests but the NE64 code was built using the CMX TCP/IP stack rather than the OpenTCP stack. The fault could no longer be replicated. The conclusion therefore is that this behaviour is due to a bug in the OpenTCP stack. Unfortunately, Freescale can no longer provide support for the OpenTCP stack since Viola Systems have started charging 20,000 Euros for the product. Since I don't have the time or expertise to debug the OpenTCP stack, we have decided to try the CMX stack which is not cheap but its a lot less expensive than the new (?) 'supported' OpenTCP stack.

0 项奖励
回复

1,263 次查看
bala
Contributor I
Firstly I see that NE64FreeReceiveBuffer() has a serious bug - it doesn't clear the Rx Buffer B (a typo, used to clear Rx Buf A). So  change it to  IEVENT_RXBCIF  = 1;

 
In NE64Receive() I notice that there could be multiple events occuring when you swamp your system with packets and hence explicitly checking for Rx Buffer B helps.
 
   if (mp.status & IEVENT_RXACIF_MASK)
   {
       IMASK_RXACIE = 0;   /* Block IRQs on buffer A */
       (void) mENQUEUE(&mp);
   }
   else if (mp.status & IEVENT_RXBCIF_MASK)
   {
       IMASK_RXBCIE = 0;   /* Block IRQs on buffer B */
       (void) mENQUEUE(&mp);
   }
 
These changes hopefully fixes your problem!
 
Cheers
Bala
0 项奖励
回复

1,263 次查看
foreigner
Contributor I
Hi All!
 
I am running into the same issue with my NE64.  Right now I am just sending "raw" ethernet packets (BacNet-ethernet) and it will "lock up" every now and then (most of the time a day or many days in between).  I have added some debug capability to spit out some registers on a serial port to try to figure it out.
When the problem occurs the IEVENT register have the RXACIF and RXBCIF flags set, the IMASK register have the RXACIE and RXBCIE flags cleared.  My buffer status flags (in mbuf) have the "not empty flags" cleared so it thinks there is nothing in the buffers.  So the "free receive buffers" will not free my buffers and turn the isrs back on and it does not think there is anything in the rx buffers and it will just not do anything.
One note:  This board ran fine for about 6 months until we installed a new router and that's when this started happening.  I don't know why but I believe it's getting a lot more traffic now which seems to make it worse (maybe using RXA and RXB buffers??).
 
Thanks,
Foreigner
0 项奖励
回复

1,263 次查看
BugBlatter
Contributor I
I have just had the same problem and think I have fixed it. The problem is in ne64api.c which has a number of errors and typos which causes both receive interrupts to get switched off. The main fix was in NE64Receive() which assumes that if the IEVENT_RXACIF_MASK is not set, it must be a buffer B receive. However, it looks like this routine is called when neither IEVENT_RXACIF_MASK nor IEVENT_RXBCIF_MASK is set (I have got to look into this further).

Other fixes are:-

1. move the setup of received_frame from NE64Recieve() to NE64ValidFrameReception(). This prevents receive event on one buffer overwiting information for the other.

2. Fixed a typo in NE64FreeReceiveBuffer() which was setting IEVENT_RXACIF when freeing up the B buffer

I have attached a new version of ne64api.c from the Connector_App application which came with the DEMO9S12NE64 box. In case you can't get the attachment, just email me to send you the file instead.

Mike
0 项奖励
回复

1,263 次查看
OmniSense
Contributor I
The following function has a bug whcih I have also reported here http://sourceforge.net/tracker/?func=detail&aid=2941074&group_id=119500&atid=684216. Under heavy traffic it can (and will and
has in my case) free up two packets in one call resulting
in the condition where where both RX?CIF flags were set and both RX?CIE
interrupt enables were disabled which in turn prevents
any more packets from getting received resulting in total lockup of the
ethernet interface.

void NE64FreeReceiveBuffer (void)
{
if (pCurrentMBuf->status & IEVENT_RXACIF_MASK)
{
pCurrentMBuf->status = 0;
IEVENT = IEVENT_RXACIF_MASK;
IMASK_RXACIE = 1;
}

if (pCurrentMBuf->status & IEVENT_RXBCIF_MASK)
{
pCurrentMBuf->status = 0;
IEVENT = IEVENT_RXBCIF_MASK;
IMASK_RXBCIE = 1;
}
}

CORRECTED CODE - note the addition of the else to prevent execution of both
ifs in one call

void NE64FreeReceiveBuffer (void)
{
if (pCurrentMBuf->status & IEVENT_RXACIF_MASK) {
pCurrentMBuf->status = 0;
IEVENT = IEVENT_RXACIF_MASK;
IMASK_RXACIE = 1;
} else if (pCurrentMBuf->status & IEVENT_RXBCIF_MASK) {
pCurrentMBuf->status = 0;
IEVENT = IEVENT_RXBCIF_MASK;
IMASK_RXBCIE = 1;
}
}
0 项奖励
回复