Value differs for static / nonstatic function

Hey guys,

I'm programming for over 10 years now already, but I never saw this one. What I want to do, is run the WebServer example for the W5100 chip that is included in the standard Arduino IDE. The only difference is that I'm using my own bootloader, which I will make public soon, that allows you to upload sketches to the Arduino Ethernet via LAN.

The uploading works like a charm so far, but if I try to use the W5100 chip outside of the bootloader, here in the WebServer example, it doesn't work anymore. I can ping it, I can connect to it, but I get no reply.
After some debugging I found, that client.available() returns 1024-1280 before any read, even tho I'm only connection with telnet and not sending a single byte. The number goes down till it reaches 1024 when it will jump to 1280 and start over.

I traced the problem down to this:

uint16_t res = W5100.readSnRX_RSR(0);
// res is now 1024

res = W5100.readSn(0, 0x0026);
res = (res << 8) + W5100.readSn(0, 0x0026 + 1);
// res is now 0 as it should be

The lower part is the actual readSnRX_RSR(0) function.
So I defined my own function:

uint16_t readTest(SOCKET _s) 
{ 
    uint16_t res = W5100.readSn(_s, 0x0026);                      
    res = (res << 8) +W5100. readSn(_s, 0x0026 + 1);              
    return res;          
}

uint16_t res = readTest(0); // returns 1024

If I change the definition of the function slightly, by adding the static keyword:

static uint16_t readTest(SOCKET _s)

then it returns 0 as it's supposed to.

Does anyone have a good suggestions what might cause this?
Note: I'm using a slimmed version of w5100.h/.c and socket.h/.c in the bootloader as well.

Thanks!

there is a oneliner diff in the 2 codeblocks you showed

try this to make it identical (just looking at the pattern, no detailed knowledge of the wiz chip)

uint16_t readTest(SOCKET _s) 
{ 
  uint16_t res = W5100.readSnRX_RSR(0);  // may set some register ... 
  res = W5100.readSn(_s, 0x0026);                      
  res = (res << 8) + W5100.readSn(_s, 0x0026 + 1);             
  return res;          
}

Sorry, maybe i wasn't entirely clear in that section.

This is the code that should work, but doesnt:

uint16_t res = W5100.readSnRX_RSR(0);

This is the code that works:

uint16_t res = W5100.readSn(0, 0x0026);
res = (res << 8) + W5100.readSn(0, 0x0026 + 1);

readSnRX_RSR is defined as the two lines in the lower code block. Makes sense?

Now I understand the problem better, thank you.

Sorry, I can't help you with a solution.

Rob

Apparently this is caused by Arduinos IDE not using -fno-split-wide-types with avr-gcc 4.5.3
Adding that optimizer flag resolves all problems.

Does anyone know how that could be the reason? Arduinos IDE should really have a config value to enter own CFLAGS.