Pages: 1 ... 8 9 [10] 11 12 ... 18   Go Down
Author Topic: Ethernet (w5100) sketch hangs  (Read 21396 times)
0 Members and 1 Guest are viewing this topic.
Miramar Beach, Florida
Offline Offline
Faraday Member
**
Karma: 138
Posts: 5851
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@DCContrarian: That is not correct. Those registers are in the w5100, not the Arduino. I am reading them over the SPI connection. That jumping around is happening in the w5100.
Logged

Offline Offline
Full Member
***
Karma: 11
Posts: 147
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Did some more testing

client.print("Content-Length:");  will send a single packet of length 15

char* stuff = {"Content-Length:"};
client.print(stuff};                       will send a single packet of length 15

strcpy_P(Dbuf,PSTR("Content-Length:"));  will send a single packet of length 15
pachube.print(Dbuf);

Whereas,

int stuff = pick a number;
client.print(stuff, DEC);                     will send several packets 1 byte in length

So, it seems that formatting variables for display is where the problem could happen, otherwise it's no big deal.  Therefore, don't use client.print for sending individual variables.  Format them into a larger message like the sprintf examples we've shown and in general, the less prints, printlns, writes, you do, the less packets you'll be sending.  That makes sense, but is a far cry from the warnings I've seen about every single character being put into a separate packet when one uses print.

We should watch that, it will really drive the new folks nuts.

But:
String stuff = {"Content-Length:"};
client.print(stuff};                      

will result in 15 sends of length one.

It will go through Print::print(), which looks like this:

Code:
void Print::print(const String &s)
{
  for (int i = 0; i < s.length(); i++) {
    write(s[i]);
  }
}

That's where the danger is.
« Last Edit: October 20, 2011, 11:27:41 am by DCContrarian » Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
@zoomkat - Used your meta refresh example, mine locked at 9325 refreshes!!!!

I'm just letting the browser (IE 7) instance keep refreshing the page, and the counter goes up to ~32,000, at which point it rolls over and starts counting down, probably because the number is declared as an int. So far it has flipped four times and is increasing again at ~7,000, so the total number of pages served is ~135,000+ and counting. Had to turn off the hybernate on the laptop so there would be no power interruption. Every ~two seconds the ethernet shield LEDs blink and a new page is served. Been doing this for a couple of days now, just keeps working. I have a standard 328 arduino clone and old style ethernet shield. I've got other stuff hooked up to to the arduino for servos and such.

Very stange!  I'm not sure what the difference is between what you have going on and what I have going on.  I took your exact sketch (with changes to the IP and Mac address) and ran it using Firefox.  My Arduino Uno with brand new ethernet sheild froze at 9325 refreshes.  I'm using a desktop that never goes into any kind of power save, and defintely would not have during the time the page was able to refresh that many times, becuase I was using it the whole time.  AS far as power goes, it locks up when I power it externally as well with a 12v wall plug instead of using the usb cable.

So the question is, whats different between your hardware and mine?
Logged

New River, Arizona
Offline Offline
God Member
*****
Karma: 19
Posts: 928
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
But:
String stuff = {"Content-Length:"};
client.print(stuff};                       

will result in 15 sends of length one.

Yep, I completely believe that.  Things like that are why I never use the String library.  The Strings library is just too memory intensive with the various allocs and frees fragmenting stuff, it's just going to eventually kill an arduino.  Fine for learning experiences before moving on to a bigger machine, not fine for embedded processors.

But, that's not related to the problem here.  My machine ran for the longest period yet without failure.  The difference is that I'm counting socket opens against socket closes that I do, as well as comparing the length of the buffers to what they should be.  I put in monitoring code only, nothing to fix anything.  All I've managed find out is that I'm not doing something too terribly wrong in my own code.
Logged

Trying to keep my house under control http://www.desert-home.com/

Offline Offline
Full Member
***
Karma: 11
Posts: 147
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@DCContrarian: That is not correct. Those registers are in the w5100, not the Arduino. I am reading them over the SPI connection. That jumping around is happening in the w5100.


You're right,  readSnTX_WR(s) and readSnTX_RD(s) send an SPI message to the w5100 asking for the state of those registers.  I didn't dig enough.
Logged

Miramar Beach, Florida
Offline Offline
Faraday Member
**
Karma: 138
Posts: 5851
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That is why I think it is a critical timing thing. Here is the timing

TX_RD = 0
TX_WR = 0

Arduino reads TX_WR, writes 30 characters to the w5100 TX buffer, and sets TX_WR to the previously loaded value plus the length of the data. The registers are now
TX_RD = 0
TX_WR = 30

But after the w5100 sends them, they are
TX_RD = 1185
TX_WR = 1185

So at some point, the w5100 changes the TX_WR register.

Now the fail timing

The arduino code reads the TX_WR register, getting value 1185, and starts writing the 30 bytes to the TX buffer in the w5100 at position 1185.

Just as it starts, the w5100 decides it needs to build a packet, so it changes the TX_WR register to get the memory. Just for conversation, the value in TX_WR is now 1974.

The arduino code does not know this has changed, so it continues to write into the area the w5100 is using to build a packet.

The w5100 is now done creating the packet, so it sets TX_RD = 1974. Now TX_RD = TX_WR

The arduino code finishes writing the 30 bytes, and sets TX_WR to 1185 + 30 = 1215

And here is what you would end up with:
TX_WR = 1215
TX_RD = 1974


« Last Edit: October 20, 2011, 12:51:24 pm by SurferTim » Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 143
Posts: 5309
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If the w5100 had some manners and had learned to share, it would know not to change the TX_WR register. That belongs to the Arduino.

It doesn't change TX_WR.

At some point between sends with client.write(), both the TX_WR and the TX_RD registers change dramatically. Have you watched them?

Yes, I've seen that.

Any sudden changes in TX_WR are an illusion caused by interference with the SD card. If you're still seeing them then you didn't fix the SD card SPI problem.
Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 143
Posts: 5309
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

At the risk of being pedantic, I'll reiterate that the W5100 has no ability to write to the Arduino memory or registers. It just has a simple serial connection using SPI.

When SPI is started, a timer interrupt is enabled on the Arduino. A few thousand times a second that interrupt goes off, and when it does the Arduino calls an interrupt service routine which checks the SPI registers to see if a read or a write is pending. If one is, the Arduino writes to the MOSI line, strobes the clock, reads the MISO line, and updates the registers.

The leaping around of registers you see is being done by the Arduino in the interrupt service routine. 


With the greatest respect... that's complete rubbish. The main SPI interface is done completely in hardware by the ATmega chip. There's absolutely no need for any interrupts.

In fact it would be impossible to do it that way because you'd have to interrupt the CPU at 16MHz - not going to happen.

Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Miramar Beach, Florida
Offline Offline
Faraday Member
**
Karma: 138
Posts: 5851
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Yes, I've seen that.

Any sudden changes in TX_WR are an illusion caused by interference with the SD card. If you're still seeing them then you didn't fix the SD card SPI problem.

There is no longer any interference with the SD card. Not a single fail in thousands of downloads now.

Logged

New River, Arizona
Offline Offline
God Member
*****
Karma: 19
Posts: 928
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, folks, help me here.  It occurred to me that one of the loops in the ethernet library could be hanging up and killing us.  So, I've been traipsing through the code in socket.cpp.  There's stuff in send(SOCKET s, const uint8_t * buf, uint16_t len) that I just can't make sense of.

Please correct me if I'm wrong here, but it looks like there's several chances for problems in there.  There's also a couple of things that I just can't understand.  For example:  
Code:
 do
  {
    freesize = W5100.getTXFreeSize(s);
    status = W5100.readSnSR(s);
    if ((status != SnSR::ESTABLISHED) && (status != SnSR::CLOSE_WAIT))
    {
      ret = 0;
      break;
    }
  }
  while (freesize < ret);

  // copy data
  W5100.send_data_processing(s, (uint8_t *)buf, ret);
  W5100.execCmdSn(s, Sock_SEND);


Couldn't this lead to sending zero bytes?  Although, I can't see that being a problem like we've been having, I still don't understand it.  There's a couple of other things in there that appear weird to me.

edit:  if it does, it means W5100Class::write(uint16_t _addr, uint8_t *_buf, uint16_t _len) will write one byte and that will screw up the transfer buffer pointers.....won't it?
« Last Edit: October 20, 2011, 02:30:32 pm by draythomp » Logged

Trying to keep my house under control http://www.desert-home.com/

Offline Offline
Full Member
***
Karma: 11
Posts: 147
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Yes, I've seen that.

Any sudden changes in TX_WR are an illusion caused by interference with the SD card. If you're still seeing them then you didn't fix the SD card SPI problem.

There is no longer any interference with the SD card. Not a single fail in thousands of downloads now.



Just so we're all on the same page, is this a correct summary of your current status:
1. Pin 4 set to high to disable SD card
2. "Correction Code" that monitors for changes in TX_WR
3. Zero failures in that configuration so far
?

Is it also true that both (1) and (2) are necessary and that if either is omitted there will be failure?
Logged

New River, Arizona
Offline Offline
God Member
*****
Karma: 19
Posts: 928
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I have pin 4 high, but I have a check to tell me if the values change in the tx register while it's being copied.  I want to know that it found something instead of silently fixing it. 

And it fails.  Not as often, but it does fail.

I've been noticing though that I interact with the internet.  My device is subject to the vagaries of the world and I could well be getting partial packets and junk from time to time. 
Logged

Trying to keep my house under control http://www.desert-home.com/

Miramar Beach, Florida
Offline Offline
Faraday Member
**
Karma: 138
Posts: 5851
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@DCContrarian: Actually, I have removed the correction code. I am not comfortable with that. I may put it back.

But even with that correction code disabled, no errors. I ran it to over 4000 downloads each day two days in a row with not a single problem.

The only change now is pin 4 OUTPUT and HIGH before Ethernet.begin(). But considering the way I send data, I am not subject to the data collision problem. It is only if you are sending a bunch of packets in a row with only a few characters in each that you are subject to data collision problem.

I send one packet every 20 seconds. If that thing can't send a packet in 20 seconds....
 
Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 143
Posts: 5309
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Just so we're all on the same page, is this a correct summary of your current status:
1. Pin 4 set to high to disable SD card
2. "Correction Code" that monitors for changes in TX_WR

Is it also true that both (1) and (2) are necessary and that if either is omitted there will be failure?

If (1) is true I don't think you need (2)...
Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 143
Posts: 5309
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have pin 4 high, but I have a check to tell me if the values change in the tx register while it's being copied.  I want to know that it found something instead of silently fixing it. 

I'm not sure what you mean by this...

You don't really ever need to look at TD_RD. Use the free space register.

The W5100 only updates its internal copy of TX_WR after you send a "SEND" command.


Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Pages: 1 ... 8 9 [10] 11 12 ... 18   Go Up
Jump to: