[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lwip-users] TCP tmr endless loop
From: |
Erik Ekman |
Subject: |
[lwip-users] TCP tmr endless loop |
Date: |
Wed, 24 Oct 2007 13:11:48 +0200 |
Hello
I am using an NXP LPC2364 ARM7 with a very simple OS (not realtime,
just a timer service and message passing between tasks). I use the GCC
toolchain and GDB+OpenOCD via a Amontec JTAG-key for
flashing/debugging.
I have lwIP up and running with no problems, and DHCP, ping and echo
services work fine. I am now trying to build an application that
connects to my pc, sends a message, and then disconnects. I use the
raw TCP api and lwIP version 1.2.0.
The problem is that sometimes it gets stuck in the tcp_slowtmr and
tcp_fasttmr, just like described earlier in the list. The
tcp_active_pcb has a pointer next which points to itself.
My task that runs lwIP:
void lwip_tick()
{
static int i = 0;
struct nosys_msg *m = nosys_getmsg();
ASSERT(m);
switch (m->type) {
case NOSYS_MSG_TIMER:
// Timer tick
if ((i & 1) == 0)
tcp_tmr();
if (i%5 == 0)
dhcp_fine_tmr();
if (i%50 == 0)
etharp_tmr();
if (i%600 == 0)
dhcp_coarse_tmr();
i++;
break;
case NOSYS_MSG_ETH_PACKET:
// Ethernet packet
#if CONFIG_LWIP_TAPIF
if (m->data == ETH_PKT_SRC_TAP) {
struct pbuf* p = (struct pbuf *) (m->ptr);
tapif_packet(&net_tap, p);
}
#endif
#if CONFIG_LWIP_ETH_23XX
if (m->data == ETH_PKT_SRC_23xx) {
struct netif* netif = (struct netif *) (m->ptr);
lpc23xxif_input(netif);
}
#endif
default:
break;
}
nosys_delmsg(m);
}
void lwip_init(struct nosys_queue *q)
{
struct ip_addr empty;
sys_init();
mem_init();
tcp_init();
udp_init();
memp_init();
pbuf_init();
netif_init();
etharp_init();
IP4_ADDR(&empty, 0, 0, 0, 0);
#if CONFIG_LWIP_TAPIF
// Init network and then start new thread that does polling
netif_add(&net_tap, &empty, &empty, &empty, &net_tap, tapif_init, ip_input);
netif_set_default(&net_tap);
dhcp_start(&net_tap);
struct tap_poll_data *data = malloc(sizeof(struct tap_poll_data));
data->q = q;
data->netif = &net_tap;
pthread_create(&tap_poll_h, 0, tap_poll, data);
#endif
#if CONFIG_LWIP_ETH_23XX
// Start interface
netif_add(&net_23, &empty, &empty, &empty, &net_23, lpc23xxif_init, ip_input);
// Set up nosys layer
eth_nosys_config(q, &net_23);
netif_set_default(&net_23);
netif_set_up(&net_23);
dhcp_start(&net_23);
#endif //CONFIG_LWIP_ETH_23XX
echo_init();
}
My sending application:
#include <nosys.h>
#include <debug.h>
#include "lwip/tcp.h"
#include <basic_signal.h>
struct signal_state
{
struct tcp_pcb *pcb;
char *data;
int size;
};
void signal_err(void *arg, err_t err);
err_t signal_connected(void *arg, struct tcp_pcb *pcb, err_t err);
err_t signal_sent(void *arg, struct tcp_pcb *pcb, u16_t len);
void signal_send(void)
{
struct nosys_msg *m;
struct signal_state *ss;
struct tcp_pcb *pcb;
struct ip_addr target;
m = nosys_getmsg();
ASSERT(m);
ss = mem_malloc(sizeof(struct signal_state));
if (ss != NULL) {
if (m->type == NOSYS_MSG_TIMER) {
ss->data = "timer";
ss->size = 5;
} else if (m->type == NOSYS_MSG_SIGNAL_STRING) {
ss->data = (char *) m->ptr;
ss->size = m->data;
} else { // Unknown message type
mem_free(ss);
return;
}
}
nosys_delmsg(m);
pcb = tcp_new();
if (pcb == NULL) {
mem_free(ss);
return;
}
ss->pcb = pcb;
tcp_arg(pcb, ss); // Register ss struct as user data for this pcb
tcp_err(pcb, signal_err); // Error callback
tcp_bind(pcb, NULL, 0); // Bind to any port on external IP
IP4_ADDR(&target, 172, 30, 81, 105);
tcp_connect(pcb, &target, 8080, signal_connected);
}
void signal_err(void *arg, err_t err)
{
struct signal_state *ss;
ss= (struct signal_state *) arg;
tcp_close(ss->pcb);
}
err_t signal_connected(void *arg, struct tcp_pcb *pcb, err_t err)
{
struct signal_state *ss;
ss= (struct signal_state *) arg;
tcp_sent(pcb, signal_sent);
// tcp_write(pcb, ss->data, ss->size, 0);
tcp_close(pcb);
return ERR_OK;
}
err_t signal_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
{
tcp_close(pcb);
return ERR_OK;
}
My lwipopts.h:
#define LWIP_TCP 1
#define LWIP_DHCP 1
#define NO_SYS 1
#define IP_REASSEMBLY 0
#define ARP_QUEUEING 0
#define ARP_TABLE_SIZE 4
#define PBUF_POOL_SIZE 25
#define MEMP_NUM_PBUF 25
#define MEMP_NUM_TCP_SEG 8
#define MEMP_NUM_TCP_PCB_LISTEN 2
#define MEMP_NUM_TCP_PCB 2
#define MEMP_NUM_UDP_PCB 1
#define MEMP_NUM_RAW_PCB 2
#define MEM_SIZE 2800
#define IP_DEBUG DBG_OFF
#define NETIF_DEBUG DBG_OFF
#define ETHARP_DEBUG DBG_OFF
#define PBUF_DEBUG DBG_OFF
#define TCP_DEBUG DBG_OFF
#define DHCP_DEBUG DBG_OFF
#define DBG_TYPES_ON 0
The lwip_tick is currently called every 100 ms, and the signal_send is
called every 10 seconds.
I get the same behaviour both on target and when emulated on Linux
with tapif, but my feeling is that it works a lot better on Linux.
Any ideas?
/Erik
- [lwip-users] TCP tmr endless loop,
Erik Ekman <=