Problem with lwip_select under Nucleus

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Problem with lwip_select under Nucleus

brivero

Hello again.

I had a look at the points you mentioned to me:

First of all, I have checked that MSG_DONTWAIT in the flags to the recv operation, and O_NONBLOCK to the socket options are both set to zero. In fact, both flag fields are completely zero. So that the socket should be blocking, am I right?

>Take a look at the lwip_recvfrom() function.  Can you check the following when you call it by adding some extra debugging:
> - that sock->lastdata is NULL.

OK, it is null

> - that buf returned by netconn_recv() is NULL.

It is null too.

>If that is the case, take a look at netconn_recv().  This can return NULL for all sorts of reasons.  Add debugging (e.g. a printf) to each one and >see which case is failing.


Next, I specify the failing case, which shows the reason for which the function returns NULL.

struct netbuf *
netconn_recv(struct netconn *conn)
{

...
   
  if (conn == NULL) {
    return NULL;
  }
 
  if (conn->recvmbox == SYS_MBOX_NULL) {
    conn->err = ERR_CONN;
    return NULL;
  }

  if (conn->err != ERR_OK) {
    return NULL;
  }

  if (conn->type == NETCONN_TCP) {
    if (conn->pcb.tcp->state == LISTEN) {
      conn->err = ERR_CONN;
      return NULL;
    }

    buf = memp_malloc(MEMP_NETBUF);

    if (buf == NULL) {
      conn->err = ERR_MEM;
      return NULL;
    }
   
    sys_mbox_fetch(conn->recvmbox, (void **)&p);

    if (p != NULL)
    {
        len = p->tot_len;
        conn->recv_avail -= len;
    }
    else                                                                        <<<<<<<<<<<<<<<<<<<<<<<<< IT GETS INTO THIS ELSE
        len = 0;
            printf("\n Entra en el ELSE, Chkp1\n");
   
    /* Register event with callback */
      if (conn->callback)
        (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, len);
            printf("\n Entra en el Callback, Chkp2\n");

    /* If we are closed, we indicate that we no longer wish to receive
       data by setting conn->recvmbox to SYS_MBOX_NULL. */
    if (p == NULL) {                                                        <<<<<<<<<<<<<<<<<<<<<<<<< IT GOES INTO THIS IF (p==NULL)
      memp_free(MEMP_NETBUF, buf);
      sys_mbox_free(conn->recvmbox);
      conn->recvmbox = SYS_MBOX_NULL;
      return NULL;                                                        <<<<<<<<<<<<<<<<<<<<<<<<< RETURNS NULL
    }

....
....
....

  return buf;
}

The problem seems to be that it is receiving that null p. I would thank any advice.


Thank you very much for your help and for using your time for this purpose.

Best regards,

Borja.

_______________________________________________
lwip-users mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-users
Reply | Threaded
Open this post in threaded view
|

RE : Problem with lwip_select under Nucleus

Frédéric BERNON
Message
Hi,
 
You should receive the NULL because in api_msg.c, the err_tcp function is called. You should add a printf to check that. If it's not the case, the problem could be your sys_arch.c implementation...
 
Good luck...
 
 
====================================
Frédéric BERNON
HYMATOM SA
Chef de projet informatique
Microsoft Certified Professional
Tél. : +33 (0)4-67-87-61-10
Fax. : +33 (0)4-67-70-85-44
Email : [hidden email]r
Web Site : http://www.hymatom.fr
====================================
P Avant d'imprimer, penser à l'environnement
 
-----Message d'origine-----
De : lwip-users-bounces+frederic.bernon=[hidden email] [mailto:lwip-users-bounces+frederic.bernon=[hidden email]] De la part de [hidden email]
Envoyé : lundi 28 mai 2007 17:06
À : [hidden email]
Objet : [lwip-users] Problem with lwip_select under Nucleus


Hello again.

I had a look at the points you mentioned to me:

First of all, I have checked that MSG_DONTWAIT in the flags to the recv operation, and O_NONBLOCK to the socket options are both set to zero. In fact, both flag fields are completely zero. So that the socket should be blocking, am I right?

>Take a look at the lwip_recvfrom() function.  Can you check the following when you call it by adding some extra debugging:
> - that sock->lastdata is NULL.

OK, it is null

> - that buf returned by netconn_recv() is NULL.

It is null too.

>If that is the case, take a look at netconn_recv().  This can return NULL for all sorts of reasons.  Add debugging (e.g. a printf) to each one and >see which case is failing.


Next, I specify the failing case, which shows the reason for which the function returns NULL.

struct netbuf *
netconn_recv(struct netconn *conn)
{

...
   
  if (conn == NULL) {
    return NULL;
  }
 
  if (conn->recvmbox == SYS_MBOX_NULL) {
    conn->err = ERR_CONN;
    return NULL;
  }

  if (conn->err != ERR_OK) {
    return NULL;
  }

  if (conn->type == NETCONN_TCP) {
    if (conn->pcb.tcp->state == LISTEN) {
      conn->err = ERR_CONN;
      return NULL;
    }

    buf = memp_malloc(MEMP_NETBUF);

    if (buf == NULL) {
      conn->err = ERR_MEM;
      return NULL;
    }
   
    sys_mbox_fetch(conn->recvmbox, (void **)&p);

    if (p != NULL)
    {
        len = p->tot_len;
        conn->recv_avail -= len;
    }
    else                                                                        <<<<<<<<<<<<<<<<<<<<<<<<< IT GETS INTO THIS ELSE
        len = 0;
            printf("\n Entra en el ELSE, Chkp1\n");
   
    /* Register event with callback */
      if (conn->callback)
        (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, len);
            printf("\n Entra en el Callback, Chkp2\n");

    /* If we are closed, we indicate that we no longer wish to receive
       data by setting conn->recvmbox to SYS_MBOX_NULL. */
    if (p == NULL) {                                                        <<<<<<<<<<<<<<<<<<<<<<<<< IT GOES INTO THIS IF (p==NULL)
      memp_free(MEMP_NETBUF, buf);
      sys_mbox_free(conn->recvmbox);
      conn->recvmbox = SYS_MBOX_NULL;
      return NULL;                                                        <<<<<<<<<<<<<<<<<<<<<<<<< RETURNS NULL
    }

....
....
....

  return buf;
}

The problem seems to be that it is receiving that null p. I would thank any advice.


Thank you very much for your help and for using your time for this purpose.

Best regards,

Borja.

_______________________________________________
lwip-users mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-users

=?iso-8859-1?Q?Fr=E9d=E9ric_BERNON=2Evcf?= (810 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Problem with lwip_select under Nucleus

Kieran Mansley
In reply to this post by brivero
On Mon, 2007-05-28 at 17:06 +0200, [hidden email] wrote:

> The problem seems to be that it is receiving that null p. I would
> thank any advice.

OK.  That leaves two possibilities:
 - someone has posted a NULL message to the mbox (which is used I think
to signify that a connection has been closed) or there's a problem in
the mbox code that means it's returning NULL when in fact there is
nothing there.  I think some of the mbox code is defined by the port.
I'd suggest this is a good place to look.

Kieran



_______________________________________________
lwip-users mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-users
Reply | Threaded
Open this post in threaded view
|

TCP Window and Memory Allocation

Caglar Akyuz-2
Hi,

When I was playing with my lwipopts.h file, I realized that increasing
TCP_WND size does not effect my memory allocation. Is this the case?

If it is, then what should I do to assure correct operation for the
stack? I think I should adjust my memory allocation accordingly, but I
don't know what should be the policy. How much memory should I allocate
for a given size of TCP Window?

Excuse me if I'm asking something trivial but I'm having hard-time
understanding lwIP's memory allocation scheme on my embedded system.

Kind Regards
Caglar Akyuz

P.S: I'm attaching my options file for convenience.


=======================================================================================


#ifndef __LWIPOPTS_H__
#define __LWIPOPTS_H__

#define LWIP_NOASSERT 1 // To suppress some errors for now (no debug output)
#define SYS_LIGHTWEIGHT_PROT            1

#define TCPIP_THREAD_PRIO 3

/* ---------- Memory options ---------- */
/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
   lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
   byte alignment -> define MEM_ALIGNMENT to 2. */
#define MEM_ALIGNMENT           4

/* MEM_SIZE: the size of the heap memory. If the application will send
a lot of data that needs to be copied, this should be set high. */
#define MEM_SIZE                2000

/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
   sends a lot of data out of ROM (or other static memory), this
   should be set high. */
#define MEMP_NUM_PBUF           5
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
   per active UDP "connection". */
#define MEMP_NUM_UDP_PCB        4
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
   connections. */
#define MEMP_NUM_TCP_PCB        10
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
   connections. */
#define MEMP_NUM_TCP_PCB_LISTEN 8
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
   segments. */
#define MEMP_NUM_TCP_SEG        8
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
   timeouts. */
#define MEMP_NUM_SYS_TIMEOUT    3


/* The following four are used only with the sequential API and can be
   set to 0 if the application only will use the raw API. */
/* MEMP_NUM_NETBUF: the number of struct netbufs. */
#define MEMP_NUM_NETBUF         4
/* MEMP_NUM_NETCONN: the number of struct netconns. */
#define MEMP_NUM_NETCONN        4
/* MEMP_NUM_APIMSG: the number of struct api_msg, used for
   communication between the TCP/IP stack and the sequential
   programs. */
#define MEMP_NUM_API_MSG        8
/* MEMP_NUM_TCPIPMSG: the number of struct tcpip_msg, which is used
   for sequential API communication and incoming packets. Used in
   src/api/tcpip.c. */
#define MEMP_NUM_TCPIP_MSG      8

/* These two control is reclaimer functions should be compiled
   in. Should always be turned on (1). */
#define MEM_RECLAIM             1
#define MEMP_RECLAIM            1

/* ---------- Pbuf options ---------- */
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
#define PBUF_POOL_SIZE          8

/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
#define PBUF_POOL_BUFSIZE       2048

/* PBUF_LINK_HLEN: the number of bytes that should be allocated for a
   link level header. */
#define PBUF_LINK_HLEN          16

/* ---------- TCP options ---------- */
#define LWIP_TCP                1
#define TCP_TTL                 255

/* Controls if TCP should queue segments that arrive out of
   order. Define to 0 if your device is low on memory. */
#define TCP_QUEUE_OOSEQ         1

/* TCP Maximum segment size. */
#define TCP_MSS                 1490

/* TCP sender buffer space (bytes). */
#define TCP_SND_BUF             4 * TCP_MSS

/* TCP sender buffer space (pbufs). This must be at least = 2 *
   TCP_SND_BUF/TCP_MSS for things to work. */
#define TCP_SND_QUEUELEN        6 * TCP_SND_BUF/TCP_MSS

/* TCP receive window. */
#define TCP_WND                 10000

/* Maximum number of retransmissions of data segments. */
#define TCP_MAXRTX              12

/* Maximum number of retransmissions of SYN segments. */
#define TCP_SYNMAXRTX           4

/* ---------- ARP options ---------- */
#define ARP_TABLE_SIZE 10
#define ARP_QUEUEING 1

/* ---------- IP options ---------- */
/* Define IP_FORWARD to 1 if you wish to have the ability to forward
   IP packets across network interfaces. If you are going to run lwIP
   on a device with only one network interface, define this to 0. */
#define IP_FORWARD              1

/* If defined to 1, IP options are allowed (but not parsed). If
   defined to 0, all packets with IP options are dropped. */
#define IP_OPTIONS              1

/* ---------- ICMP options ---------- */
#define ICMP_TTL                255


/* ---------- DHCP options ---------- */
/* Define LWIP_DHCP to 1 if you want DHCP configuration of
   interfaces. DHCP is not implemented in lwIP 0.5.1, however, so
   turning this on does currently not work. */
#define LWIP_DHCP               0

/* 1 if you want to do an ARP check on the offered address
   (recommended). */
#define DHCP_DOES_ARP_CHECK     1

/* ---------- UDP options ---------- */
#define LWIP_UDP                1
#define UDP_TTL                 255


/* ---------- Statistics options ---------- */
#define STATS

#ifdef STATS
#define LINK_STATS 0
#define IP_STATS   0
#define ICMP_STATS 0
#define UDP_STATS  0
#define TCP_STATS  0
#define MEM_STATS  0
#define MEMP_STATS 0
#define PBUF_STATS 0
#define SYS_STATS  0
#endif /* STATS */

#define LWIP_PROVIDE_ERRNO 1

#endif /* __LWIPOPTS_H__ */


=======================================================================================


_______________________________________________
lwip-users mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-users
Reply | Threaded
Open this post in threaded view
|

Re: TCP Window and Memory Allocation

Kieran Mansley
On Wed, 2007-05-30 at 10:35 +0300, Caglar Akyuz wrote:
> Hi,
>
> When I was playing with my lwipopts.h file, I realized that increasing
> TCP_WND size does not effect my memory allocation. Is this the case?
>
> If it is, then what should I do to assure correct operation for the
> stack? I think I should adjust my memory allocation accordingly, but I
> don't know what should be the policy. How much memory should I allocate
> for a given size of TCP Window?

For each connection, if you're sending and receiving data, and you never
want to run out of memory for packets, you need at most the TCP_SND_BUF
and TCP_WND bytes of packet buffers (pbufs) available.  These values
don't affect how much memory is allocated directly because some users
may prefer to occasionally run out of memory for packets rather than
configure the theoretical maximum amount of memory.

Packet buffers can be allocated in a couple of different ways.  For
example, there is a fixed size pool of packet buffers whose size you can
modify using the PBUF_POOL options in lwipopts.h  Note that if a buffer
is taken from the pool the stack might not always use the full amount in
that buffer, so in general if memory is your main concern you're better
off having lots of little pool buffers rather than a few big ones.  It
can chain small ones together to make long ones if it needs to.

The stack can also allocate packet buffers dynamically from RAM, rather
than the pool, and depending on which API you're using this is perhaps
the most common method.  The amount of memory required is then not pre-
determined, but will grow and shrink as the stack's usage changes.  

Hope that helps,

Kieran



_______________________________________________
lwip-users mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-users
Reply | Threaded
Open this post in threaded view
|

Re: TCP Window and Memory Allocation

Caglar Akyuz-2
Kieran Mansley wrote:

> On Wed, 2007-05-30 at 10:35 +0300, Caglar Akyuz wrote:
>> Hi,
>>
>> When I was playing with my lwipopts.h file, I realized that increasing
>> TCP_WND size does not effect my memory allocation. Is this the case?
>>
>> If it is, then what should I do to assure correct operation for the
>> stack? I think I should adjust my memory allocation accordingly, but I
>> don't know what should be the policy. How much memory should I allocate
>> for a given size of TCP Window?
>
> For each connection, if you're sending and receiving data, and you never
> want to run out of memory for packets, you need at most the TCP_SND_BUF
> and TCP_WND bytes of packet buffers (pbufs) available.  These values
> don't affect how much memory is allocated directly because some users
> may prefer to occasionally run out of memory for packets rather than
> configure the theoretical maximum amount of memory.
>
> Packet buffers can be allocated in a couple of different ways.  For
> example, there is a fixed size pool of packet buffers whose size you can
> modify using the PBUF_POOL options in lwipopts.h  Note that if a buffer
> is taken from the pool the stack might not always use the full amount in
> that buffer, so in general if memory is your main concern you're better
> off having lots of little pool buffers rather than a few big ones.  It
> can chain small ones together to make long ones if it needs to.
>
> The stack can also allocate packet buffers dynamically from RAM, rather
> than the pool, and depending on which API you're using this is perhaps
> the most common method.  The amount of memory required is then not pre-
> determined, but will grow and shrink as the stack's usage changes.  
>
> Hope that helps,

Thank you for this valuable information. This was an excellent
description for the stack's memory usage(at least for me) and answered
all questions in my mind.

Best regards
Caglar


_______________________________________________
lwip-users mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-users