public inbox for ecos-discuss@sourceware.org
 help / color / mirror / Atom feed
* [ECOS] socket times out, but not with printf
@ 2003-09-06  0:14 mailsagr
  2003-09-06  8:34 ` Andrew Lunn
  0 siblings, 1 reply; 4+ messages in thread
From: mailsagr @ 2003-09-06  0:14 UTC (permalink / raw)
  To: ecos-discuss

hello,

i have been trying to get a simple tcp client to work
with a tcp server.

The server(sitting on my linux machine) just listens
on a port say 5000. All it does is wait for a
connection from a client. When it does receive one, it
just pumps in a large amount of data (around 7 to 8
MB).

The client is a straightforward tcp client that
connects to the tcp server and tries to read in 7 to
8MB of the data pumped in by server. Now this works
when both the client and server are running on a
desktop.

But when i run the client on eCos, it can only
download 230KB of data and then the select call times
out. 

This happens every time. The timeout value is large
like 30 secs. Even if there is no select statement and
i directly use a blocking read, to read in 7 MB of
data, it just stops working after 230KB. One the
server side, it is just waiting to send more data to
client and the byte count sent to client reads 230KB.
I have fiddled around with the thread priority, buffer
size, ...., but they dont work.

Surprisingly if i put a printf statment after the read
call, and print something to the screen, then it just
goes ahead and downloads the entire contents (7MB).
What does this printf statement do that makes the
client work. I tried replacing it with fflush(stdout)
but that doesnt work. Do i need to do anything
different with my eCos configuration. I have also
observed this when i try using a libxml parser on
eCos. when i have to parse a long doc (7MB) it just
bails out in between, after parsing some amount of
data. But if i print to stdout some info after it
encounters some tag (in a callback function), then it
works just fine.

The eCos config is a standard 'net' template on a i386
HAL. It has a RAM disk and i82559 driver with FreeBSD.
I dont think it has anyting to do with FreeBSD and
82559 since it works with the printf statements.

Any help would be appreciated.

Thanks
Sagar


/* tcpclient.c
*/
int
connect(char *addr, unsigned short port)
{
	struct sockaddr_in sock_name;
  	int sock, save_errno;
	int errcode=0;

	memset(&sock_name, 0, sizeof(sock_name));
	// Set port and protocol
	sock_name.sin_family = AF_INET;
	sock_name.sin_port = htons (port);
	sock_name.sin_addr.s_addr = inet_addr(addr);  
	#ifdef __ECOS
	sock_name.sin_len = sizeof(sock_name);
	#endif

	// Make an internet socket, stream type.
	sock = socket (AF_INET, SOCK_STREAM, 0);
	if (sock < 0)
		return -1;

	// Connect the socket to the remote host.
	if ((errcode=connect (sock, (struct sockaddr
*)&sock_name, sizeof (sock_name))) < 0)
	{
		close (sock);
		return -1;
	}

 	return sock; 
}

int client_start(char *ip, unsigned short port, int
bytes_to_read)
{
	int nbytes=0, ret=0;
	double timeout = 15;
	char buff[1024];
	int fd = connect_to_one(ip, port);
	
	while(nbytes<bytes_to_read) {
		ret = read(fd, buff, sizeof(buff));
		if(ret<0) {
			return -1;
		}
		nbytes += ret;
		/*
		This is the read call that I was referring to which
removes the 230 KB
		read limit on the client side.
		*/
		printf("read=%d bytes\n");
	}
	printf("tot bytes read=%d bytes\n", nbytes);
	return nbytes;
}
	

/* File framework.c
*/


#include <stdio.h>
#include <cyg/fileio/fileio.h>
#include <network.h>

#define MAIN_THREAD_PRIORITY
CYGPKG_NET_THREAD_PRIORITY-4
#define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL +
0x20000)

static char stack[STACK_SIZE];
static cyg_thread thread_data;
static cyg_handle_t thread_handle;

#define ROOTFS "/"

int init_network(void)
{
	init_all_network_interfaces();
	
	if(eth0_up) {
		printf("eth0 is up and running ....\n");
	} else {
		printf("eth0 is not up yet.\n");
		return -1;
	}
	printf("Network initialization done.\n");

	return 0;
}

int cleanup_ecos()
{
	umount(ROOTFS);
	return 0;
}

int start_tests();

void init_ecos(cyg_addrword_t param)
{
	init_network();
	
	if(mount("", ROOTFS, "ramfs")<0) {
		printf("Error: Unable to create a Ramdisk\n");
		return;
	}
	printf("Mounted Ramdisk at %s\n", ROOTFS);

	printf("\n\n");

	//start_tests();
	client_start("192.168.0.4", 5000, 1024*1024*7);	

	cleanup_ecos();
}

void cyg_user_start(void)
{
	printf("Initializing eCos environment....\n");

	cyg_thread_create(CYGPKG_NET_THREAD_PRIORITY+2,//
Priority
                      init_ecos,                //
entry
                      0,                        //
entry parameter
                      "eCos init",              //
Name
                      &stack[0],                //
Stack
                      STACK_SIZE,               //
Size
                      &thread_handle,           //
Handle
                      &thread_data              //
Thread data structure
            );
	cyg_thread_resume(thread_handle);           // Start
it
	cyg_scheduler_start();
}



__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com

-- 
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [ECOS] socket times out, but not with printf
  2003-09-06  0:14 [ECOS] socket times out, but not with printf mailsagr
@ 2003-09-06  8:34 ` Andrew Lunn
  2003-09-06 15:06   ` mailsagr
  0 siblings, 1 reply; 4+ messages in thread
From: Andrew Lunn @ 2003-09-06  8:34 UTC (permalink / raw)
  To: mailsagr; +Cc: ecos-discuss

You code looks OK. The extra printf is probably changing the timing
somehow. Do you have assert's enabled? If not turn them on. 

Also, can you ping the device once its got into its blocked state
after 230KB. 

      Andrew


On Fri, Sep 05, 2003 at 05:14:53PM -0700, mailsagr@yahoo.com wrote:
> hello,
> 
> i have been trying to get a simple tcp client to work
> with a tcp server.
> 
> The server(sitting on my linux machine) just listens
> on a port say 5000. All it does is wait for a
> connection from a client. When it does receive one, it
> just pumps in a large amount of data (around 7 to 8
> MB).
> 
> The client is a straightforward tcp client that
> connects to the tcp server and tries to read in 7 to
> 8MB of the data pumped in by server. Now this works
> when both the client and server are running on a
> desktop.
> 
> But when i run the client on eCos, it can only
> download 230KB of data and then the select call times
> out. 
> 
> This happens every time. The timeout value is large
> like 30 secs. Even if there is no select statement and
> i directly use a blocking read, to read in 7 MB of
> data, it just stops working after 230KB. One the
> server side, it is just waiting to send more data to
> client and the byte count sent to client reads 230KB.
> I have fiddled around with the thread priority, buffer
> size, ...., but they dont work.
> 
> Surprisingly if i put a printf statment after the read
> call, and print something to the screen, then it just
> goes ahead and downloads the entire contents (7MB).
> What does this printf statement do that makes the
> client work. I tried replacing it with fflush(stdout)
> but that doesnt work. Do i need to do anything
> different with my eCos configuration. I have also
> observed this when i try using a libxml parser on
> eCos. when i have to parse a long doc (7MB) it just
> bails out in between, after parsing some amount of
> data. But if i print to stdout some info after it
> encounters some tag (in a callback function), then it
> works just fine.
> 
> The eCos config is a standard 'net' template on a i386
> HAL. It has a RAM disk and i82559 driver with FreeBSD.
> I dont think it has anyting to do with FreeBSD and
> 82559 since it works with the printf statements.
> 
> Any help would be appreciated.
> 
> Thanks
> Sagar
> 
> 
> /* tcpclient.c
> */
> int
> connect(char *addr, unsigned short port)
> {
> 	struct sockaddr_in sock_name;
>   	int sock, save_errno;
> 	int errcode=0;
> 
> 	memset(&sock_name, 0, sizeof(sock_name));
> 	// Set port and protocol
> 	sock_name.sin_family = AF_INET;
> 	sock_name.sin_port = htons (port);
> 	sock_name.sin_addr.s_addr = inet_addr(addr);  
> 	#ifdef __ECOS
> 	sock_name.sin_len = sizeof(sock_name);
> 	#endif
> 
> 	// Make an internet socket, stream type.
> 	sock = socket (AF_INET, SOCK_STREAM, 0);
> 	if (sock < 0)
> 		return -1;
> 
> 	// Connect the socket to the remote host.
> 	if ((errcode=connect (sock, (struct sockaddr
> *)&sock_name, sizeof (sock_name))) < 0)
> 	{
> 		close (sock);
> 		return -1;
> 	}
> 
>  	return sock; 
> }
> 
> int client_start(char *ip, unsigned short port, int
> bytes_to_read)
> {
> 	int nbytes=0, ret=0;
> 	double timeout = 15;
> 	char buff[1024];
> 	int fd = connect_to_one(ip, port);
> 	
> 	while(nbytes<bytes_to_read) {
> 		ret = read(fd, buff, sizeof(buff));
> 		if(ret<0) {
> 			return -1;
> 		}
> 		nbytes += ret;
> 		/*
> 		This is the read call that I was referring to which
> removes the 230 KB
> 		read limit on the client side.
> 		*/
> 		printf("read=%d bytes\n");
> 	}
> 	printf("tot bytes read=%d bytes\n", nbytes);
> 	return nbytes;
> }
> 	
> 
> /* File framework.c
> */
> 
> 
> #include <stdio.h>
> #include <cyg/fileio/fileio.h>
> #include <network.h>
> 
> #define MAIN_THREAD_PRIORITY
> CYGPKG_NET_THREAD_PRIORITY-4
> #define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL +
> 0x20000)
> 
> static char stack[STACK_SIZE];
> static cyg_thread thread_data;
> static cyg_handle_t thread_handle;
> 
> #define ROOTFS "/"
> 
> int init_network(void)
> {
> 	init_all_network_interfaces();
> 	
> 	if(eth0_up) {
> 		printf("eth0 is up and running ....\n");
> 	} else {
> 		printf("eth0 is not up yet.\n");
> 		return -1;
> 	}
> 	printf("Network initialization done.\n");
> 
> 	return 0;
> }
> 
> int cleanup_ecos()
> {
> 	umount(ROOTFS);
> 	return 0;
> }
> 
> int start_tests();
> 
> void init_ecos(cyg_addrword_t param)
> {
> 	init_network();
> 	
> 	if(mount("", ROOTFS, "ramfs")<0) {
> 		printf("Error: Unable to create a Ramdisk\n");
> 		return;
> 	}
> 	printf("Mounted Ramdisk at %s\n", ROOTFS);
> 
> 	printf("\n\n");
> 
> 	//start_tests();
> 	client_start("192.168.0.4", 5000, 1024*1024*7);	
> 
> 	cleanup_ecos();
> }
> 
> void cyg_user_start(void)
> {
> 	printf("Initializing eCos environment....\n");
> 
> 	cyg_thread_create(CYGPKG_NET_THREAD_PRIORITY+2,//
> Priority
>                       init_ecos,                //
> entry
>                       0,                        //
> entry parameter
>                       "eCos init",              //
> Name
>                       &stack[0],                //
> Stack
>                       STACK_SIZE,               //
> Size
>                       &thread_handle,           //
> Handle
>                       &thread_data              //
> Thread data structure
>             );
> 	cyg_thread_resume(thread_handle);           // Start
> it
> 	cyg_scheduler_start();
> }
> 
> 
> 
> __________________________________
> Do you Yahoo!?
> Yahoo! SiteBuilder - Free, easy-to-use web site design software
> http://sitebuilder.yahoo.com
> 
> -- 
> Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
> and search the list archive: http://sources.redhat.com/ml/ecos-discuss
> 

-- 
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [ECOS] socket times out, but not with printf
  2003-09-06  8:34 ` Andrew Lunn
@ 2003-09-06 15:06   ` mailsagr
  2003-09-06 15:14     ` Andrew Lunn
  0 siblings, 1 reply; 4+ messages in thread
From: mailsagr @ 2003-09-06 15:06 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: ecos-discuss


thanks Andrew, for the mail.

i turned on Asserts now. and when i boot up this is
what it gives me:
[cyg_net_init] Init: mbinit(0x00000000)
[cyg_net_init] Init: cyg_net_init_devs(0x00000000)
Init device 'i82559_eth0'
ASSERT FAIL: <1>intr.cxx[619]static void
Cyg_Interrupt::mask_interrupt() Invalid vector
ASSERT FAIL: intr.cxx            [ 619] static void
Cyg_Interrupt::mask_interrupt()
                                 Invalid vector

Earlier, before turning on asserts, after the 230KB
limit this is what i have observed on ethereal. The
tcp client on eCos keeps sending tcp pkts with payload
= 0 bytes. it keeps on sending these pkts with the
same sequence no. hoping to get ACKs from the server.
The server sees these SEQ pkts and sends the
approprite ACK. However eCos client never seems to see
these ACKs so it continues to send the same SEQ nos
again and again for a long time. In the mean time the
select call on the client times out.

For some reason(probably due to the bogus intr vector)
the client tcp stack doesnt seems to be receiving data
from driver after this initial read of 230 KB. And the
printf seems to be doing something that makes it work.
The printf is actually printing to my telnet session.
And Redboot is taking care of that. 

Redboot has ip 192.168.0.10 and my eCos app has an ip
192.168.0.100 (both configured statically though
configtool). 

How do I resolve this now.

Appreciate your help. Thanks again
Sagar

--- Andrew Lunn <andrew@lunn.ch> wrote:
> You code looks OK. The extra printf is probably
> changing the timing
> somehow. Do you have assert's enabled? If not turn
> them on. 
> 
> Also, can you ping the device once its got into its
> blocked state
> after 230KB. 
> 
>       Andrew
> 
> 
> On Fri, Sep 05, 2003 at 05:14:53PM -0700,
> mailsagr@yahoo.com wrote:
> > hello,
> > 
> > i have been trying to get a simple tcp client to
> work
> > with a tcp server.
> > 
> > The server(sitting on my linux machine) just
> listens
> > on a port say 5000. All it does is wait for a
> > connection from a client. When it does receive
> one, it
> > just pumps in a large amount of data (around 7 to
> 8
> > MB).
> > 
> > The client is a straightforward tcp client that
> > connects to the tcp server and tries to read in 7
> to
> > 8MB of the data pumped in by server. Now this
> works
> > when both the client and server are running on a
> > desktop.
> > 
> > But when i run the client on eCos, it can only
> > download 230KB of data and then the select call
> times
> > out. 
> > 
> > This happens every time. The timeout value is
> large
> > like 30 secs. Even if there is no select statement
> and
> > i directly use a blocking read, to read in 7 MB of
> > data, it just stops working after 230KB. One the
> > server side, it is just waiting to send more data
> to
> > client and the byte count sent to client reads
> 230KB.
> > I have fiddled around with the thread priority,
> buffer
> > size, ...., but they dont work.
> > 
> > Surprisingly if i put a printf statment after the
> read
> > call, and print something to the screen, then it
> just
> > goes ahead and downloads the entire contents
> (7MB).
> > What does this printf statement do that makes the
> > client work. I tried replacing it with
> fflush(stdout)
> > but that doesnt work. Do i need to do anything
> > different with my eCos configuration. I have also
> > observed this when i try using a libxml parser on
> > eCos. when i have to parse a long doc (7MB) it
> just
> > bails out in between, after parsing some amount of
> > data. But if i print to stdout some info after it
> > encounters some tag (in a callback function), then
> it
> > works just fine.
> > 
> > The eCos config is a standard 'net' template on a
> i386
> > HAL. It has a RAM disk and i82559 driver with
> FreeBSD.
> > I dont think it has anyting to do with FreeBSD and
> > 82559 since it works with the printf statements.
> > 
> > Any help would be appreciated.
> > 
> > Thanks
> > Sagar
> > 
> > 
> > /* tcpclient.c
> > */
> > int
> > connect(char *addr, unsigned short port)
> > {
> > 	struct sockaddr_in sock_name;
> >   	int sock, save_errno;
> > 	int errcode=0;
> > 
> > 	memset(&sock_name, 0, sizeof(sock_name));
> > 	// Set port and protocol
> > 	sock_name.sin_family = AF_INET;
> > 	sock_name.sin_port = htons (port);
> > 	sock_name.sin_addr.s_addr = inet_addr(addr);  
> > 	#ifdef __ECOS
> > 	sock_name.sin_len = sizeof(sock_name);
> > 	#endif
> > 
> > 	// Make an internet socket, stream type.
> > 	sock = socket (AF_INET, SOCK_STREAM, 0);
> > 	if (sock < 0)
> > 		return -1;
> > 
> > 	// Connect the socket to the remote host.
> > 	if ((errcode=connect (sock, (struct sockaddr
> > *)&sock_name, sizeof (sock_name))) < 0)
> > 	{
> > 		close (sock);
> > 		return -1;
> > 	}
> > 
> >  	return sock; 
> > }
> > 
> > int client_start(char *ip, unsigned short port,
> int
> > bytes_to_read)
> > {
> > 	int nbytes=0, ret=0;
> > 	double timeout = 15;
> > 	char buff[1024];
> > 	int fd = connect_to_one(ip, port);
> > 	
> > 	while(nbytes<bytes_to_read) {
> > 		ret = read(fd, buff, sizeof(buff));
> > 		if(ret<0) {
> > 			return -1;
> > 		}
> > 		nbytes += ret;
> > 		/*
> > 		This is the read call that I was referring to
> which
> > removes the 230 KB
> > 		read limit on the client side.
> > 		*/
> > 		printf("read=%d bytes\n");
> > 	}
> > 	printf("tot bytes read=%d bytes\n", nbytes);
> > 	return nbytes;
> > }
> > 	
> > 
> > /* File framework.c
> > */
> > 
> > 
> > #include <stdio.h>
> > #include <cyg/fileio/fileio.h>
> > #include <network.h>
> > 
> > #define MAIN_THREAD_PRIORITY
> > CYGPKG_NET_THREAD_PRIORITY-4
> > #define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL
> +
> > 0x20000)
> > 
> > static char stack[STACK_SIZE];
> > static cyg_thread thread_data;
> > static cyg_handle_t thread_handle;
> > 
> > #define ROOTFS "/"
> > 
> > int init_network(void)
> > {
> > 	init_all_network_interfaces();
> > 	
> > 	if(eth0_up) {
> > 		printf("eth0 is up and running ....\n");
> > 	} else {
> > 		printf("eth0 is not up yet.\n");
> > 		return -1;
> > 	}
> > 	printf("Network initialization done.\n");
> > 
> > 	return 0;
> > }
> > 
> > int cleanup_ecos()
> > {
> > 	umount(ROOTFS);
> > 	return 0;
> > }
> > 
> > int start_tests();
> > 
> > void init_ecos(cyg_addrword_t param)
> > {
> > 	init_network();
> > 	
> > 	if(mount("", ROOTFS, "ramfs")<0) {
> > 		printf("Error: Unable to create a Ramdisk\n");
> > 		return;
> 
=== message truncated ===


__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com

-- 
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [ECOS] socket times out, but not with printf
  2003-09-06 15:06   ` mailsagr
@ 2003-09-06 15:14     ` Andrew Lunn
  0 siblings, 0 replies; 4+ messages in thread
From: Andrew Lunn @ 2003-09-06 15:14 UTC (permalink / raw)
  To: mailsagr; +Cc: Andrew Lunn, ecos-discuss

On Sat, Sep 06, 2003 at 08:06:35AM -0700, mailsagr@yahoo.com wrote:
> 
> thanks Andrew, for the mail.
> 
> i turned on Asserts now. and when i boot up this is
> what it gives me:
> [cyg_net_init] Init: mbinit(0x00000000)
> [cyg_net_init] Init: cyg_net_init_devs(0x00000000)
> Init device 'i82559_eth0'
> ASSERT FAIL: <1>intr.cxx[619]static void
> Cyg_Interrupt::mask_interrupt() Invalid vector
> ASSERT FAIL: intr.cxx            [ 619] static void
> Cyg_Interrupt::mask_interrupt()
>                                  Invalid vector
> 
> Earlier, before turning on asserts, after the 230KB
> limit this is what i have observed on ethereal. The
> tcp client on eCos keeps sending tcp pkts with payload
> = 0 bytes. it keeps on sending these pkts with the
> same sequence no. hoping to get ACKs from the server.
> The server sees these SEQ pkts and sends the
> approprite ACK. However eCos client never seems to see
> these ACKs so it continues to send the same SEQ nos
> again and again for a long time. In the mean time the
> select call on the client times out.
> 
> For some reason(probably due to the bogus intr vector)
> the client tcp stack doesnt seems to be receiving data
> from driver after this initial read of 230 KB. And the
> printf seems to be doing something that makes it work.
> The printf is actually printing to my telnet session.
> And Redboot is taking care of that. 

That explains a lot. Redboot does polled IO on the ethernet
driver. When it sends/receives something it will also flush out any
packets waiting to the sent/received but have not yet raised an
interrupt. Now the assert suggests the interrupt setup code is wrong
for your platform, so the i82559 is not causing any interrupts.....

Debug that assert failure. See what vector its trying to use and
compare it with what it should be using. My guess something is wrong
with the PCI information.... You might also want to run the test
program pci1 and see what it says.

     Andrew

-- 
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2003-09-06 15:14 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-09-06  0:14 [ECOS] socket times out, but not with printf mailsagr
2003-09-06  8:34 ` Andrew Lunn
2003-09-06 15:06   ` mailsagr
2003-09-06 15:14     ` Andrew Lunn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).