lwip-users
[Top][All Lists]
Advanced

[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




reply via email to

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