[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [lwip-users] netconn_recv blocking forever
From: |
Çağlar AKYÜZ |
Subject: |
Re: [lwip-users] netconn_recv blocking forever |
Date: |
Thu, 08 Mar 2007 16:29:13 +0200 |
User-agent: |
Mozilla Thunderbird 1.5.0.10 (Windows/20070221) |
Mateusz Plocinski wrote:
Hi,
I'm using an ARM7 FreeRTOS port of lwip. I'm trying to implement a
thread which waits for data from PC using netconn_recv. Everything
works fine in most situations (for week or longer without any
problems), but when I disconnect network cable or PC simply hangs up
without closing a connection, my lwip socket thread still sits in
netconn_recv function.
Is there any way to check if connection isnt dead while thread is
blocked in netconn_recv? I need to know in few seconds if I should
close connection because I need to quickly restart connection to my
ARM hardware (and I have only on thread so I cant open more sockets to
wait for connection).
Just don't use netconn_recv. Instead use raw api with callbacks enabled.
Then sleep in your task
with vTaskDelayUntil api of FreeRTOS. This way if something goes wrong,
you won't be blocking
forever in netconn_recv and you will have a chance to correct things up.
There is a nice code in the list illustrating the use of raw api. I'm
using this code happly with my SAM7X with FreeRTOS
installed. I searched thru the list but unable to find the link. So I'm
attaching my own modified version.
By the way, using raw api is not that much hard. I was able to migrate
my code from netconn api to raw api in hours keeping
in mind that I'm not a code guru. Just give it a try.
Regards
Caglar AKYUZ
err_t netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
/* This callback function is called when stack receives data from
the MAC
* interface(on our port of course). Then we can process this message
*/
static int settings[SETTINGS_LENGTH];
(void) arg;
if (err == ERR_OK && p != NULL)
{
/* if config_mode is not 0, then we are in configuration mode */
if( config_mode ) {
configure_device_tcp( &settings[0] , pcb , p );
} else {
/* Process message then if we are not in config mode */
process_tcp_message( &settings[0] , pcb , p );
}
/* Acknowledge stack that we have processed the message so that
it can
* inrcrease window size
,
*/
tcp_recved(pcb, p->tot_len);
/* Never forget to free a buffer! */
pbuf_free(p);
}
else
pbuf_free(p); /* Never forget to free a buffer! */
if (err == ERR_OK && p == NULL)
{
/* If we are here this means that other side has closed the
connection. */
tcp_arg(pcb, NULL);
tcp_sent(pcb, NULL);
tcp_recv(pcb, NULL);
tcp_close(pcb);
pioA_toggle_led( 1 );
/* Inform mac task that communication is closed. Otherwise, it
will immediately
* send conversion data as soon as a client arrives without
waiting the
* send commdand.
*/
comm_open = 0;
}
return ERR_OK;
}
err_t netio_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
/* When there is a connection request this function is called by the
stack */
(void) arg;
(void) err;
tcp_arg(pcb, NULL);
tcp_sent(pcb, NULL);
/* Inform stack about which function to call-back when there is data
on the line */
tcp_recv(pcb, netio_recv);
/* Hold the accepted connection pcb. This will used later when we
desire to send
* data asynchronously from the receive callback function
*/
netio_pcb = pcb;
pioA_toggle_led( 0 );
return ERR_OK;
}
struct tcp_pcb* netio_init(void)
{
/* This function initalizes the connection. We start listenin on the
desired port
* and our defined callback function to be called by the stack when
someone
* arrives
*/
struct tcp_pcb *pcb;
pcb = tcp_new();
tcp_bind(pcb, IP_ADDR_ANY, SETTINGS_PAGE[LOCAL_PORT]);
pcb = tcp_listen(pcb);
tcp_accept(pcb, netio_accept);
return pcb;
}