[uip-users] Webserver problem

31 views
Skip to first unread message

Simone

unread,
Mar 4, 2007, 6:17:42 AM3/4/07
to uip-...@sics.se
Hello,
i'm playing with uIP stack on an 8051 like microcontroller (specifically the
cypress FX2 usb chip)
I was able to port the stack and run it, get ping responses and have the
telnetd application working.
I'm not currently able to run the webserver example. Here is the description
of events (8051 is refered as the host/webserver while the PC/browser is the
client):

1) i run the application, setup the connection, open the browser and browse
for the main page (index.html)
2) the webserver receive the HTTP GET request for the required page and send
the correct header (http_header_200)
3) a tcp acknowledge message is sent back from the client to the host
4) the webserver try to send the http header once again but then stop
without doing it.
5) the webclient waits forever for a message that will never arrive.

at this point i'm able to perform a ping and it works, so this meand that
tcp and microcontroller are still working. The only problem is related to
the webserver. In my opinion on point 4 the webserver doesn't have to send
the http header again but the file content instead (index.html), but this
doesn't happen and the client waits forever.
Some idea on what's the problem and how to solve it?
Thanks in advance to everybody,
Simone Pedruzzi

Peter Zuidema

unread,
Mar 4, 2007, 10:03:39 AM3/4/07
to uip-...@sics.se
Hello Simone,

Try to set the buffer size to at least 1500 bytes. I got the same problems
with uIP v1.0 and after a week of testing I found the cause.

Open "uip-conf.h" and set "UIP_CONF_BUFFER_SIZE" to at least 1500 (I use
2048).

See also the mail thread on 24 january 2007 "Problems with uIP 1.0 for
FreeRTOS 4.1.2".

According the developers it should work with smaller buffer sizes, but not
with me. I used IAR with FreeRTOS v4.1.2 and uIP 1.0. Now I use
Eclipse/Yagarto with GCC-ARM and FreeRTOS v4.1.3 and uIP 1.0.

What version of uIP do you use and which development environment?

Regards,
Peter

> -----Oorspronkelijk bericht-----
> Van: owner-u...@sics.se [mailto:owner-u...@sics.se]Namens
> Simone
> Verzonden: zondag 4 maart 2007 12:18
> Aan: uip-...@sics.se
> Onderwerp: [uip-users] Webserver problem

Simone

unread,
Mar 4, 2007, 1:27:18 PM3/4/07
to uip-...@sics.se
Thanks a lot Peter!!
The buffer size seems to be one of the problems!! But the first one i've
figured out is this one: the & operator used in the psock.c don't work as
written in the comments below! There are at least a couple of points in the
code which are affected by this, maybe it's due to the compiler and/or
compiler optimizations i've used (it's the keil c51).

THE ORIGINAL CODE:

/*
* The condition for this PT_WAIT_UNTIL is a little tricky: the
* protothread will wait here until all data has been acknowledged
* (data_acked() returns true) and until all data has been sent
* (send_data() returns true). The two functions data_acked() and
* send_data() must be called in succession to ensure that all
* data is sent. Therefore the & operator is used instead of the
* && operator, which would cause only the data_acked() function
* to be called when it returns false.
*/

PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));


It seems that with my setup the evaluation of the expression data_acked(s) &
send_data(s) depends on the order of the operands and it do not work in any
case, so i've adjusted the code in this way, using a temp variable to store
the results and have both function evaluated:

THE CODE MODIFIED BY ME

temp = 1;
temp &= data_acked(s);
temp &= send_data(s);
PT_WAIT_UNTIL(&s->psockpt, temp );

In this way i've made a significant step in having the webserver running!!
But it wasn't enough since the pages do not load completely, and here is
where your advice come in help. In facts, after having increased the buffer
size finally i can see the (full) sample web page in the browser window!
Great!! Now i've some problems with the script handling but this is another
matter.. i'll check it later.
About the buffer size, i think that if packet fragmentation is disabled you
need to set the buffer size at the maximum size of the file you want to
send/receive, otherwise the file do not fit and without fragmentation it
cannot reach the destination. I suppose that with fragmentation enabled
bigger files can be sent even with limited buffer but I do not know if the
fragmentation code, which is disabled by default, is working or not. I've
tried it but fragmented ping requests do not generate the expected answer.
Maybe developers can help on this..? :p
Anyway, great job guys!!
Simone

Till Harbaum

unread,
Mar 4, 2007, 3:27:02 PM3/4/07
to uip-...@sics.se, Simone
Hi,

Am Sonntag, 4. März 2007 19:27 schrieb Simone:
> The buffer size seems to be one of the problems!! But the first one i've
> figured out is this one: the & operator used in the psock.c don't work as
> written in the comments below! There are at least a couple of points in the

Interesting. In fact i don't think the assumption made in the comment is
necessarily true. Is there any convention in the C standard stating that both
sides of an arithmetic expression _must_ be evaluated?

Can you ask the compiler to gerneate an assembler file? It should be easily
visible as there must be an explicit test for a zero first result.

Ciao,
Till

--
Dr. Till Harbaum <Ti...@Harbaum.org>

Olaf Hartmann

unread,
Mar 5, 2007, 5:04:17 AM3/5/07
to uip-...@sics.se
Quoting Simone <one...@tiscalinet.it>:

Uhm. This patch is no good. =)

The macro PT_WAIT_UNTIL implements a blocking wait for protothreads and
gets translated to:


temp = 1;
temp &= data_acked(s);
temp &= send_data(s);

do {
LC_SET((&s->psockpt)->lc);
if(!(temp)) {
return PT_WAITING;
}
} while(0)
where LC_SET basically is a label that will be jumped to from the
beginning of the function. So temp will not be evaluated every time as
it should. If your variable temp isn't static or global it's contents
is even random...

But i agree that this data_acked() & send_data() code is very ugly and
even seems to fail for you. I suggest that data_acked() and send_data()
should be put into one function, which makes to code much more readable.

btw: additionally psock_generator_send() has the problem, that it
cannot retransmit packets, since the PT_WAIT_UNTIL() macro waits for an
ack, but the retransmit is done in a loop around PT_WAIT_UNTIL.

Greets
Olaf

Olaf Hartmann

unread,
Mar 5, 2007, 5:27:15 AM3/5/07
to uip-...@sics.se
Quoting Olaf Hartmann <olaf.h...@s1998.tu-chemnitz.de>:
> btw: additionally psock_generator_send() has the problem, that it
> cannot retransmit packets, since the PT_WAIT_UNTIL() macro waits for
> an ack, but the retransmit is done in a loop around PT_WAIT_UNTIL.

Well, the retransmit occurs, but the data is no generated again. Thats
the code i am talking about here:

do {
/* Call the generator function again if we are called to perform a
retransmission. */
if(uip_rexmit()) {
generate(arg);
}
/* Wait until all data is sent and acknowledged. */


PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));

} while(s->sendlen > 0);

I believe the loop does not make sense, because only one packet of data
is transmitted in psock_generator_send(). An the data is not
regenerated in case of retransmission, which should not be a problem
unless the buffer gets overwritten by received data.


Olaf

Simone

unread,
Mar 7, 2007, 2:36:24 PM3/7/07
to uip-...@sics.se
Hello,
i'm here again, i can confirm that the following code do not work well in my environment.
 
PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s) );
 
but looking at the assembly code, as suggested by Till, we can see that both expressions are evalueted before the jump, so it's not clear why it doesn't work
 
   217:     PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s) );
C:0x4B20    900002   MOV      DPTR,#0x0002
C:0x4B23    E4       CLR      A
C:0x4B24    75F0D9   MOV      B(0xF0),#0xD9
C:0x4B27    122DAA   LCALL    C?ISTOPTR(C:2DAA)
C:0x4B2A    90D635   MOV      DPTR,#psock_send?BYTE(0xD635)
C:0x4B2D    122DE3   LCALL    C?PLDXDATA(C:2DE3)
C:0x4B30    12543C   LCALL    send_data(C:543C)
C:0x4B33    AC07     MOV      R4,0x07
C:0x4B35    90D635   MOV      DPTR,#psock_send?BYTE(0xD635)
C:0x4B38    122DE3   LCALL    C?PLDXDATA(C:2DE3)
C:0x4B3B    12539E   LCALL    data_acked(C:539E)
C:0x4B3E    EF       MOV      A,R7
C:0x4B3F    5C       ANL      A,R4
C:0x4B40    70D7     JNZ      C:4B19
C:0x4B42    FF       MOV      R7,A

 
Anyway, by putting the two functions in one and having them explicitally evalueted, and returning the combined result, it works fine.
Simone
 
 
 
Reply all
Reply to author
Forward
0 new messages