LWIP on LPC4357, stuck in lpc_low_level_output

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LWIP on LPC4357, stuck in lpc_low_level_output

1,309 Views
mj7man
Contributor I

Hi, I'm stuck here with the TX side of my app. It appears I am running out of descriptors. I've already modified the famous loop that is problematic as follows: 

(in lpc18xx_43xx_emac)

 volatile u32_t check = lpc_tx_ready(netif);

while(dn > check)
#if NO_SYS == 0
{ xSemaphoreTake(lpc_netifdata->xTXDCountSem, 0);}
#else
{
  lpc_tx_reclaim(netif);
  check = lpc_tx_ready(netif);
}

The strange thing is this is only happening when I'm sending a payload that is following a full packet. So if I'm sending anything under 1460 bytes I can do as many transmissions as I want. When I send 1460 followed by a shorter packet of say 500 then it gets stuck. It is very strange. I'll include the mechanisms I'm using to queue the data.

send_buffer(const void* pvBuffer, uint32 uiNumBytes)

struct pbuf *ptr;
ptr = pbuf_alloc(PBUF_TRANSPORT, uiNumBytes , PBUF_RAM);
pbuf_take(ptr, pvBuffer, uiNumBytes);
// std::memcpy(ptr->payload, pvBuffer, uiNumBytes);
// ptr->len = ptr->tot_len = uiNumBytes;
return AddDataAndSend(ptr);

and

if(mxDataSet.out_pb == NULL || mxDataSet.out_pb->tot_len == 0)
{
// load data to out_pb
if(mxDataSet.out_pb->tot_len == 0)
{
pbuf_free(mxDataSet.out_pb);
}
mxDataSet.out_pb = ptr;
}else
{
pbuf_cat(mxDataSet.out_pb, ptr);
}
return tcp_client_send_data_set(&mxDataSet);

which is implemented as follows

static void tcp_client_raw_send(struct EStreamDataSet* data_set)
{
struct pbuf *ptr;
err_t wr_err = ERR_OK;

while ((wr_err == ERR_OK) && (data_set->out_pb != NULL) && (data_set->out_pb->len <= tcp_sndbuf(data_set->pcb)))
{
ptr = data_set->out_pb;
/* enqueue data for transmission */
wr_err = tcp_write(data_set->pcb, ptr->payload, ptr->len, 1);
if (wr_err == ERR_OK) {
/* continue with next pbuf in chain (if any) */
data_set->out_pb = ptr->next;
if(data_set->out_pb != NULL) {
/* new reference! */
pbuf_ref(data_set->out_pb);
}
/* chop first pbuf from chain */
pbuf_free(ptr);
} else if(wr_err == ERR_MEM) {
/* we are low on memory, try later / harder, defer to poll */
data_set->out_pb = ptr;
} else {
/* other problem ?? */
}
}
}

and 

static err_t tcp_client_raw_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
{
struct EStreamDataSet *data_set;
data_set = (struct EStreamDataSet *)arg;

LWIP_UNUSED_ARG(len);

if(data_set->out_pb != NULL)
{
/* still got pbufs to send */
tcp_sent(tpcb, tcp_client_raw_sent);
tcp_client_raw_send(data_set);
} else
{
/* no more pbufs to send */
}
return ERR_OK;
}

Do you think I'm experiencing underflow problems? Or is this a different issue entirely? 

Note the payloads are getting queued in seperate calls to the send function, the first with a full buffer 1460 the second with an amount less than that. In this instance it seems that second packets descriptor is not clearing, and after 4 of these sequences of 2 (the number of descriptors I have) I get stuck in an infinite loop in emac.

oh and just in case, here's my poll

static err_t
tcp_client_raw_poll(void *arg, struct tcp_pcb *tpcb)
{
err_t ret_err;
struct EStreamDataSet *data_set;
data_set = (struct EStreamDataSet *)arg;

if (data_set != NULL)
{
if ((data_set->out_pb != NULL) && (data_set->out_pb->tot_len > 0))
{
/* there is a remaining pbuf (chain) */
tcp_client_raw_send(data_set);
} else
{
/* no remaining pbuf (chain) */
// TODO: what needs to happen here?
if (data_set->out_pb != NULL)
{
// Free the buffer.
pbuf_free(data_set->out_pb);
}
}
ret_err = ERR_OK;
} else
{
/* nothing to be done */
// tcp_abort(tpcb);
ret_err = ERR_ABRT;
}
return ret_err;
}

0 Kudos
4 Replies

891 Views
jean-marcrouxel
Contributor I

Hi,

I think I have the same type of problems (not with LWIP but with KEIL-MDK and a LPC4337)..

After a first send of 1440 bytes, the second send of the rest of the frame (about 200 bytes) may fail.

I have a bit TX Underflow set in the DMA_STAT register of the EMAC, and I must reset the EMAC to have TCP transmissions again.

Did you find a solution to your problem ?

Jean-Marc

0 Kudos

891 Views
mj7man
Contributor I

Yes, I am using WireShark to see the network traffic. I can confirm the same problem exists in the ethernet tcp echo raw demo, running on external memory.

0 Kudos

891 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Mitchell Jones,

I find that there are some lwip demos in the lpcopen_2_20_keil_iar_keil_mcb_4357, didn't these demo you run?
Have a great day,
TIC

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

891 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Mitchell Jones ,

Thank you for your interest in NXP Semiconductor products and 
the opportunity to serve you.
I was wondering if you can tell me which code you testing, and I also wonder whether you use the wireshark to testing.
Have a great day,

TIC

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos