lwip 1.4.0

This forum is dedicated to feedback, discussions about ongoing or future developments, ideas and suggestions regarding the ChibiOS projects are welcome. This forum is NOT for support.
liamstask
Posts: 34
Joined: Wed Dec 08, 2010 5:42 pm

Re: lwip 1.4.0

Post by liamstask »

Great! Thanks for taking a look - I will test against the updated version from svn and report if I find any problems.
likewise
Posts: 18
Joined: Tue Jun 14, 2011 3:43 pm

Re: lwip 1.4.0

Post by likewise »

Hi guys,

thanks for taking a good spin with lwIP and ChibiOS/RT. I'm investigating if we should drop the sys_arch layer for something better.

Oh, and thanks for the two STM32F107 board links. I didn't have to spin my own board after all :)

Regards,

Leon Woestenberg.
likewise
Posts: 18
Joined: Tue Jun 14, 2011 3:43 pm

Re: lwip 1.4.0

Post by likewise »

Hello Liam, Brian, Giovanni, others,

I have just finished adding a board and demo port of the "stm32_ethernet_wrapper" branch (thus lwIP 1.4.0-rc1) for my STM32F107/DP83848 board.

However, I get un (seemingly non backtrackable by GDB, argh) trap.

This reminded me of a bug I found last week in ST's lwIP example; there is a race condition in the start of the lwIP stack and the Ethernet interrupt handler. netif_init() already starts Ethernet reception, whereas the lwIP stack is still being brought up.
I fixed that bug by simply enabling the global Ethernet interrupt just after everything is initialized.

I just did the same for the demo, and it suddenly seems to work, i.e. I moved this from mac_ldd.c to just before the lwip_thread main loop:

/* Enable the Ethernet global interrupt */
NVICEnableVector(ETH_IRQn,
CORTEX_PRIORITY_MASK(STM32_ETH1_IRQ_PRIORITY));

However I have not found why this would actually be a problem on the ChibiOS/RT lwIP demo design; an rx event is signaled by the ISR, so who cares that lwIP is not yet waiting for that event?

So this might be a false report. Stay tuned while I sleep over it :)
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: lwip 1.4.0

Post by Giovanni »

Hi Leon,

You finally registered here too :-)

lwIP 1.4.0 has been a definite improvement in OS integration area, as you suggest there are other things that could be done in order to further improve it. I don't know if dropping the sys_arch layer is a good idea, you would still need an abstraction layer toward the underlying OS, probably it should just be improved.

In my opinion there are several areas where lwIP could be improved.

- Currently there is a lot of duplication between the OS and lwIP, both offer allocators and timers. Probably it would be a good idea to abstract those functions into the interface layer and let the OS manage those.
- Implementing a copy-less stack is problematic. In my opinion the management of pbuf chains should be delegated to the device drivers that could then implement them in an optimized way, for example making chains point to static buffers in memory that must not be freed when the chain is released.
- Lock/unlock primitives should be assumed to not be nestable, invoking OS APIs with interrupts disabled should be forbidden. It is already this way but in is not documented so you have to assume the worst case.

Giovanni
likewise
Posts: 18
Joined: Tue Jun 14, 2011 3:43 pm

Re: lwip 1.4.0

Post by likewise »

Hi Giovanni,

yes, finally, again :) Good to see ChibiOS/RT is alive and kicking.

- agreed, for another RTOS port, long ago, I skipped the sys_arch layer, I hate it, but maybe it has come to a more mature status nowadays.
- I wonder how lwIP behaves if the driver creates PBUF_REF or even PBUF_ROM references to the static receive buffer, I don't think I have seen this before.
- Agreed.

As for my bug, I tracked it down to printf->sd driver->queueing->scheduling panic, could it be there are still queue bugs lurking in stm32_ethernet_wrapper branch? I am now merging trunk with that branch for lwIP.

Cheers,

Leon.
likewise
Posts: 18
Joined: Tue Jun 14, 2011 3:43 pm

Re: lwip 1.4.0

Post by likewise »

I have described my bug in the user forum, "qwait() chDbgPanic()". It is unrelated to the lwIP project itself.
likewise
Posts: 18
Joined: Tue Jun 14, 2011 3:43 pm

Re: lwip 1.4.0

Post by likewise »

Scrap bug report, user error.

Now, to remove the copy loop in packet reception, I think PBUF_PREF will not do, as we never know when the pbuf is freed, and we need to maintain the descriptor along with the pbuf.

There is support for custom pbufs in lwIP, which can call a custom callback function when the pbuf is free()d, see code from pbuf.c:
#if LWIP_SUPPORT_CUSTOM_PBUF
/* is this a custom pbuf? */
if ((p->flags & PBUF_FLAG_IS_CUSTOM) != 0) {
struct pbuf_custom *pc = (struct pbuf_custom*)p;
LWIP_ASSERT("pc->custom_free_function != NULL", pc->custom_free_function != NULL);
pc->custom_free_function(p);
} else
#endif /* LWIP_SUPPORT_CUSTOM_PBUF */

Support for that is currently only enabled in lwIP for ip_frag.c (IP packet fragmentation), but we can ask lwIP developerslater to allow to enable this type of pbuf via the lwipopts.h. For now, this will do in pbuf.h:
#define LWIP_SUPPORT_CUSTOM_PBUF 1 // was: (IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF)

Then, we define a static set of pbufs, one for each Rx descriptor of the DMA engine.

struct pbuf_mine {
struct pbuf_custom;
MACReceiveDescriptor rd;
} rx_pbufs[4];

When a packet arrives, we do not copy it, but use this:

pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, struct pbuf_custom *p,
void *payload_mem, u16_t payload_mem_len);

and set p->custom_free_function = pbuf_mine_free;

the lwipthread does something like this:

struct pbuf_mine {
struct pbuf_custom pc;
MACReceiveDescriptor rd;
} rx_pbufs[4];


if (macWaitReceiveDescriptor(&ETH1, &rd, TIME_IMMEDIATE) == RDY_OK) {
len = (u16_t)rd.size;
/* determine which rx_pbuf matches with the descriptor rd , TODO */
int i = 0;

msg_t rc = max_lld_get_receive_descriptor(&ETH1, &rd);
if (rc == RDY_OK)
{
p = pbuf_alloced_custom(PBUF_RAW, MAC_BUFFERS_SIZE, PBUF_REF, (struct pbuf_custom *)&rx_pbufs[i], p->payload, MAC_BUFFERS_SIZE);
pm = p;
p->payload = (uint8_t *)(rdp->physdesc->Buffer1Addr) +
rdp.offset;
p->len = p->tot_len = rdp.size;
/* we need to defer this until the point where our pbuf_custom_free() is called */
//macReleaseReceiveDescriptor(&rd);
pm->pc.custom_free_function = pbuf_mine_free;

If anyone wants to pick this up, please do so, as I have only limited time to work on this.

Leon.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: lwip 1.4.0

Post by Giovanni »

Well, what is really needed is support for "physical" buffers that must not be handled like normal buffers, the custom free() function would work in order to inform the driver that the buffer is no more required, I would also associate a driver-defined parameter for the free() function, just in case the driver needs to keep an extra pointer (for an internal descriptor for example).

It would not be a bad idea to bring this to their attention.

Giovanni
Post Reply