lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] lwip on freertos


From: Jesper Vestergaard
Subject: Re: [lwip-users] lwip on freertos
Date: Mon, 15 Jun 2009 10:07:21 +0200
User-agent: Thunderbird 2.0.0.21 (X11/20090409)

address@hidden wrote:
On Tue, 2009-06-09 at 17:12 +0200, Jesper Vestergaard wrote:
I have found the problem. ip_output_if generates a header for the packet
but there's not enough room for it and  pbuf_header(p, IP_HLEN)) fails.
To be more precise it is the if ((u8_t *)p->payload < (u8_t *)p +
SIZEOF_STRUCT_PBUF) check in pbuf_header which fails.

What can i do to fix this problem?

That is a very strange problem, the pbuf should have been allocated with
enough space to contain the IP header.

Unfortunately, this code has changed a lot recently (since 1.3.0) so
it's hard to diagnose using the current CVS head, or even establish if
the problem still exists.

To investigate, look for where the pbuf is allocated (should be in
tcp_enqueue() I think), and see what value is given for the first
argument "pbuf_layer layer".  It is this that should control the
additional space allocated for lower layer headers.

Kieran



_______________________________________________
lwip-users mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/lwip-users


Thanks

I will look into the allocation in tcp_enqueue() and also get the CVS
version for comparison.



_______________________________________________
lwip-users mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/lwip-users


I finally figured out the probem. The ethernetif driver i am using is designed for an earlier version of lwip and it seems that lwip changed the argument order in etharp_output() in version 1.3.0 so instead of putting the header in the pbuffer, lwip tried to put it in ipaddr. So it was a quick fix after i figured it out.


Now i have run into a problem with a mailbox in lwip or a queue in FreeRTOS. I have a printf in netcom accept just after the creation of the newconn pointer and after the sys_arch_mbox_fetch and they prints:
"newconn 0x2af6"
and
"mbox fetch: 0x10013540 conn: 0x2af6 recmbox: 0xf01f0046" In accept_function i have a printf just before the data is added to the mailbox and looks like this: "mailbox: 0x10013540 conn 0x10002600 recvmbox: 0x100136b0" Why isn't the data properly sent through the mailbox or queue? Here's the code from lwip: /** * Accept a new connection on a TCP listening netconn. * * @param conn the TCP listen netconn * @return the newly accepted netconn or NULL on timeout */ struct netconn * netconn_accept(struct netconn *conn) { struct netconn *newconn; printf("newconn %p\n", newconn); LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return NULL;); LWIP_ERROR("netconn_accept: invalid acceptmbox", (conn->acceptmbox != SYS_MBOX_NULL), return NULL;); #if LWIP_SO_RCVTIMEO if (sys_arch_mbox_fetch(conn->acceptmbox, (void *)&newconn, conn->recv_timeout) == SYS_ARCH_TIMEOUT) { newconn = NULL; } else #else sys_arch_mbox_fetch(conn->acceptmbox, (void *)&newconn, 0); printf("mbox fetch: %p\ conn: %p recmbox: %p\n",conn->acceptmbox, newconn, newconn->recvmbox); #endif /* LWIP_SO_RCVTIMEO*/ { /* Register event with callback */ API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0); #if TCP_LISTEN_BACKLOG if (newconn != NULL) { /* Let the stack know that we have accepted the connection. */ struct api_msg msg; msg.function = do_recv; msg.msg.conn = conn; TCPIP_APIMSG(&msg); } #endif /* TCP_LISTEN_BACKLOG */ } return newconn; }

/** * Accept callback function for TCP netconns. * Allocates a new netconn and posts that to conn->acceptmbox. * * @see tcp.h (struct tcp_pcb_listen.accept) for parameters and return value */ static err_t accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) { struct netconn *newconn; struct netconn *conn; #if API_MSG_DEBUG #if TCP_DEBUG tcp_debug_print_state(newpcb->state); #endif /* TCP_DEBUG */ #endif /* API_MSG_DEBUG */ conn = (struct netconn *)arg; LWIP_ERROR("accept_function: invalid conn->acceptmbox", conn->acceptmbox != SYS_MBOX_NULL, return ERR_VAL;); /* We have to set the callback here even though * the new socket is unknown. conn->socket is marked as -1. */ newconn = netconn_alloc(conn->type, conn->callback); if (newconn == NULL) { return ERR_MEM; } newconn->pcb.tcp = newpcb; setup_tcp(newconn); newconn->err = err; /* Register event with callback */ API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); printf("mailbox: %p conn %p recvmbox: %p\n", conn->acceptmbox, newconn, newconn->recvmbox); if (sys_mbox_trypost(conn->acceptmbox, newconn) != ERR_OK) { /* When returning != ERR_OK, the connection is aborted in tcp_process(), so do nothing here! */ newconn->pcb.tcp = NULL; netconn_free(newconn); return ERR_MEM; } return ERR_OK; }

/* Blocks the thread until a message arrives in the mailbox, but does not block the thread longer than "timeout" milliseconds (similar to the sys_arch_sem_wait() function). The "msg" argument is a result parameter that is set by the function (i.e., by doing "*msg = ptr"). The "msg" parameter maybe NULL to indicate that the message should be dropped. The return values are the same as for the sys_arch_sem_wait() function: Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a timeout. Note that a function with a similar name, sys_mbox_fetch(), is implemented by lwIP. */ u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout) { void *dummyptr; portTickType StartTime, EndTime, Elapsed; StartTime = xTaskGetTickCount(); if( msg == NULL ) { msg = &dummyptr; } if( timeout != 0 ) { if(pdTRUE == xQueueReceive( mbox, &(*msg), timeout ) ) { EndTime = xTaskGetTickCount(); Elapsed = EndTime - StartTime; if( Elapsed == 0 ) { Elapsed = 1; } return ( Elapsed ); } else // timed out blocking for message { *msg = NULL; return SYS_ARCH_TIMEOUT; } } else // block forever for a message. { while( pdTRUE != xQueueReceive( mbox, &(*msg), portMAX_DELAY ) ) // time is arbitrary { ; } EndTime = xTaskGetTickCount(); Elapsed = EndTime - StartTime; if( Elapsed == 0 ) { Elapsed = 1; } return ( Elapsed ); // return time blocked TBD test } } /*-----------------------------------------------------------------------------------*/ // Try immediately posting the "msg" to the mailbox. err_t sys_mbox_trypost(sys_mbox_t mbox, void *data) { if ( xQueueSend( mbox, &data, ( portTickType ) 1 ) == pdPASS ) { return ERR_OK; } else { return ERR_MEM; } }


||




reply via email to

[Prev in Thread] Current Thread [Next in Thread]