Hi

Yes you're probably right, that would be a better solution. What looks like happens next in the wireshark capture is that the interrupt triggered by the retransmission signals your code to read and ack the queued old packet. Then there's an ACK in packet 26 triggering another interrupt that signals your application to read the queued retransmission packet, hence the dup ack in packet 27. And so on, your application is constantly one packet behind the interrupt.

One comment though: I don't know which MCU you're on but I wouldn't assume one interrupt equals one packet. I recently fixed a bug in my application that had a similar setup (interrupt signals with counting semaphore to receive thread, which processed a number of packets equal to the counting semaphore) which didn't cover the case where a second packet is received before the ethernet interrupt has serviced the first packet. My interrupt would only hit once so the second packet was left until the next interrupt.

My solution was to simply try to fetch packets from DMA until it was empty each time my receive thread was woken.

BR /Jens


On 2014-03-20 16:21, Julien Jemine wrote:
Hi Sergio,

I've found this drop packet thing in my driver, however it doesn't seem to break there.
I've had a look at the driver code but I can't find anything...

I am a bit surprised that the ethernet interrupt just raises a flag :

static void eth_notify (ARM_ETH_MAC_EVENT event) {
  /* Send notification on RX event */
  if (event == ARM_ETH_MAC_EVENT_RX_FRAME) {
    rx_event = true;
  }
}

It seems to imply that calling ethernetif_poll in an IDLE thread will only process on packet even if multiple interrupts have been raised :

void ethernetif_poll (struct netif *netif) {
  struct ethernetif *eth = netif->state;

  if (!eth->phy_ok || eth->link == ARM_ETH_LINK_DOWN) {
    return;
  }
  if (rx_event) {
    rx_event = false;
    /* process received ethernet packet */
    ethernetif_input (netif);
  }
}

I think that an atomic counter and a while loop instead of a flag and a "if" would be more appropriate. Am I wrong ?
Could that have anything to do with my problem ?

Thanks for your help,

Julien.




2014-03-20 15:10 GMT+01:00 Sergio R. Caprile <scapr...@gmail.com <mailto:scapr...@gmail.com>>:

    Hi Julien.
    Yes, there is a TCP retransmission from your host.
    I bet that is because when the two packets come in such a close
    proximity your Ethernet driver is losing the second one. This, in
    fact,
    can be because there is a problem with the driver itself, or you
    have a
    really low-memory condition and the driver can't find enough memory to
    store the packet.
    If I would have to hunt this witch, I would start by setting a
    breakpoint on the Ethernet driver low_level_input() routine, somewhere
    around here:


    static struct pbuf *
    low_level_input(struct netif *netif)
    {
      [...]
      /* We allocate a pbuf chain of pbufs from the pool. */
      p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);

      if (p != NULL) {
            [...]
          read data into(q->payload, q->len);
        }
        acknowledge that packet has been read();
      [...]
      } else {
        drop packet();      <-------------

    It actually depends on how the one who actually wrote the driver
    wanted
    to make it difficult for you.
    Let me know how it goes.
    Cheers

    --


    _______________________________________________
    lwip-users mailing list
    lwip-users@nongnu.org <mailto:lwip-users@nongnu.org>
    https://lists.nongnu.org/mailman/listinfo/lwip-users




_______________________________________________
lwip-users mailing list
lwip-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/lwip-users

_______________________________________________
lwip-users mailing list
lwip-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/lwip-users

Reply via email to