How is the rx buffer of a custom i/o driver using esp_netif_receive() is freed?

ci4rail
Posts: 4
Joined: Thu Sep 02, 2021 1:49 pm

How is the rx buffer of a custom i/o driver using esp_netif_receive() is freed?

Postby ci4rail » Thu Sep 02, 2021 2:53 pm

Hi,
I'm writing a cdc ecm (Ethernet over USB) driver for the esp32s2 which is using the same esp-netif configuration as the native ethernet driver (ESP_NETIF_DEFAULT_ETH).
In the manual (https://docs.espressif.com/projects/esp ... river.html) is written:
The first two functions for transmitting and freeing the rx buffer are provided as callbacks, i.e. they get called from esp-netif (and its underlying TCP/IP stack) and I/O driver provides their implementation.
So I wrote the implementation to free the rx buffer and assigned it to the function pointer esp_netif->driver_free_rx_buffer.
Now I found that the function is never called. So I checked the native ethernet driver and it assigns NULL to esp_netif->driver_free_rx_buffer.
Now I suspect that the buffer is already freed in the lwip stack or in esp-netif. Is this correct?

Daniel81
Posts: 2
Joined: Fri Sep 17, 2021 5:18 pm

Re: How is the rx buffer of a custom i/o driver using esp_netif_receive() is freed?

Postby Daniel81 » Thu Apr 28, 2022 9:29 am

I encountered the same problem and found, that a buffer allocated and passed to

Code: Select all

esp_err_t esp_netif_receive(esp_netif_t *esp_netif, void *buffer, size_t len, void *eb)
will never be freed, even though you specify a driver_free_rx_buffer callback.

I found out by try and error (no documentation found), that the driver_free_rx_buffer callback
will only be called, if you pass a non-NULL argument to the 'void *eb' parameter of esp_netif_receive(...).

Passing the same buffer twice, as 'void *buffer' and 'void *eb' did the trick. Now the driver_free_rx_buffer
callback is called and you can free the buffer.

ESP_ondrej
Posts: 166
Joined: Fri May 07, 2021 10:35 am

Re: How is the rx buffer of a custom i/o driver using esp_netif_receive() is freed?

Postby ESP_ondrej » Thu Apr 28, 2022 10:27 am

Daniel81 wrote: I encountered the same problem and found, that a buffer allocated and passed to
CODE: SELECT ALL

esp_err_t esp_netif_receive(esp_netif_t *esp_netif, void *buffer, size_t len, void *eb)
You probably found this in `esp_netif_loopback.c`, am I right? This piece of code is not used on target, it is used for test purposes.

The true is though, the Ethernet `esp_netif->driver_free_rx_buffer` is currently not used. Buffers coming from Ethernet driver are simply freed by direct call of `free` by `static void ethernet_free_rx_buf_l2(struct netif *netif, void *buf)` function in `ethernetif.c`.

To use `esp_netif->driver_free_rx_buffer` for Ethernet, you could probably update `ethernet_free_rx_buf_l2` as follows (similar to `wlanif.c`):

Code: Select all

static void ethernet_free_rx_buf_l2(struct netif *netif, void *buf)
{
    esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif);
    esp_netif_free_rx_buffer(esp_netif, buf);
}

witek117
Posts: 1
Joined: Sun Jul 17, 2022 10:00 pm

Re: How is the rx buffer of a custom i/o driver using esp_netif_receive() is freed?

Postby witek117 » Fri Aug 12, 2022 7:31 pm

@ci4rail did you succeed in writing a CDC-ECM (Ethernet over USB) driver for the esp32s2?

Who is online

Users browsing this forum: Baidu [Spider], Bing [Bot] and 112 guests