diff --git a/doc/ZeroCopyRx.c b/doc/ZeroCopyRx.c new file mode 100644 index 00000000..525b28ff --- /dev/null +++ b/doc/ZeroCopyRx.c @@ -0,0 +1,39 @@ +typedef struct my_custom_pbuf +{ + struct pbuf_custom p; + void* dma_descriptor; +} my_custom_pbuf_t; + +LWIP_MEMPOOL_DECLARE(RX_POOL, 10, sizeof(my_custom_pbuf_t), "Zero-copy RX PBUF pool"); + +void my_pbuf_free_custom(void* p) +{ + my_custom_pbuf_t* my_puf = (my_custom_pbuf_t*)p; + + LOCK_INTERRUPTS(); + free_rx_dma_descriptor(my_pbuf->dma_descriptor); + LWIP_MEMPOOL_FREE(RX_POOL, my_pbuf); + UNLOCK_INTERRUPTS(); +} + +void eth_rx_irq() +{ + dma_descriptor* dma_desc = get_RX_DMA_descriptor_from_ethernet(); + my_custom_pbuf_t* my_pbuf = (my_custom_pbuf_t*)LWIP_MEMPOOL_ALLOC(RX_POOL); + + my_pbuf->p.custom_free_function = my_pbuf_free_custom; + my_pbuf->dma_descriptor = dma_desc; + + invalidate_cpu_cache(dma_desc->rx_data, dma_desc->rx_length); + + struct pbuf* p = pbuf_alloced_custom(PBUF_RAW, + dma_desc->rx_length, + PBUF_REF, + &my_pbuf->p, + dma_desc->rx_data, + dma_desc->max_buffer_size); + + if(netif->input(p, netif) != ERR_OK) { + pbuf_free(p); + } +} diff --git a/doc/doxygen/main_page.h b/doc/doxygen/main_page.h index 0fc9bee0..efe11a64 100644 --- a/doc/doxygen/main_page.h +++ b/doc/doxygen/main_page.h @@ -100,6 +100,12 @@ * https://savannah.nongnu.org/bugs/?group=lwip */ +/** + * @page zerocopyrx Zero-copy RX + * The following code is an example for zero-copy RX ethernet driver: + * @include ZeroCopyRx.c + */ + /** * @defgroup lwip_nosys Mainloop mode ("NO_SYS") * @ingroup lwip diff --git a/src/core/pbuf.c b/src/core/pbuf.c index 2ee5efcb..804c412d 100644 --- a/src/core/pbuf.c +++ b/src/core/pbuf.c @@ -33,48 +33,7 @@ * Therefore, looping through a pbuf of a single packet, has an * loop end condition (tot_len == p->len), NOT (next == NULL). * - * Example of custom pbuf usage for zero-copy RX: - @code{.c} -typedef struct my_custom_pbuf -{ - struct pbuf_custom p; - void* dma_descriptor; -} my_custom_pbuf_t; - -LWIP_MEMPOOL_DECLARE(RX_POOL, 10, sizeof(my_custom_pbuf_t), "Zero-copy RX PBUF pool"); - -void my_pbuf_free_custom(void* p) -{ - my_custom_pbuf_t* my_puf = (my_custom_pbuf_t*)p; - - LOCK_INTERRUPTS(); - free_rx_dma_descriptor(my_pbuf->dma_descriptor); - LWIP_MEMPOOL_FREE(RX_POOL, my_pbuf); - UNLOCK_INTERRUPTS(); -} - -void eth_rx_irq() -{ - dma_descriptor* dma_desc = get_RX_DMA_descriptor_from_ethernet(); - my_custom_pbuf_t* my_pbuf = (my_custom_pbuf_t*)LWIP_MEMPOOL_ALLOC(RX_POOL); - - my_pbuf->p.custom_free_function = my_pbuf_free_custom; - my_pbuf->dma_descriptor = dma_desc; - - invalidate_cpu_cache(dma_desc->rx_data, dma_desc->rx_length); - - struct pbuf* p = pbuf_alloced_custom(PBUF_RAW, - dma_desc->rx_length, - PBUF_REF, - &my_pbuf->p, - dma_desc->rx_data, - dma_desc->max_buffer_size); - - if(netif->input(p, netif) != ERR_OK) { - pbuf_free(p); - } -} - @endcode + * Example of custom pbuf usage: @ref zerocopyrx */ /* @@ -1320,12 +1279,12 @@ pbuf_coalesce(struct pbuf *p, pbuf_layer layer) /** * @ingroup pbuf - * Allocates a new pbuf of same length (via @pbuf_alloc) and copies the source - * pbuf into this new pbuf (using @pbuf_copy). + * Allocates a new pbuf of same length (via pbuf_alloc()) and copies the source + * pbuf into this new pbuf (using pbuf_copy()). * * @param layer pbuf_layer of the new pbuf * @param type this parameter decides how and where the pbuf should be allocated - * (@see pbuf_alloc) + * (@see pbuf_alloc()) * @param p the source pbuf * * @return a new pbuf or NULL if allocation fails diff --git a/src/include/lwip/api.h b/src/include/lwip/api.h index 4db8e162..68c14373 100644 --- a/src/include/lwip/api.h +++ b/src/include/lwip/api.h @@ -276,7 +276,7 @@ struct netconn { /** This vector type is passed to @ref netconn_write_vectors_partly to send * multiple buffers at once. - * ATTENTION: This type has to directly map @ref struct iovec since one is casted + * ATTENTION: This type has to directly map struct iovec since one is casted * into the other! */ struct netvector { diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 17e92d74..8ee4f3b7 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -2733,9 +2733,9 @@ * * Options need to appended like this: * LWIP_ASSERT("dhcp option overflow", dhcp->options_out_len + option_len + 2 <= DHCP_OPTIONS_LEN); - * dhcp->msg_out->options[dhcp->options_out_len++] = ; - * dhcp->msg_out->options[dhcp->options_out_len++] = ; - * dhcp->msg_out->options[dhcp->options_out_len++] = ; + * dhcp->msg_out->options[dhcp->options_out_len++] = <option_number>; + * dhcp->msg_out->options[dhcp->options_out_len++] = <option_len>; + * dhcp->msg_out->options[dhcp->options_out_len++] = <option_bytes>; * [...] */ #ifdef __DOXYGEN__ @@ -2759,7 +2759,7 @@ * - offset: offset in pbuf where option *data* begins * Returns void * - * A nice way to get the option contents is @ref pbuf_get_contiguous: + * A nice way to get the option contents is pbuf_get_contiguous(): * u8_t buf[32]; * u8_t *ptr = (u8_t*)pbuf_get_contiguous(p, buf, sizeof(buf), LWIP_MIN(option_len, sizeof(buf)), offset); */