esp_netif, docs: Added programmer's manual section

Also added guide for creating a custom network capable I/O driver
And added notes about default wifi interfaces and implications of using
default short-hand creation functions.
This commit is contained in:
David Cermak 2019-11-25 16:40:56 +01:00
parent c86c1ecc7e
commit ac47c74ec4
7 changed files with 144 additions and 7 deletions

View file

@ -62,8 +62,10 @@ void* esp_netif_get_netif_impl(esp_netif_t *esp_netif);
* This function gets called from network stack to output packets to IO driver.
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[in] data Data to be tranmitted
* @param[in] data Data to be transmitted
* @param[in] len Length of the data frame
*
* @return ESP_OK on success, an error passed from the I/O driver otherwise
*/
esp_err_t esp_netif_transmit(esp_netif_t *esp_netif, void* data, size_t len);
@ -75,7 +77,7 @@ esp_err_t esp_netif_transmit(esp_netif_t *esp_netif, void* data, size_t len);
* to avoid copying)
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[in] void* buffer: rx buffer pointer
* @param[in] buffer Rx buffer pointer
*/
void esp_netif_free_rx_buffer(void *esp_netif, void* buffer);

View file

@ -28,6 +28,7 @@ INPUT = \
../../components/esp_wifi/include/esp_wifi_types.h \
../../components/esp_wifi/include/esp_smartconfig.h \
../../components/esp_wifi/include/esp_now.h \
../../components/esp_wifi/include/esp_wifi_default.h \
## Mesh - API Reference
../../components/esp_wifi/include/esp_mesh.h \
## Event loop - API Reference
@ -127,6 +128,7 @@ INPUT = \
../../components/soc/esp32/include/soc/rtc_io_channel.h \
## esp_netif - API Reference
../../components/esp_netif/include/esp_netif.h \
../../components/esp_netif/include/esp_netif_net_stack.h \
##
## Protocols - API Reference
##

View file

@ -90,10 +90,6 @@ B) Interaction with network interfaces using ESP-NETIF API
* Receiving IP events (connect/disconnect)
* Controlling application lifecycle (set interface up/down)
Please note that the initialization code as well as registering event handlers for default interfaces,
such as WiFi softAP and WiFi station, are provided as a separate APIs (for example ``esp_netif_create_default_wifi_ap()`` and
``esp_netif_create_default_wifi_sta()``) to facilitate simple startup code for most applications.
B) Communication driver, IO driver, media driver
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -105,7 +101,7 @@ Communication driver plays these two important roles in relation with ESP-NETIF:
2) Glue IO layer: Adapts the input/output functions to use ESP-NETIF transmit, receive and free receive buffer
* Installs driver_transmit to appropriate ESP-NETIF object, so that outgoing packets from network stack are passed to the IO driver
* Calls ``esp_netif_receive()`` to pass incoming data to network stack
* Calls :cpp:func:`esp_netif_receive()` to pass incoming data to network stack
C) ESP-NETIF, former tcpip_adapter
@ -140,9 +136,42 @@ Network stack has no public interaction with application code with regard to pub
ESP-NETIF API.
ESP-NETIF programmer's manual
-----------------------------
Please refer to the example section for basic initialization of default interfaces:
- WiFi Station: :example:`examples/wifi/getting_started/station/main/station_example_main.c`
- WiFi Access Point: :example:`examples/wifi/getting_started/softAP/main/softap_example_main.c`
- Ethernet :example:`examples/ethernet/basic/main/ethernet_example_main.c`
For more specific cases please consult this guide: :doc:`/api-reference/network/esp_netif_driver`.
WiFi default initialization
^^^^^^^^^^^^^^^^^^^^^^^^^^^
The initialization code as well as registering event handlers for default interfaces,
such as softAP and station, are provided in two separate APIs to facilitate simple startup code for most applications:
* :cpp:func:`esp_netif_create_default_wifi_ap()`
* :cpp:func:`esp_netif_create_default_wifi_sta()`
Please note that these functions return the ``esp_netif`` handle, i.e. a pointer to a network interface object allocated and
configured with default settings, which as a consequence, means that:
* The created object has to be destroyed if a network de-initialization is provided by an application.
* These *default* interfaces must not be created multiple times, unless the created handle is deleted using :cpp:func:`esp_netif_destroy()`.
* When using Wifi in ``AP+STA`` mode, both these interfaces has to be created.
API Reference
-------------
.. include:: /_build/inc/esp_netif.inc
WiFi default API reference
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. include:: /_build/inc/esp_wifi_default.inc

View file

@ -0,0 +1,97 @@
ESP-NETIF Custom I/O Driver
===========================
This section outlines implementing a new I/O driver with esp-netif connection capabilities.
By convention the I/O driver has to register itself as an esp-netif driver and thus holds a dependency on esp-netif component
and is responsible for providing data path functions, post-attach callback and in most cases also default event handlers to define network interface
actions based on driver's lifecycle transitions.
Packet input/output
^^^^^^^^^^^^^^^^^^^
As shown in the diagram, the following three API functions for the packet data path must be defined for connecting with esp-netif:
* :cpp:func:`esp_netif_transmit()`
* :cpp:func:`esp_netif_free_rx_buffer()`
* :cpp:func:`esp_netif_receive()`
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.
The receiving function on the other hand gets called from the I/O driver, so that the driver's code simply calls :cpp:func:`esp_netif_receive()`
on a new data received event.
Post attach callback
^^^^^^^^^^^^^^^^^^^^
A final part of the network interface initialization consists of attaching the esp-netif instance to the I/O driver, by means
of calling the following API:
.. code:: c
esp_err_t esp_netif_attach(esp_netif_t *esp_netif, esp_netif_iodriver_handle driver_handle);
It is assumed that the ``esp_netif_iodriver_handle`` is a pointer to driver's object, a struct derived from ``struct esp_netif_driver_base_s``,
so that the first member of I/O driver structure must be this base structure with pointers to
* post-attach function callback
* related esp-netif instance
As a consequence the I/O driver has to create an instance of the struct per below:
.. code:: c
typedef struct my_netif_driver_s {
esp_netif_driver_base_t base; /*!< base structure reserved as esp-netif driver */
driver_impl *h; /*!< handle of driver implementation */
} my_netif_driver_t;
with actual values of ``my_netif_driver_t::base.post_attach`` and the actual drivers handle ``my_netif_driver_t::h``.
So when the :cpp:func:`esp_netif_attach()` gets called from the initialization code, the post-attach callback from I/O driver's code
gets executed to mutually register callbacks between esp-netif and I/O driver instances. Typically the driver is started
as well in the post-attach callback. An example of a simple post-attach callback is outlined below:
.. code:: c
static esp_err_t my_post_attach_start(esp_netif_t * esp_netif, void * args)
{
my_netif_driver_t *driver = args;
const esp_netif_driver_ifconfig_t driver_ifconfig = {
.driver_free_rx_buffer = my_free_rx_buf,
.transmit = my_transmit,
.handle = driver->driver_impl
};
driver->base.netif = esp_netif;
ESP_ERROR_CHECK(esp_netif_set_driver_config(esp_netif, &driver_ifconfig));
my_driver_start(driver->driver_impl);
return ESP_OK;
}
Default handlers
^^^^^^^^^^^^^^^^
I/O drivers also typically provide default definitions of lifecycle behaviour of related network interfaces based
on state transitions of I/O drivers. For example *driver start* ``->`` *network start*, etc.
An example of such a default handler is provided below:
.. code:: c
esp_err_t my_driver_netif_set_default_handlers(my_netif_driver_t *driver, esp_netif_t * esp_netif)
{
driver_set_event_handler(driver->driver_impl, esp_netif_action_start, MY_DRV_EVENT_START, esp_netif);
driver_set_event_handler(driver->driver_impl, esp_netif_action_stop, MY_DRV_EVENT_STOP, esp_netif);
return ESP_OK;
}
Network stack connection
------------------------
The packet data path functions for transmitting and freeing the rx buffer (defined in the I/O driver) are called from
the esp-netif, specifically from its TCP/IP stack connecting layer. The following API reference outlines these network stack
interaction with the esp-netif.
.. include:: /_build/inc/esp_netif_net_stack.inc

View file

@ -42,6 +42,7 @@ IP Network Layer
:hidden:
TCP/IP Adapter Migration Guide <tcpip_adapter_migration.rst>
ESP-NETIF Custom I/O Driver <esp_netif_driver.rst>
Code examples for TCP/IP socket APIs are provided in the :example:`protocols/sockets` directory of ESP-IDF examples.

View file

@ -0,0 +1 @@
.. include:: ../../../en/api-reference/network/esp_netif_driver.rst

View file

@ -37,7 +37,12 @@ IP 网络层协议
:maxdepth: 1
ESP-NETIF <esp_netif.rst>
.. toctree::
:hidden:
TCP/IP Adapter Migration Guide <tcpip_adapter_migration.rst>
ESP-NETIF Custom I/O Driver <esp_netif_driver.rst>
TCP/IP 套接字 API 的示例代码存放在 ESP-IDF 示例项目的 :example:`protocols/sockets` 目录下。