mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'docs/update_api-reference/network' into 'master'
docs: update format issues for EN and CN files under api-reference/network folder and api-reference folder Closes DOC-5656 See merge request espressif/esp-idf!24542
This commit is contained in:
commit
b7cc28f6f1
@ -13,7 +13,7 @@ ESP-IDF provides several kinds of programming interfaces:
|
||||
* :doc:`Kconfig <kconfig>` options can be used in code and in the build system (``CMakeLists.txt``) files.
|
||||
* :doc:`Host tools <../api-guides/tools/index>` and their command line parameters are also part of the ESP-IDF interfaces.
|
||||
|
||||
ESP-IDF is made up of multiple components where these components either contain code specifically written for ESP chips, or contain a third-party library (i.e., a third-party component). In some cases, third-party components will contain an "ESP-IDF specific" wrapper in order to provide an interface that is either simpler or better integrated with the rest of ESP-IDF's features. In other cases, third-party components will present the original API of the underlying library directly.
|
||||
ESP-IDF is made up of multiple components where these components either contain code specifically written for ESP chips, or contain a third-party library (i.e., a third-party component). In some cases, third-party components contain an "ESP-IDF specific" wrapper in order to provide an interface that is either simpler or better integrated with the rest of ESP-IDF's features. In other cases, third-party components present the original API of the underlying library directly.
|
||||
|
||||
The following sections explain some of the aspects of ESP-IDF APIs and their usage.
|
||||
|
||||
@ -137,7 +137,7 @@ ESP-IDF does not guarantee binary compatibility between releases. This means tha
|
||||
Other Exceptions from Compatibility
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
While we try to make upgrading to a new ESP-IDF version easy, there are parts of ESP-IDF that may change between minor versions in an incompatible way. We appreciate issuing reports about any unintended breaking changes that don't fall into the categories below.
|
||||
While we try to make upgrading to a new ESP-IDF version easy, there are parts of ESP-IDF that may change between minor versions in an incompatible way. We appreciate issuing reports about any unintended breaking changes that do not fall into the categories below.
|
||||
|
||||
* :ref:`api_reference_private_apis`.
|
||||
* :ref:`api_reference_example_components`.
|
||||
|
@ -43,7 +43,7 @@ Format rules for Kconfig files are as follows:
|
||||
Format Checker
|
||||
--------------
|
||||
|
||||
``tools/ci/check_kconfigs.py`` is provided for checking Kconfig files against the above format rules. The checker checks all Kconfig and ``Kconfig.projbuild`` files in the ESP-IDF directory, and generates a new file with suffix ``.new`` with some suggestions about how to fix issues (if there are any). Please note that the checker cannot correct all format issues and the responsibility of the developer is to final check and make corrections in order to pass the tests. For example, indentations will be corrected if there isn't any misleading formatting, but it cannot come up with a common prefix for options inside a menu.
|
||||
``tools/ci/check_kconfigs.py`` is provided for checking Kconfig files against the above format rules. The checker checks all Kconfig and ``Kconfig.projbuild`` files in the ESP-IDF directory, and generates a new file with suffix ``.new`` with some suggestions about how to fix issues (if there are any). Please note that the checker cannot correct all format issues and the responsibility of the developer is to final check and make corrections in order to pass the tests. For example, indentations will be corrected if there is not any misleading formatting, but it cannot come up with a common prefix for options inside a menu.
|
||||
|
||||
.. _configuration-options-compatibility:
|
||||
|
||||
@ -52,8 +52,8 @@ Backward Compatibility of Kconfig Options
|
||||
|
||||
The standard Kconfig_ tools ignore unknown options in ``sdkconfig``. So if a developer has custom settings for options which are renamed in newer ESP-IDF releases, then the given setting for the option would be silently ignored. Therefore, several features have been adopted to avoid this:
|
||||
|
||||
1. ``kconfgen`` is used by the tool chain to pre-process ``sdkconfig`` files before anything else. For example, ``menuconfig`` would read them, so the settings for old options will be kept and not ignored.
|
||||
2. ``kconfgen`` recursively finds all ``sdkconfig.rename`` files in ESP-IDF directory which contain old and new ``Kconfig`` option names. Old options are replaced by new ones in the ``sdkconfig`` file. Renames that should only appear for a single target can be placed in a target-specific rename file ``sdkconfig.rename.TARGET``, where ``TARGET`` is the target name, e.g. ``sdkconfig.rename.esp32s2``.
|
||||
1. ``kconfgen`` is used by the tool chain to pre-process ``sdkconfig`` files before anything else. For example, ``menuconfig`` would read them, so the settings for old options is kept and not ignored.
|
||||
2. ``kconfgen`` recursively finds all ``sdkconfig.rename`` files in ESP-IDF directory which contain old and new ``Kconfig`` option names. Old options are replaced by new ones in the ``sdkconfig`` file. Renames that should only appear for a single target can be placed in a target-specific rename file ``sdkconfig.rename.TARGET``, where ``TARGET`` is the target name, e.g., ``sdkconfig.rename.esp32s2``.
|
||||
3. ``kconfgen`` post-processes ``sdkconfig`` files and generates all build outputs (``sdkconfig.h``, ``sdkconfig.cmake``, and ``auto.conf``) by adding a list of compatibility statements, i.e., the values of old options are set for new options after modification. If users still use old options in their code, this will prevent it from breaking.
|
||||
4. :ref:`configuration-deprecated-options` are automatically generated by ``kconfgen``.
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
ESP-WIFI-MESH Programming Guide
|
||||
===================================
|
||||
===============================
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
@ -15,7 +15,7 @@ This is a programming guide for ESP-WIFI-MESH, including the API reference and c
|
||||
|
||||
5. :ref:`mesh-api-reference`
|
||||
|
||||
For documentation regarding the ESP-WIFI-MESH protocol, please see the :doc:`ESP-WIFI-MESH API Guide<../../api-guides/esp-wifi-mesh>`. For more information about ESP-WIFI-MESH Development Framework, please see `ESP-WIFI-MESH Development Framework <https://github.com/espressif/esp-mdf>`_.
|
||||
For documentation regarding the ESP-WIFI-MESH protocol, please see the :doc:`ESP-WIFI-MESH API Guide <../../api-guides/esp-wifi-mesh>`. For more information about ESP-WIFI-MESH Development Framework, please see `ESP-WIFI-MESH Development Framework <https://github.com/espressif/esp-mdf>`_.
|
||||
|
||||
|
||||
.. ---------------------- ESP-WIFI-MESH Programming Model --------------------------
|
||||
@ -28,7 +28,7 @@ ESP-WIFI-MESH Programming Model
|
||||
Software Stack
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
The ESP-WIFI-MESH software stack is built atop the Wi-Fi Driver/FreeRTOS and may use the LwIP Stack in some instances (i.e. the root node). The following diagram illustrates the ESP-WIFI-MESH software stack.
|
||||
The ESP-WIFI-MESH software stack is built atop the Wi-Fi Driver/FreeRTOS and may use the LwIP Stack in some instances (i.e., the root node). The following diagram illustrates the ESP-WIFI-MESH software stack.
|
||||
|
||||
.. _mesh-going-to-software-stack:
|
||||
|
||||
@ -58,6 +58,7 @@ The :cpp:type:`mesh_event_id_t` defines all possible ESP-WIFI-MESH events and ca
|
||||
Typical use cases of mesh events include using events such as :cpp:enumerator:`MESH_EVENT_PARENT_CONNECTED` and :cpp:enumerator:`MESH_EVENT_CHILD_CONNECTED` to indicate when a node can begin transmitting data upstream and downstream respectively. Likewise, :cpp:enumerator:`IP_EVENT_STA_GOT_IP` and :cpp:enumerator:`IP_EVENT_STA_LOST_IP` can be used to indicate when the root node can and cannot transmit data to the external IP network.
|
||||
|
||||
.. warning::
|
||||
|
||||
When using ESP-WIFI-MESH under self-organized mode, users must ensure that no calls to Wi-Fi API are made. This is due to the fact that the self-organizing mode will internally make Wi-Fi API calls to connect/disconnect/scan etc. **Any Wi-Fi calls from the application (including calls from callbacks and handlers of Wi-Fi events) may interfere with ESP-WIFI-MESH's self-organizing behavior**. Therefore, users should not call Wi-Fi APIs after :cpp:func:`esp_mesh_start` is called, and before :cpp:func:`esp_mesh_stop` is called.
|
||||
|
||||
LwIP & ESP-WIFI-MESH
|
||||
@ -188,45 +189,45 @@ After starting ESP-WIFI-MESH, the application should check for ESP-WIFI-MESH eve
|
||||
|
||||
.. _mesh-self-organized-behavior:
|
||||
|
||||
Self Organized Networking
|
||||
Self-Organized Networking
|
||||
-------------------------
|
||||
|
||||
Self organized networking is a feature of ESP-WIFI-MESH where nodes can autonomously scan/select/connect/reconnect to other nodes and routers. This feature allows an ESP-WIFI-MESH network to operate with high degree of autonomy by making the network robust to dynamic network topologies and conditions. With self organized networking enabled, nodes in an ESP-WIFI-MESH network are able to carry out the following actions without autonomously:
|
||||
Self-organized networking is a feature of ESP-WIFI-MESH where nodes can autonomously scan/select/connect/reconnect to other nodes and routers. This feature allows an ESP-WIFI-MESH network to operate with high degree of autonomy by making the network robust to dynamic network topologies and conditions. With self-organized networking enabled, nodes in an ESP-WIFI-MESH network are able to carry out the following actions without autonomously:
|
||||
|
||||
- Selection or election of the root node (see **Automatic Root Node Selection** in :ref:`mesh-building-a-network`)
|
||||
- Selection of a preferred parent node (see **Parent Node Selection** in :ref:`mesh-building-a-network`)
|
||||
- Automatic reconnection upon detecting a disconnection (see **Intermediate Parent Node Failure** in :ref:`mesh-managing-a-network`)
|
||||
|
||||
When self organized networking is enabled, the ESP-WIFI-MESH stack will internally make calls to Wi-Fi APIs. Therefore, **the application layer should not make any calls to Wi-Fi APIs whilst self organized networking is enabled as doing so would risk interfering with ESP-WIFI-MESH**.
|
||||
When self-organized networking is enabled, the ESP-WIFI-MESH stack will internally make calls to Wi-Fi APIs. Therefore, **the application layer should not make any calls to Wi-Fi APIs whilst self-organized networking is enabled as doing so would risk interfering with ESP-WIFI-MESH**.
|
||||
|
||||
Toggling Self Organized Networking
|
||||
Toggling Self-Organized Networking
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Self organized networking can be enabled or disabled by the application at runtime by calling the :cpp:func:`esp_mesh_set_self_organized` function. The function has the two following parameters:
|
||||
Self-organized networking can be enabled or disabled by the application at runtime by calling the :cpp:func:`esp_mesh_set_self_organized` function. The function has the two following parameters:
|
||||
|
||||
- ``bool enable`` specifies whether to enable or disable self organized networking.
|
||||
- ``bool enable`` specifies whether to enable or disable self-organized networking.
|
||||
|
||||
- ``bool select_parent`` specifies whether a new parent node should be selected when enabling self organized networking. Selecting a new parent has different effects depending the node type and the node's current state. This parameter is unused when disabling self organized networking.
|
||||
- ``bool select_parent`` specifies whether a new parent node should be selected when enabling self-organized networking. Selecting a new parent has different effects depending the node type and the node's current state. This parameter is unused when disabling self-organized networking.
|
||||
|
||||
Disabling Self Organized Networking
|
||||
Disabling Self-Organized Networking
|
||||
"""""""""""""""""""""""""""""""""""
|
||||
The following code snippet demonstrates how to disable self organized networking.
|
||||
The following code snippet demonstrates how to disable self-organized networking.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
//Disable self organized networking
|
||||
//Disable self-organized networking
|
||||
esp_mesh_set_self_organized(false, false);
|
||||
|
||||
ESP-WIFI-MESH will attempt to maintain the node's current Wi-Fi state when disabling self organized networking.
|
||||
ESP-WIFI-MESH will attempt to maintain the node's current Wi-Fi state when disabling self-organized networking.
|
||||
|
||||
- If the node was previously connected to other nodes, it will remain connected.
|
||||
- If the node was previously disconnected and was scanning for a parent node or router, it will stop scanning.
|
||||
- If the node was previously attempting to reconnect to a parent node or router, it will stop reconnecting.
|
||||
|
||||
Enabling Self Organized Networking
|
||||
Enabling Self-Organized Networking
|
||||
""""""""""""""""""""""""""""""""""
|
||||
|
||||
ESP-WIFI-MESH will attempt to maintain the node's current Wi-Fi state when enabling self organized networking. However, depending on the node type and whether a new parent is selected, the Wi-Fi state of the node can change. The following table shows effects of enabling self organized networking.
|
||||
ESP-WIFI-MESH will attempt to maintain the node's current Wi-Fi state when enabling self-organized networking. However, depending on the node type and whether a new parent is selected, the Wi-Fi state of the node can change. The following table shows effects of enabling self-organized networking.
|
||||
|
||||
+---------------+--------------+------------------------------------------------------------------------------------------------------------------+
|
||||
| Select Parent | Is Root Node | Effects |
|
||||
@ -244,16 +245,16 @@ ESP-WIFI-MESH will attempt to maintain the node's current Wi-Fi state when enabl
|
||||
| | | disconnect from the router and all child nodes, select a preferred parent node, and connect. |
|
||||
+---------------+--------------+------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
The following code snipping demonstrates how to enable self organized networking.
|
||||
The following code snipping demonstrates how to enable self-organized networking.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
//Enable self organized networking and select a new parent
|
||||
//Enable self-organized networking and select a new parent
|
||||
esp_mesh_set_self_organized(true, true);
|
||||
|
||||
...
|
||||
|
||||
//Enable self organized networking and manually reconnect
|
||||
//Enable self-organized networking and manually reconnect
|
||||
esp_mesh_set_self_organized(true, false);
|
||||
esp_mesh_connect();
|
||||
|
||||
@ -261,13 +262,13 @@ The following code snipping demonstrates how to enable self organized networking
|
||||
Calling Wi-Fi API
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
There can be instances in which an application may want to directly call Wi-Fi API whilst using ESP-WIFI-MESH. For example, an application may want to manually scan for neighboring APs. However, **self organized networking must be disabled before the application calls any Wi-Fi APIs**. This will prevent the ESP-WIFI-MESH stack from attempting to call any Wi-Fi APIs and potentially interfering with the application's calls.
|
||||
There can be instances in which an application may want to directly call Wi-Fi API whilst using ESP-WIFI-MESH. For example, an application may want to manually scan for neighboring APs. However, **self-organized networking must be disabled before the application calls any Wi-Fi APIs**. This will prevent the ESP-WIFI-MESH stack from attempting to call any Wi-Fi APIs and potentially interfering with the application's calls.
|
||||
|
||||
Therefore, application calls to Wi-Fi APIs should be placed in between calls of :cpp:func:`esp_mesh_set_self_organized` which disable and enable self organized networking. The following code snippet demonstrates how an application can safely call :cpp:func:`esp_wifi_scan_start` whilst using ESP-WIFI-MESH.
|
||||
Therefore, application calls to Wi-Fi APIs should be placed in between calls of :cpp:func:`esp_mesh_set_self_organized` which disable and enable self-organized networking. The following code snippet demonstrates how an application can safely call :cpp:func:`esp_wifi_scan_start` whilst using ESP-WIFI-MESH.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
//Disable self organized networking
|
||||
//Disable self-organized networking
|
||||
esp_mesh_set_self_organized(0, 0);
|
||||
|
||||
//Stop any scans already in progress
|
||||
@ -279,18 +280,18 @@ Therefore, application calls to Wi-Fi APIs should be placed in between calls of
|
||||
|
||||
...
|
||||
|
||||
//Re-enable self organized networking if still connected
|
||||
//Re-enable self-organized networking if still connected
|
||||
esp_mesh_set_self_organized(1, 0);
|
||||
|
||||
...
|
||||
|
||||
//Re-enable self organized networking if non-root and disconnected
|
||||
//Re-enable self-organized networking if non-root and disconnected
|
||||
esp_mesh_set_self_organized(1, 1);
|
||||
|
||||
...
|
||||
|
||||
//Re-enable self organized networking if root and disconnected
|
||||
esp_mesh_set_self_organized(1, 0); //Don't select new parent
|
||||
//Re-enable self-organized networking if root and disconnected
|
||||
esp_mesh_set_self_organized(1, 0); //Do not select new parent
|
||||
esp_mesh_connect(); //Manually reconnect to router
|
||||
|
||||
|
||||
|
@ -28,7 +28,7 @@ Ethernet is an asynchronous Carrier Sense Multiple Access with Collision Detect
|
||||
|
||||
Normal IEEE 802.3 compliant Ethernet frames are between 64 and 1518 bytes in length. They are made up of five or six different fields: a destination MAC address (DA), a source MAC address (SA), a type/length field, a data payload, an optional padding field and a Cyclic Redundancy Check (CRC). Additionally, when transmitted on the Ethernet medium, a 7-byte preamble field and Start-of-Frame (SOF) delimiter byte are appended to the beginning of the Ethernet packet.
|
||||
|
||||
Thus the traffic on the twist-pair cabling will appear as shown below:
|
||||
Thus the traffic on the twist-pair cabling appears as shown below:
|
||||
|
||||
.. rackdiag:: ../../../_static/diagrams/ethernet/data_frame_format.diag
|
||||
:caption: Ethernet Data Frame Format
|
||||
@ -41,14 +41,14 @@ The preamble contains seven bytes of ``55H``. It allows the receiver to lock ont
|
||||
|
||||
The Start-of-Frame Delimiter (SFD) is a binary sequence ``10101011`` (as seen on the physical medium). It is sometimes considered to be part of the preamble.
|
||||
|
||||
When transmitting and receiving data, the preamble and SFD bytes will automatically be generated or stripped from the packets.
|
||||
When transmitting and receiving data, the preamble and SFD bytes will be automatically generated or stripped from the packets.
|
||||
|
||||
Destination Address
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The destination address field contains a 6-byte length MAC address of the device that the packet is directed to. If the Least Significant bit in the first byte of the MAC address is set, the address is a multicast destination. For example, 01-00-00-00-F0-00 and 33-45-67-89-AB-CD are multi-cast addresses, while 00-00-00-00-F0-00 and 32-45-67-89-AB-CD are not.
|
||||
|
||||
Packets with multi-cast destination addresses are designed to arrive and be important to a selected group of Ethernet nodes. If the destination address field is the reserved multicast address, i.e. FF-FF-FF-FF-FF-FF, the packet is a broadcast packet and it will be directed to everyone sharing the network. If the Least Significant bit in the first byte of the MAC address is clear, the address is a unicast address and will be designed for usage by only the addressed node.
|
||||
Packets with multi-cast destination addresses are designed to arrive and be important to a selected group of Ethernet nodes. If the destination address field is the reserved multicast address, i.e., FF-FF-FF-FF-FF-FF, the packet is a broadcast packet and it will be directed to everyone sharing the network. If the Least Significant bit in the first byte of the MAC address is clear, the address is a unicast address and will be designed for usage by only the addressed node.
|
||||
|
||||
Normally the EMAC controller incorporates receive filters which can be used to discard or accept packets with multi-cast, broadcast and/or unicast destination addresses. When transmitting packets, the host controller is responsible for writing the desired destination address into the transmit buffer.
|
||||
|
||||
@ -68,12 +68,12 @@ The type/length field is a 2-byte field. If the value in this field is <= 1500 (
|
||||
* IPv6 = 86DDH
|
||||
* ARP = 0806H
|
||||
|
||||
Users implementing proprietary networks may choose to treat this field as a length field, while applications implementing protocols such as the Internet Protocol (IP) or Address Resolution Protocol (ARP), should program this field with the appropriate type defined by the protocol’s specification when transmitting packets.
|
||||
Users implementing proprietary networks may choose to treat this field as a length field, while applications implementing protocols such as the Internet Protocol (IP) or Address Resolution Protocol (ARP), should program this field with the appropriate type defined by the protocol's specification when transmitting packets.
|
||||
|
||||
Payload
|
||||
^^^^^^^
|
||||
|
||||
The payload field is a variable length field, anywhere from 0 to 1500 bytes. Larger data packets will violate Ethernet standards and will be dropped by most Ethernet nodes.
|
||||
The payload field is a variable length field, anywhere from 0 to 1500 bytes. Larger data packets violates Ethernet standards and will be dropped by most Ethernet nodes.
|
||||
|
||||
This field contains the client data, such as an IP datagram.
|
||||
|
||||
@ -84,12 +84,12 @@ The padding field is a variable length field added to meet the IEEE 802.3 specif
|
||||
|
||||
The DA, SA, type, payload, and padding of an Ethernet packet must be no smaller than 60 bytes in total. If the required 4-byte FCS field is added, packets must be no smaller than 64 bytes. If the payload field is less than 46-byte long, a padding field is required.
|
||||
|
||||
The FCS field is a 4-byte field that contains an industry-standard 32-bit CRC calculated with the data from the DA, SA, type, payload, and padding fields. Given the complexity of calculating a CRC, the hardware normally will automatically generate a valid CRC and transmit it. Otherwise, the host controller must generate the CRC and place it in the transmit buffer.
|
||||
The FCS field is a 4-byte field that contains an industry-standard 32-bit CRC calculated with the data from the DA, SA, type, payload, and padding fields. Given the complexity of calculating a CRC, the hardware normally automatically generates a valid CRC and transmit it. Otherwise, the host controller must generate the CRC and place it in the transmit buffer.
|
||||
|
||||
Normally, the host controller does not need to concern itself with padding and the CRC which the hardware EMAC will also be able to automatically generate when transmitting and verify when receiving. However, the padding and CRC fields will be written into the receive buffer when packets arrive, so they may be evaluated by the host controller if needed.
|
||||
|
||||
.. note::
|
||||
Besides the basic data frame described above, there're two other common frame types in 10/100 Mbps Ethernet: control frames and VLAN-tagged frames. They're not supported in ESP-IDF.
|
||||
Besides the basic data frame described above, there are two other common frame types in 10/100 Mbps Ethernet: control frames and VLAN-tagged frames. They are not supported in ESP-IDF.
|
||||
|
||||
.. ------------------------------ Driver Operation --------------------------------
|
||||
|
||||
@ -115,11 +115,11 @@ The Ethernet driver is composed of two parts: MAC and PHY.
|
||||
|
||||
In RMII mode, both the receiver and transmitter signals are referenced to the ``REF_CLK``. **REF_CLK must be stable during any access to PHY and MAC**. Generally, there are three ways to generate the ``REF_CLK`` depending on the PHY device in your design:
|
||||
|
||||
* Some PHY chips can derive the ``REF_CLK`` from its externally connected 25 MHz crystal oscillator (as seen the option *a* in the picture). In this case, you should select ``CONFIG_ETH_RMII_CLK_INPUT`` in :ref:`CONFIG_ETH_RMII_CLK_MODE`.
|
||||
* Some PHY chips can derive the ``REF_CLK`` from its externally connected 25 MHz crystal oscillator (as seen the option **a** in the picture). In this case, you should select ``CONFIG_ETH_RMII_CLK_INPUT`` in :ref:`CONFIG_ETH_RMII_CLK_MODE`.
|
||||
|
||||
* Some PHY chip uses an externally connected 50MHz crystal oscillator or other clock sources, which can also be used as the ``REF_CLK`` for the MAC side (as seen the option *b* in the picture). In this case, you still need to select ``CONFIG_ETH_RMII_CLK_INPUT`` in :ref:`CONFIG_ETH_RMII_CLK_MODE`.
|
||||
* Some PHY chip uses an externally connected 50MHz crystal oscillator or other clock sources, which can also be used as the ``REF_CLK`` for the MAC side (as seen the option **b** in the picture). In this case, you still need to select ``CONFIG_ETH_RMII_CLK_INPUT`` in :ref:`CONFIG_ETH_RMII_CLK_MODE`.
|
||||
|
||||
* Some EMAC controllers can generate the ``REF_CLK`` using an internal high-precision PLL (as seen the option *c* in the picture). In this case, you should select ``CONFIG_ETH_RMII_CLK_OUTPUT`` in :ref:`CONFIG_ETH_RMII_CLK_MODE`.
|
||||
* Some EMAC controllers can generate the ``REF_CLK`` using an internal high-precision PLL (as seen the option **c** in the picture). In this case, you should select ``CONFIG_ETH_RMII_CLK_OUTPUT`` in :ref:`CONFIG_ETH_RMII_CLK_MODE`.
|
||||
|
||||
.. note::
|
||||
``REF_CLK`` is configured via Project Configuration as described above by default. However, it can be overwritten from user application code by appropriately setting :cpp:member:`eth_esp32_emac_config_t::interface` and :cpp:member:`eth_esp32_emac_config_t::clock_config` members. See :cpp:enum:`emac_rmii_clock_mode_t` and :cpp:enum:`emac_rmii_clock_gpio_t` for more details.
|
||||
@ -127,22 +127,22 @@ The Ethernet driver is composed of two parts: MAC and PHY.
|
||||
.. warning::
|
||||
If the RMII clock mode is selected to ``CONFIG_ETH_RMII_CLK_OUTPUT``, then ``GPIO0`` can be used to output the ``REF_CLK`` signal. See :ref:`CONFIG_ETH_RMII_CLK_OUTPUT_GPIO0` for more information.
|
||||
|
||||
What's more, if you're not using PSRAM in your design, GPIO16 and GPIO17 are also available to output the reference clock. See :ref:`CONFIG_ETH_RMII_CLK_OUT_GPIO` for more information.
|
||||
What is more, if you are not using PSRAM in your design, GPIO16 and GPIO17 are also available to output the reference clock. See :ref:`CONFIG_ETH_RMII_CLK_OUT_GPIO` for more information.
|
||||
|
||||
If the RMII clock mode is selected to ``CONFIG_ETH_RMII_CLK_INPUT``, then ``GPIO0`` is the only choice to input the ``REF_CLK`` signal. Please note that ``GPIO0`` is also an important strapping GPIO on ESP32. If GPIO0 samples a low level during power-up, ESP32 will go into download mode. The system will get halted until a manually reset. The workaround for this issue is disabling the ``REF_CLK`` in hardware by default so that the strapping pin won't be interfered by other signals in the boot stage. Then, re-enable the ``REF_CLK`` in the Ethernet driver installation stage.
|
||||
If the RMII clock mode is selected to ``CONFIG_ETH_RMII_CLK_INPUT``, then ``GPIO0`` is the only choice to input the ``REF_CLK`` signal. Please note that ``GPIO0`` is also an important strapping GPIO on ESP32. If GPIO0 samples a low level during power-up, ESP32 will go into download mode. The system will get halted until a manually reset. The workaround for this issue is disabling the ``REF_CLK`` in hardware by default so that the strapping pin is not interfered by other signals in the boot stage. Then, re-enable the ``REF_CLK`` in the Ethernet driver installation stage.
|
||||
|
||||
The ways to disable the ``REF_CLK`` signal can be:
|
||||
|
||||
* Disable or power down the crystal oscillator (as the case *b* in the picture).
|
||||
* Disable or power down the crystal oscillator (as the case **b** in the picture).
|
||||
|
||||
* Force the PHY device to reset status (as the case *a* in the picture). **This could fail for some PHY device** (i.e. it still outputs signals to GPIO0 even in reset state).
|
||||
* Force the PHY device to reset status (as the case **a** in the picture). **This could fail for some PHY device** (i.e., it still outputs signals to GPIO0 even in reset state).
|
||||
|
||||
**No matter which RMII clock mode you select, you really need to take care of the signal integrity of REF_CLK in your hardware design!** Keep the trace as short as possible. Keep it away from RF devices and inductor elements.
|
||||
|
||||
.. note::
|
||||
ESP-IDF only supports the RMII interface (i.e. always select ``CONFIG_ETH_PHY_INTERFACE_RMII`` in the Kconfig option :ref:`CONFIG_ETH_PHY_INTERFACE`).
|
||||
ESP-IDF only supports the RMII interface (i.e., always select ``CONFIG_ETH_PHY_INTERFACE_RMII`` in the Kconfig option :ref:`CONFIG_ETH_PHY_INTERFACE`).
|
||||
|
||||
Signals used in the data plane are fixed to specific GPIOs via MUX, they can't be modified to other GPIOs. Signals used in the control plane can be routed to any free GPIOs via Matrix. Please refer to :doc:`ESP32-Ethernet-Kit <../../hw-reference/esp32/get-started-ethernet-kit>` for hardware design example.
|
||||
Signals used in the data plane are fixed to specific GPIOs via MUX, they can not be modified to other GPIOs. Signals used in the control plane can be routed to any free GPIOs via Matrix. Please refer to :doc:`ESP32-Ethernet-Kit <../../hw-reference/esp32/get-started-ethernet-kit>` for hardware design example.
|
||||
|
||||
You need to set up the necessary parameters for MAC and PHY respectively based on your Ethernet board design, and then combine the two together to complete the driver installation.
|
||||
|
||||
@ -166,13 +166,13 @@ Configuration for PHY is described in :cpp:class:`eth_phy_config_t`, including:
|
||||
|
||||
.. list::
|
||||
|
||||
* :cpp:member:`eth_phy_config_t::phy_addr`: multiple PHY devices can share the same SMI bus, so each PHY needs a unique address. Usually, this address is configured during hardware design by pulling up/down some PHY strapping pins. You can set the value from 0 to 15 based on your Ethernet board. Especially, if the SMI bus is shared by only one PHY device, setting this value to -1 can enable the driver to detect the PHY address automatically.
|
||||
* :cpp:member:`eth_phy_config_t::phy_addr`: multiple PHY devices can share the same SMI bus, so each PHY needs a unique address. Usually, this address is configured during hardware design by pulling up/down some PHY strapping pins. You can set the value from ``0`` to ``15`` based on your Ethernet board. Especially, if the SMI bus is shared by only one PHY device, setting this value to ``-1`` can enable the driver to detect the PHY address automatically.
|
||||
|
||||
* :cpp:member:`eth_phy_config_t::reset_timeout_ms`: reset timeout value, in milliseconds. Typically, PHY reset should be finished within 100 ms.
|
||||
|
||||
* :cpp:member:`eth_phy_config_t::autonego_timeout_ms`: auto-negotiation timeout value, in milliseconds. The Ethernet driver will start negotiation with the peer Ethernet node automatically, to determine to duplex and speed mode. This value usually depends on the ability of the PHY device on your board.
|
||||
* :cpp:member:`eth_phy_config_t::autonego_timeout_ms`: auto-negotiation timeout value, in milliseconds. The Ethernet driver starts negotiation with the peer Ethernet node automatically, to determine to duplex and speed mode. This value usually depends on the ability of the PHY device on your board.
|
||||
|
||||
* :cpp:member:`eth_phy_config_t::reset_gpio_num`: if your board also connects the PHY reset pin to one of the GPIO, then set it here. Otherwise, set this field to -1.
|
||||
* :cpp:member:`eth_phy_config_t::reset_gpio_num`: if your board also connects the PHY reset pin to one of the GPIO, then set it here. Otherwise, set this field to ``-1``.
|
||||
|
||||
ESP-IDF provides a default configuration for MAC and PHY in macro :c:macro:`ETH_MAC_DEFAULT_CONFIG` and :c:macro:`ETH_PHY_DEFAULT_CONFIG`.
|
||||
|
||||
@ -263,23 +263,23 @@ SPI-Ethernet Module
|
||||
|
||||
|
||||
.. note::
|
||||
* When creating MAC and PHY instances for SPI-Ethernet modules (e.g. DM9051), the constructor function must have the same suffix (e.g. `esp_eth_mac_new_dm9051` and `esp_eth_phy_new_dm9051`). This is because we don't have other choices but the integrated PHY.
|
||||
* When creating MAC and PHY instances for SPI-Ethernet modules (e.g., DM9051), the constructor function must have the same suffix (e.g., `esp_eth_mac_new_dm9051` and `esp_eth_phy_new_dm9051`). This is because we don not have other choices but the integrated PHY.
|
||||
|
||||
* The SPI device configuration (i.e. `spi_device_interface_config_t`) may slightly differ for other Ethernet modules or to meet SPI timing on specific PCB. Please check out your module's specs and the examples in ESP-IDF.
|
||||
* The SPI device configuration (i.e., `spi_device_interface_config_t`) may slightly differ for other Ethernet modules or to meet SPI timing on specific PCB. Please check out your module's specs and the examples in ESP-IDF.
|
||||
|
||||
|
||||
Install Driver
|
||||
--------------
|
||||
|
||||
To install the Ethernet driver, we need to combine the instance of MAC and PHY and set some additional high-level configurations (i.e. not specific to either MAC or PHY) in :cpp:class:`esp_eth_config_t`:
|
||||
To install the Ethernet driver, we need to combine the instance of MAC and PHY and set some additional high-level configurations (i.e., not specific to either MAC or PHY) in :cpp:class:`esp_eth_config_t`:
|
||||
|
||||
* :cpp:member:`esp_eth_config_t::mac`: instance that created from MAC generator (e.g. :cpp:func:`esp_eth_mac_new_esp32`).
|
||||
* :cpp:member:`esp_eth_config_t::mac`: instance that created from MAC generator (e.g., :cpp:func:`esp_eth_mac_new_esp32`).
|
||||
|
||||
* :cpp:member:`esp_eth_config_t::phy`: instance that created from PHY generator (e.g. :cpp:func:`esp_eth_phy_new_ip101`).
|
||||
* :cpp:member:`esp_eth_config_t::phy`: instance that created from PHY generator (e.g., :cpp:func:`esp_eth_phy_new_ip101`).
|
||||
|
||||
* :cpp:member:`esp_eth_config_t::check_link_period_ms`: Ethernet driver starts an OS timer to check the link status periodically, this field is used to set the interval, in milliseconds.
|
||||
|
||||
* :cpp:member:`esp_eth_config_t::stack_input`: In most Ethernet IoT applications, any Ethernet frame received by a driver should be passed to the upper layer (e.g. TCP/IP stack). This field is set to a function that is responsible to deal with the incoming frames. You can even update this field at runtime via function :cpp:func:`esp_eth_update_input_path` after driver installation.
|
||||
* :cpp:member:`esp_eth_config_t::stack_input`: In most Ethernet IoT applications, any Ethernet frame received by a driver should be passed to the upper layer (e.g., TCP/IP stack). This field is set to a function that is responsible to deal with the incoming frames. You can even update this field at runtime via function :cpp:func:`esp_eth_update_input_path` after driver installation.
|
||||
|
||||
* :cpp:member:`esp_eth_config_t::on_lowlevel_init_done` and :cpp:member:`esp_eth_config_t::on_lowlevel_deinit_done`: These two fields are used to specify the hooks which get invoked when low-level hardware has been initialized or de-initialized.
|
||||
|
||||
@ -293,7 +293,7 @@ ESP-IDF provides a default configuration for driver installation in macro :c:mac
|
||||
esp_eth_handle_t eth_handle = NULL; // after the driver is installed, we will get the handle of the driver
|
||||
esp_eth_driver_install(&config, ð_handle); // install driver
|
||||
|
||||
The Ethernet driver also includes an event-driven model, which will send useful and important events to user space. We need to initialize the event loop before installing the Ethernet driver. For more information about event-driven programming, please refer to :doc:`ESP Event <../system/esp_event>`.
|
||||
The Ethernet driver also includes an event-driven model, which sends useful and important events to user space. We need to initialize the event loop before installing the Ethernet driver. For more information about event-driven programming, please refer to :doc:`ESP Event <../system/esp_event>`.
|
||||
|
||||
.. highlight:: c
|
||||
|
||||
@ -347,7 +347,7 @@ After driver installation, we can start Ethernet immediately.
|
||||
Connect Driver to TCP/IP Stack
|
||||
------------------------------
|
||||
|
||||
Up until now, we have installed the Ethernet driver. From the view of OSI (Open System Interconnection), we're still on level 2 (i.e. Data Link Layer). While we can detect link up and down events and gain MAC address in user space, it's infeasible to obtain the IP address, let alone send an HTTP request. The TCP/IP stack used in ESP-IDF is called LwIP. For more information about it, please refer to :doc:`LwIP <../../api-guides/lwip>`.
|
||||
Up until now, we have installed the Ethernet driver. From the view of OSI (Open System Interconnection), we are still on level 2 (i.e., Data Link Layer). While we can detect link up and down events and gain MAC address in user space, it is infeasible to obtain the IP address, let alone send an HTTP request. The TCP/IP stack used in ESP-IDF is called LwIP. For more information about it, please refer to :doc:`LwIP <../../api-guides/lwip>`.
|
||||
|
||||
To connect the Ethernet driver to TCP/IP stack, follow these three steps:
|
||||
|
||||
@ -385,7 +385,7 @@ For more information about the network interface, please refer to :doc:`Network
|
||||
esp_eth_start(eth_handle); // start Ethernet driver state machine
|
||||
|
||||
.. warning::
|
||||
It is recommended to fully initialize the Ethernet driver and network interface before registering the user's Ethernet/IP event handlers, i.e. register the event handlers as the last thing prior to starting the Ethernet driver. Such an approach ensures that Ethernet/IP events get executed first by the Ethernet driver or network interface so the system is in the expected state when executing the user's handlers.
|
||||
It is recommended to fully initialize the Ethernet driver and network interface before registering the user's Ethernet/IP event handlers, i.e., register the event handlers as the last thing prior to starting the Ethernet driver. Such an approach ensures that Ethernet/IP events get executed first by the Ethernet driver or network interface so the system is in the expected state when executing the user's handlers.
|
||||
|
||||
.. _misc-operation-of-driver:
|
||||
|
||||
@ -421,7 +421,7 @@ Flow Control
|
||||
|
||||
Ethernet on MCU usually has a limitation in the number of frames it can handle during network congestion, because of the limitation in RAM size. A sending station might be transmitting data faster than the peer end can accept it. The ethernet flow control mechanism allows the receiving node to signal the sender requesting the suspension of transmissions until the receiver catches up. The magic behind that is the pause frame, which was defined in IEEE 802.3x.
|
||||
|
||||
Pause frame is a special Ethernet frame used to carry the pause command, whose EtherType field is 0x8808, with the Control opcode set to 0x0001. Only stations configured for full-duplex operation may send pause frames. When a station wishes to pause the other end of a link, it sends a pause frame to the 48-bit reserved multicast address of 01-80-C2-00-00-01. The pause frame also includes the period of pause time being requested, in the form of a two-byte integer, ranging from 0 to 65535.
|
||||
Pause frame is a special Ethernet frame used to carry the pause command, whose EtherType field is ``0x8808``, with the Control opcode set to ``0x0001``. Only stations configured for full-duplex operation may send pause frames. When a station wishes to pause the other end of a link, it sends a pause frame to the 48-bit reserved multicast address of ``01-80-C2-00-00-01``. The pause frame also includes the period of pause time being requested, in the form of a two-byte integer, ranging from ``0`` to ``65535``.
|
||||
|
||||
After the Ethernet driver installation, the flow control feature is disabled by default. You can enable it by:
|
||||
|
||||
@ -432,7 +432,7 @@ After the Ethernet driver installation, the flow control feature is disabled by
|
||||
bool flow_ctrl_enable = true;
|
||||
esp_eth_ioctl(eth_handle, ETH_CMD_S_FLOW_CTRL, &flow_ctrl_enable);
|
||||
|
||||
One thing that should be kept in mind is that the pause frame ability will be advertised to the peer end by PHY during auto-negotiation. The Ethernet driver sends a pause frame only when both sides of the link support it.
|
||||
One thing that should be kept in mind is that the pause frame ability is advertised to the peer end by PHY during auto-negotiation. The Ethernet driver sends a pause frame only when both sides of the link support it.
|
||||
|
||||
.. -------------------------------- Examples -----------------------------------
|
||||
|
||||
@ -460,7 +460,7 @@ There are multiple PHY manufacturers with wide portfolios of chips available. Th
|
||||
Luckily, a management interface between EMAC and PHY is standardized by IEEE 802.3 in Section 22.2.4 Management Functions. It defines provisions of the so-called “MII Management Interface” to control the PHY and gather status from the PHY. A set of management registers is defined to control chip behavior, link properties, auto-negotiation configuration, etc. This basic management functionality is addressed by :component_file:`esp_eth/src/esp_eth_phy_802_3.c` in ESP-IDF and so it makes the creation of a new custom PHY chip driver quite a simple task.
|
||||
|
||||
.. note::
|
||||
Always consult with PHY datasheet since some PHY chips may not comply with IEEE 802.3, Section 22.2.4. It does not mean you are not able to create a custom PHY driver, it will just require more effort. You will have to define all PHY management functions.
|
||||
Always consult with PHY datasheet since some PHY chips may not comply with IEEE 802.3, Section 22.2.4. It does not mean you are not able to create a custom PHY driver, but it just requires more effort. You will have to define all PHY management functions.
|
||||
|
||||
The majority of PHY management functionality required by the ESP-IDF Ethernet driver is covered by the :component_file:`esp_eth/src/esp_eth_phy_802_3.c`. However, the following may require developing chip-specific management functions:
|
||||
|
||||
|
@ -3,7 +3,7 @@ Wi-Fi Aware\ :sup:`TM` (NAN)
|
||||
|
||||
Wi-Fi Aware\ :sup:`TM` or NAN (Neighbor Awareness Networking) is a protocol that allows Wi-Fi devices to discover services in their proximity. Typically, location-based services are based on querying servers for information about the environment and the location knowledge is based on GPS or other location reckoning techniques. However NAN does not require real-time connection to servers, GPS or other geo-location, but instead uses direct device-to-device Wi-Fi to discover and exchange information. NAN scales effectively in dense Wi-Fi environments and complements the connectivity of Wi-Fi by providing information about people and services in the proximity.
|
||||
|
||||
Multiple NAN devices which are in the vicinity will form a NAN cluster which allows them to communicate with each other. Devices within a NAN cluster can advertise (Publish method) or look for (Subscribe method) services using NAN Service Discovery protocols. Matching of services is done by service name, once a match is found a device can either send a message or establish an IPv6 datapath with the peer.
|
||||
Multiple NAN devices which are in the vicinity form a NAN cluster which allows them to communicate with each other. Devices within a NAN cluster can advertise (Publish method) or look for (Subscribe method) services using NAN Service Discovery protocols. Matching of services is done by service name, once a match is found a device can either send a message or establish an IPv6 datapath with the peer.
|
||||
|
||||
{IDF_TARGET_NAME} supports Wi-Fi Aware in standalone mode with support for both Service Discovery and Datapath. Wi-Fi Aware is still an evolving protocol. Please refer to Wi-Fi Alliance's official page on `Wi-Fi Aware <https://www.wi-fi.org/discover-wi-fi/wi-fi-aware>`_ for more information. Many Android smartphones with Android 8 or higher support Wi-Fi Aware. Refer to Android's developer guide on Wi-Fi Aware `Wi-Fi Aware <https://www.wi-fi.org/discover-wi-fi/wi-fi-aware>`_ for more information.
|
||||
|
||||
|
@ -5,7 +5,7 @@ ESP-NETIF
|
||||
|
||||
The purpose of the ESP-NETIF library is twofold:
|
||||
|
||||
- It provides an abstraction layer for the application on top of the TCP/IP stack. This will allow applications to choose between IP stacks in the future.
|
||||
- It provides an abstraction layer for the application on top of the TCP/IP stack. This allows applications to choose between IP stacks in the future.
|
||||
- The APIs it provides are thread-safe, even if the underlying TCP/IP stack APIs are not.
|
||||
|
||||
ESP-IDF currently implements ESP-NETIF for the lwIP TCP/IP stack only. However, the adapter itself is TCP/IP implementation-agnostic and allows different implementations.
|
||||
@ -76,7 +76,7 @@ Data and Event Flow in the Diagram
|
||||
ESP-NETIF Interaction
|
||||
---------------------
|
||||
|
||||
A) User code, boilerplate
|
||||
A) User Code, Boilerplate
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Overall application interaction with a specific IO driver for communication media and configured TCP/IP network stack is abstracted using ESP-NETIF APIs and is outlined as below:
|
||||
@ -151,7 +151,7 @@ The ESP-NETIF L2 TAP interface is a mechanism in ESP-IDF used to access Data Lin
|
||||
|
||||
From a user perspective, the ESP-NETIF L2 TAP interface is accessed using file descriptors of VFS, which provides file-like interfacing (using functions like ``open()``, ``read()``, ``write()``, etc). To learn more, refer to :doc:`/api-reference/storage/vfs`.
|
||||
|
||||
There is only one ESP-NETIF L2 TAP interface device (path name) available. However multiple file descriptors with different configurations can be opened at a time since the ESP-NETIF L2 TAP interface can be understood as a generic entry point to the Layer 2 infrastructure. What is important is then the specific configuration of the particular file descriptor. It can be configured to give access to a specific Network Interface identified by ``if_key`` (e.g. `ETH_DEF`) and to filter only specific frames based on their type (e.g. Ethernet type in the case of IEEE 802.3). Filtering only specific frames is crucial since the ESP-NETIF L2 TAP needs to exist along with the IP stack and so the IP-related traffic (IP, ARP, etc.) should not be passed directly to the user application. Even though this option is still configurable, it is not recommended in standard use cases. Filtering is also advantageous from the perspective of the user’s application, as it only gets access to the frame types it is interested in, and the remaining traffic is either passed to other L2 TAP file descriptors or to the IP stack.
|
||||
There is only one ESP-NETIF L2 TAP interface device (path name) available. However multiple file descriptors with different configurations can be opened at a time since the ESP-NETIF L2 TAP interface can be understood as a generic entry point to the Layer 2 infrastructure. What is important is then the specific configuration of the particular file descriptor. It can be configured to give access to a specific Network Interface identified by ``if_key`` (e.g., `ETH_DEF`) and to filter only specific frames based on their type (e.g., Ethernet type in the case of IEEE 802.3). Filtering only specific frames is crucial since the ESP-NETIF L2 TAP needs to exist along with the IP stack and so the IP-related traffic (IP, ARP, etc.) should not be passed directly to the user application. Even though this option is still configurable, it is not recommended in standard use cases. Filtering is also advantageous from the perspective of the user's application, as it only gets access to the frame types it is interested in, and the remaining traffic is either passed to other L2 TAP file descriptors or to the IP stack.
|
||||
|
||||
ESP-NETIF L2 TAP Interface Usage Manual
|
||||
---------------------------------------
|
||||
@ -160,21 +160,21 @@ Initialization
|
||||
^^^^^^^^^^^^^^
|
||||
To be able to use the ESP-NETIF L2 TAP interface, it needs to be enabled in Kconfig by :ref:`CONFIG_ESP_NETIF_L2_TAP` first and then registered by :cpp:func:`esp_vfs_l2tap_intf_register()` prior usage of any VFS function.
|
||||
|
||||
open()
|
||||
^^^^^^
|
||||
``open()``
|
||||
^^^^^^^^^^
|
||||
Once the ESP-NETIF L2 TAP is registered, it can be opened at path name “/dev/net/tap”. The same path name can be opened multiple times up to :ref:`CONFIG_ESP_NETIF_L2_TAP_MAX_FDS` and multiple file descriptors with a different configuration may access the Data Link Layer frames.
|
||||
|
||||
The ESP-NETIF L2 TAP can be opened with the ``O_NONBLOCK`` file status flag to make sure the ``read()`` does not block. Note that the ``write()`` may block in the current implementation when accessing a Network interface since it is a shared resource among multiple ESP-NETIF L2 TAP file descriptors and IP stack, and there is currently no queuing mechanism deployed. The file status flag can be retrieved and modified using ``fcntl()``.
|
||||
|
||||
On success, ``open()`` returns the new file descriptor (a nonnegative integer). On error, -1 is returned, and ``errno`` is set to indicate the error.
|
||||
|
||||
ioctl()
|
||||
^^^^^^^
|
||||
``ioctl()``
|
||||
^^^^^^^^^^^
|
||||
The newly opened ESP-NETIF L2 TAP file descriptor needs to be configured prior to its usage since it is not bounded to any specific Network Interface and no frame type filter is configured. The following configuration options are available to do so:
|
||||
|
||||
* ``L2TAP_S_INTF_DEVICE`` - bounds the file descriptor to a specific Network Interface that is identified by its ``if_key``. ESP-NETIF Network Interface ``if_key`` is passed to ``ioctl()`` as the third parameter. Note that default Network Interfaces ``if_key``'s used in ESP-IDF can be found in :component_file:`esp_netif/include/esp_netif_defaults.h`.
|
||||
* ``L2TAP_S_DEVICE_DRV_HNDL`` - is another way to bound the file descriptor to a specific Network Interface. In this case, the Network interface is identified directly by IO Driver handle (e.g. :cpp:type:`esp_eth_handle_t` in case of Ethernet). The IO Driver handle is passed to ``ioctl()`` as the third parameter.
|
||||
* ``L2TAP_S_RCV_FILTER`` - sets the filter to frames with the type to be passed to the file descriptor. In the case of Ethernet frames, the frames are to be filtered based on the Length and Ethernet type field. In case the filter value is set less than or equal to 0x05DC, the Ethernet type field is considered to represent IEEE802.3 Length Field, and all frames with values in interval <0, 0x05DC> at that field will be passed to the file descriptor. The IEEE802.2 logical link control (LLC) resolution is then expected to be performed by the user’s application. In case the filter value is set greater than 0x05DC, the Ethernet type field is considered to represent protocol identification and only frames that are equal to the set value are to be passed to the file descriptor.
|
||||
* ``L2TAP_S_DEVICE_DRV_HNDL`` - is another way to bound the file descriptor to a specific Network Interface. In this case, the Network interface is identified directly by IO Driver handle (e.g., :cpp:type:`esp_eth_handle_t` in case of Ethernet). The IO Driver handle is passed to ``ioctl()`` as the third parameter.
|
||||
* ``L2TAP_S_RCV_FILTER`` - sets the filter to frames with the type to be passed to the file descriptor. In the case of Ethernet frames, the frames are to be filtered based on the Length and Ethernet type field. In case the filter value is set less than or equal to 0x05DC, the Ethernet type field is considered to represent IEEE802.3 Length Field, and all frames with values in interval <0, 0x05DC> at that field are passed to the file descriptor. The IEEE802.2 logical link control (LLC) resolution is then expected to be performed by the user's application. In case the filter value is set greater than 0x05DC, the Ethernet type field is considered to represent protocol identification and only frames that are equal to the set value are to be passed to the file descriptor.
|
||||
|
||||
All above-set configuration options have a getter counterpart option to read the current settings.
|
||||
|
||||
@ -182,20 +182,20 @@ All above-set configuration options have a getter counterpart option to read the
|
||||
The file descriptor needs to be firstly bounded to a specific Network Interface by ``L2TAP_S_INTF_DEVICE`` or ``L2TAP_S_DEVICE_DRV_HNDL`` to make ``L2TAP_S_RCV_FILTER`` option available.
|
||||
|
||||
.. note::
|
||||
VLAN-tagged frames are currently not recognized. If the user needs to process VLAN-tagged frames, they need a set filter to be equal to the VLAN tag (i.e. 0x8100 or 0x88A8) and process the VLAN-tagged frames in the user application.
|
||||
VLAN-tagged frames are currently not recognized. If the user needs to process VLAN-tagged frames, they need a set filter to be equal to the VLAN tag (i.e., 0x8100 or 0x88A8) and process the VLAN-tagged frames in the user application.
|
||||
|
||||
.. note::
|
||||
``L2TAP_S_DEVICE_DRV_HNDL`` is particularly useful when the user's application does not require the usage of an IP stack and so ESP-NETIF is not required to be initialized too. As a result, Network Interface cannot be identified by its ``if_key`` and hence it needs to be identified directly by its IO Driver handle.
|
||||
|
||||
| On success, ``ioctl()`` returns 0. On error, -1 is returned, and ``errno`` is set to indicate the error.
|
||||
| * EBADF - not a valid file descriptor.
|
||||
| * EACCES - options change is denied in this state (e.g. file descriptor has not been bounded to Network interface yet).
|
||||
| * EACCES - options change is denied in this state (e.g., file descriptor has not been bounded to Network interface yet).
|
||||
| * EINVAL - invalid configuration argument. Ethernet type filter is already used by other file descriptors on that same Network interface.
|
||||
| * ENODEV - no such Network Interface which is tried to be assigned to the file descriptor exists.
|
||||
| * ENOSYS - unsupported operation, passed configuration option does not exist.
|
||||
|
||||
fcntl()
|
||||
^^^^^^^
|
||||
``fcntl()``
|
||||
^^^^^^^^^^^
|
||||
``fcntl()`` is used to manipulate with properties of opened ESP-NETIF L2 TAP file descriptor.
|
||||
|
||||
The following commands manipulate the status flags associated with the file descriptor:
|
||||
@ -207,17 +207,17 @@ The following commands manipulate the status flags associated with the file desc
|
||||
| * EBADF - not a valid file descriptor.
|
||||
| * ENOSYS - unsupported command.
|
||||
|
||||
read()
|
||||
^^^^^^
|
||||
``read()``
|
||||
^^^^^^^^^^
|
||||
Opened and configured ESP-NETIF L2 TAP file descriptor can be accessed by ``read()`` to get inbound frames. The read operation can be either blocking or non-blocking based on the actual state of the ``O_NONBLOCK`` file status flag. When the file status flag is set to blocking, the read operation waits until a frame is received and the context is switched to other tasks. When the file status flag is set to non-blocking, the read operation returns immediately. In such case, either a frame is returned if it was already queued or the function indicates the queue is empty. The number of queued frames associated with one file descriptor is limited by :ref:`CONFIG_ESP_NETIF_L2_TAP_RX_QUEUE_SIZE` Kconfig option. Once the number of queued frames reached a configured threshold, the newly arrived frames are dropped until the queue has enough room to accept incoming traffic (Tail Drop queue management).
|
||||
|
||||
| On success, ``read()`` returns the number of bytes read. Zero is returned when the size of the destination buffer is 0. On error, -1 is returned, and ``errno`` is set to indicate the error.
|
||||
| * EBADF - not a valid file descriptor.
|
||||
| * EAGAIN - the file descriptor has been marked non-blocking (``O_NONBLOCK``), and the read would block.
|
||||
|
||||
write()
|
||||
^^^^^^^
|
||||
A raw Data Link Layer frame can be sent to Network Interface via opened and configured ESP-NETIF L2 TAP file descriptor. The user’s application is responsible to construct the whole frame except for fields which are added automatically by the physical interface device. The following fields need to be constructed by the user's application in case of an Ethernet link: source/destination MAC addresses, Ethernet type, actual protocol header, and user data. The length of these fields is as follows:
|
||||
``write()``
|
||||
^^^^^^^^^^^
|
||||
A raw Data Link Layer frame can be sent to Network Interface via opened and configured ESP-NETIF L2 TAP file descriptor. The user's application is responsible to construct the whole frame except for fields which are added automatically by the physical interface device. The following fields need to be constructed by the user's application in case of an Ethernet link: source/destination MAC addresses, Ethernet type, actual protocol header, and user data. The length of these fields is as follows:
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
@ -240,15 +240,15 @@ In other words, there is no additional frame processing performed by the ESP-NET
|
||||
| * EBADMSG - The Ethernet type of the frame is different from the file descriptor configured filter.
|
||||
| * EIO - Network interface not available or busy.
|
||||
|
||||
close()
|
||||
^^^^^^^
|
||||
``close()``
|
||||
^^^^^^^^^^^
|
||||
Opened ESP-NETIF L2 TAP file descriptor can be closed by the ``close()`` to free its allocated resources. The ESP-NETIF L2 TAP implementation of ``close()`` may block. On the other hand, it is thread-safe and can be called from a different task than the file descriptor is actually used. If such a situation occurs and one task is blocked in the I/O operation and another task tries to close the file descriptor, the first task is unblocked. The first's task read operation then ends with an error.
|
||||
|
||||
| On success, ``close()`` returns zero. On error, -1 is returned, and ``errno`` is set to indicate the error.
|
||||
| * EBADF - not a valid file descriptor.
|
||||
|
||||
select()
|
||||
^^^^^^^^
|
||||
``select()``
|
||||
^^^^^^^^^^^^
|
||||
Select is used in a standard way, just :ref:`CONFIG_VFS_SUPPORT_SELECT` needs to be enabled to make the ``select()`` function available.
|
||||
|
||||
|
||||
@ -262,7 +262,7 @@ You can find a brief introduction to SNTP in general, its initialization code, a
|
||||
This section provides more details about specific use cases of the SNTP service, with statically configured servers, or use the DHCP-provided servers, or both. The workflow is usually very simple:
|
||||
|
||||
1) Initialize and configure the service using :cpp:func:`esp_netif_sntp_init()`.
|
||||
2) Start the service via :cpp:func:`esp_netif_sntp_start()`. This step is not needed if we auto-started the service in the previous step (default). It's useful to start the service explicitly after connecting if we want to use the DHCP-obtained NTP servers. Please note, this option needs to be enabled before connecting, but the SNTP service should be started after.
|
||||
2) Start the service via :cpp:func:`esp_netif_sntp_start()`. This step is not needed if we auto-started the service in the previous step (default). It is useful to start the service explicitly after connecting if we want to use the DHCP-obtained NTP servers. Please note, this option needs to be enabled before connecting, but the SNTP service should be started after.
|
||||
3) Wait for the system time to synchronize using :cpp:func:`esp_netif_sntp_sync_wait()` (only if needed).
|
||||
4) Stop and destroy the service using :cpp:func:`esp_netif_sntp_deinit()`.
|
||||
|
||||
@ -270,7 +270,7 @@ This section provides more details about specific use cases of the SNTP service,
|
||||
Basic Mode with Statically Defined Server(s)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Initialize the module with the default configuration after connecting to the network. Note that it's possible to provide multiple NTP servers in the configuration struct:
|
||||
Initialize the module with the default configuration after connecting to the network. Note that it is possible to provide multiple NTP servers in the configuration struct:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
@ -295,7 +295,7 @@ First of all, we have to enable the lwIP configuration option :ref:`CONFIG_LWIP_
|
||||
config.server_from_dhcp = true; // accept the NTP offer from the DHCP server
|
||||
esp_netif_sntp_init(&config);
|
||||
|
||||
Then, once we're connected, we could start the service using:
|
||||
Then, once we are connected, we could start the service using:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
@ -303,7 +303,7 @@ Then, once we're connected, we could start the service using:
|
||||
|
||||
.. note::
|
||||
|
||||
It's also possible to start the service during initialization (default ``config.start=true``). This would likely to cause the initial SNTP request to fail (since we are not connected yet) and lead to some back-off time for subsequent requests.
|
||||
It is also possible to start the service during initialization (default ``config.start=true``). This would likely to cause the initial SNTP request to fail (since we are not connected yet) and lead to some back-off time for subsequent requests.
|
||||
|
||||
|
||||
Use Both Static and Dynamic Servers
|
||||
@ -359,7 +359,7 @@ For more specific cases, please consult this guide: :doc:`/api-reference/network
|
||||
|
||||
* :cpp:func:`esp_netif_create_default_wifi_ap()`
|
||||
|
||||
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, as a consequence, which means that:
|
||||
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, as a consequence, which means that:
|
||||
|
||||
* The created object has to be destroyed if a network de-initialization is provided by an application using :cpp:func:`esp_netif_destroy_default_wifi()`.
|
||||
|
||||
|
@ -2,12 +2,11 @@ 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.
|
||||
|
||||
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
|
||||
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:
|
||||
@ -16,25 +15,21 @@ As shown in the diagram, the following three API functions for the packet data p
|
||||
* :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 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.
|
||||
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
|
||||
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:
|
||||
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
|
||||
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
|
||||
@ -49,9 +44,8 @@ As a consequence the I/O driver has to create an instance of the struct per belo
|
||||
} 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:
|
||||
|
||||
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
|
||||
|
||||
@ -70,11 +64,10 @@ as well in the post-attach callback. An example of a simple post-attach callback
|
||||
}
|
||||
|
||||
|
||||
Default handlers
|
||||
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.
|
||||
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
|
||||
@ -87,15 +80,13 @@ An example of such a default handler is provided below:
|
||||
}
|
||||
|
||||
|
||||
Network stack connection
|
||||
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 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.
|
||||
|
||||
Note, that IDF provides several network stack configurations for the most common network interfaces, such as for the WiFi station or Ethernet.
|
||||
These configurations are defined in :component_file:`esp_netif/include/esp_netif_defaults.h` and should be sufficient for most network drivers.
|
||||
(In rare cases, expert users might want to define custom lwIP based interface layers; it is possible, but an explicit dependency to lwIP needs to be set)
|
||||
Note, that ESP-IDF provides several network stack configurations for the most common network interfaces, such as for the WiFi station or Ethernet.
|
||||
These configurations are defined in :component_file:`esp_netif/include/esp_netif_defaults.h` and should be sufficient for most network drivers. (In rare cases, expert users might want to define custom lwIP based interface layers; it is possible, but an explicit dependency to lwIP needs to be set)
|
||||
|
||||
The following API reference outlines these network stack interaction with the esp-netif:
|
||||
|
||||
|
@ -6,8 +6,9 @@ ESP-NOW
|
||||
Overview
|
||||
--------
|
||||
|
||||
ESP-NOW is a kind of connectionless Wi-Fi communication protocol that is defined by Espressif. In ESP-NOW, application data is encapsulated in a vendor-specific action frame and then transmitted from one Wi-Fi device to another without connection.
|
||||
CTR with CBC-MAC Protocol(CCMP) is used to protect the action frame for security. ESP-NOW is widely used in smart light, remote controlling, sensor, etc.
|
||||
ESP-NOW is a kind of connectionless Wi-Fi communication protocol that is defined by Espressif. In ESP-NOW, application data is encapsulated in a vendor-specific action frame and then transmitted from one Wi-Fi device to another without connection.
|
||||
|
||||
CTR with CBC-MAC Protocol (CCMP) is used to protect the action frame for security. ESP-NOW is widely used in smart light, remote controlling, sensor, etc.
|
||||
|
||||
Frame Format
|
||||
------------
|
||||
@ -23,7 +24,7 @@ ESP-NOW uses a vendor-specific action frame to transmit ESP-NOW data. The defaul
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
24 bytes 1 byte 3 bytes 4 bytes 7~257 bytes 4 bytes
|
||||
|
||||
- Category Code: The Category Code field is set to the value(127) indicating the vendor-specific category.
|
||||
- Category Code: The Category Code field is set to the value (127) indicating the vendor-specific category.
|
||||
- Organization Identifier: The Organization Identifier contains a unique identifier (0x18fe34), which is the first three bytes of MAC address applied by Espressif.
|
||||
- Random Value: The Random Value filed is used to prevents relay attacks.
|
||||
- Vendor Specific Content: The Vendor Specific Content contains vendor-specific fields as follows:
|
||||
@ -39,7 +40,7 @@ ESP-NOW uses a vendor-specific action frame to transmit ESP-NOW data. The defaul
|
||||
|
||||
- Element ID: The Element ID field is set to the value (221), indicating the vendor-specific element.
|
||||
- Length: The length is the total length of Organization Identifier, Type, Version and Body.
|
||||
- Organization Identifier: The Organization Identifier contains a unique identifier(0x18fe34), which is the first three bytes of MAC address applied by Espressif.
|
||||
- Organization Identifier: The Organization Identifier contains a unique identifier (0x18fe34), which is the first three bytes of MAC address applied by Espressif.
|
||||
- Type: The Type field is set to the value (4) indicating ESP-NOW.
|
||||
- Version: The Version field is set to the version of ESP-NOW.
|
||||
- Body: The Body contains the ESP-NOW data.
|
||||
@ -49,22 +50,24 @@ As ESP-NOW is connectionless, the MAC header is a little different from that of
|
||||
Security
|
||||
--------
|
||||
|
||||
ESP-NOW uses the CCMP method, which is described in IEEE Std. 802.11-2012, to protect the vendor-specific action frame. The Wi-Fi device maintains a Primary Master Key (PMK) and several Local Master Keys (LMK). The lengths of both PMK and LMk are 16 bytes.
|
||||
* PMK is used to encrypt LMK with the AES-128 algorithm. Call :cpp:func:`esp_now_set_pmk()` to set PMK. If PMK is not set, a default PMK will be used.
|
||||
ESP-NOW uses the CCMP method, which is described in IEEE Std. 802.11-2012, to protect the vendor-specific action frame. The Wi-Fi device maintains a Primary Master Key (PMK) and several Local Master Keys (LMK). The lengths of both PMK and LMk are 16 bytes.
|
||||
|
||||
* PMK is used to encrypt LMK with the AES-128 algorithm. Call :cpp:func:`esp_now_set_pmk()` to set PMK. If PMK is not set, a default PMK will be used.
|
||||
* LMK of the paired device is used to encrypt the vendor-specific action frame with the CCMP method. The maximum number of different LMKs is six. If the LMK of the paired device is not set, the vendor-specific action frame will not be encrypted.
|
||||
|
||||
|
||||
Encrypting multicast vendor-specific action frame is not supported.
|
||||
|
||||
Initialization and De-initialization
|
||||
Initialization and Deinitialization
|
||||
------------------------------------
|
||||
|
||||
Call :cpp:func:`esp_now_init()` to initialize ESP-NOW and :cpp:func:`esp_now_deinit()` to de-initialize ESP-NOW. ESP-NOW data must be transmitted after Wi-Fi is started, so it is recommended to start Wi-Fi before initializing ESP-NOW and stop Wi-Fi after de-initializing ESP-NOW.
|
||||
When :cpp:func:`esp_now_deinit()` is called, all of the information of paired devices will be deleted.
|
||||
|
||||
When :cpp:func:`esp_now_deinit()` is called, all of the information of paired devices are deleted.
|
||||
|
||||
Add Paired Device
|
||||
-----------------
|
||||
|
||||
Call :cpp:func:`esp_now_add_peer()` to add the device to the paired device list before you send data to this device. If security is enabled, the LMK must be set. You can send ESP-NOW data via both the Station and the SoftAP interface. Make sure that the interface is enabled before sending ESP-NOW data.
|
||||
Call :cpp:func:`esp_now_add_peer()` to add the device to the paired device list before you send data to this device. If security is enabled, the LMK must be set. You can send ESP-NOW data via both the Station and the SoftAP interface. Make sure that the interface is enabled before sending ESP-NOW data.
|
||||
|
||||
.. only:: esp32c2
|
||||
|
||||
@ -79,7 +82,7 @@ A device with a broadcast MAC address must be added before sending broadcast dat
|
||||
Send ESP-NOW Data
|
||||
-----------------
|
||||
|
||||
Call :cpp:func:`esp_now_send()` to send ESP-NOW data and :cpp:func:`esp_now_register_send_cb()` to register sending callback function. It will return `ESP_NOW_SEND_SUCCESS` in sending callback function if the data is received successfully on the MAC layer. Otherwise, it will return `ESP_NOW_SEND_FAIL`. Several reasons can lead to ESP-NOW fails to send data. For example, the destination device doesn't exist; the channels of the devices are not the same; the action frame is lost when transmitting on the air, etc. It is not guaranteed that application layer can receive the data. If necessary, send back ack data when receiving ESP-NOW data. If receiving ack data timeouts, retransmit the ESP-NOW data. A sequence number can also be assigned to ESP-NOW data to drop the duplicate data.
|
||||
Call :cpp:func:`esp_now_send()` to send ESP-NOW data and :cpp:func:`esp_now_register_send_cb()` to register sending callback function. It will return `ESP_NOW_SEND_SUCCESS` in sending callback function if the data is received successfully on the MAC layer. Otherwise, it will return `ESP_NOW_SEND_FAIL`. Several reasons can lead to ESP-NOW fails to send data. For example, the destination device does not exist; the channels of the devices are not the same; the action frame is lost when transmitting on the air, etc. It is not guaranteed that application layer can receive the data. If necessary, send back ack data when receiving ESP-NOW data. If receiving ack data timeouts, retransmit the ESP-NOW data. A sequence number can also be assigned to ESP-NOW data to drop the duplicate data.
|
||||
|
||||
If there is a lot of ESP-NOW data to send, call :cpp:func:`esp_now_send()` to send less than or equal to 250 bytes of data once a time. Note that too short interval between sending two ESP-NOW data may lead to disorder of sending callback function. So, it is recommended that sending the next ESP-NOW data after the sending callback function of the previous sending has returned. The sending callback function runs from a high-priority Wi-Fi task. So, do not do lengthy operations in the callback function. Instead, post the necessary data to a queue and handle it from a lower priority task.
|
||||
|
||||
@ -94,7 +97,7 @@ Config ESP-NOW Rate
|
||||
|
||||
.. only:: esp32 or esp32s2 or esp32s3 or esp32c2 or esp32c3
|
||||
|
||||
Call :cpp:func:`esp_wifi_config_espnow_rate()` to config ESPNOW rate of specified interface. Make sure that the interface is enabled before config rate. This API should be called after :cpp:func:`esp_wifi_start()`.
|
||||
Call :cpp:func:`esp_wifi_config_espnow_rate()` to config ESP-NOW rate of specified interface. Make sure that the interface is enabled before config rate. This API should be called after :cpp:func:`esp_wifi_start()`.
|
||||
|
||||
.. only:: esp32c6
|
||||
|
||||
@ -111,7 +114,7 @@ Sleep is supported only when {IDF_TARGET_NAME} is configured as station.
|
||||
|
||||
Call :cpp:func:`esp_now_set_wake_window()` to configure Window for ESP-NOW RX at sleep. The default value is the maximum, which allowing RX all the time.
|
||||
|
||||
If Power-saving is needed for ESP-NOW, call :cpp:func:`esp_wifi_connectionless_module_set_wake_interval()` to configure Interval as well.
|
||||
If Power-saving is needed for ESP-NOW, call :cpp:func:`esp_wifi_connectionless_module_set_wake_interval()` to configure Interval as well.
|
||||
|
||||
.. only:: SOC_WIFI_SUPPORTED
|
||||
|
||||
|
@ -4,7 +4,7 @@ Thread
|
||||
Introduction
|
||||
------------
|
||||
|
||||
`Thread <https://www.threadgroup.org>`_ is a IP-based mesh networking protocol. It's based on the 802.15.4 physical and MAC layer.
|
||||
`Thread <https://www.threadgroup.org>`_ is a IP-based mesh networking protocol. It is based on the 802.15.4 physical and MAC layer.
|
||||
|
||||
Application Examples
|
||||
--------------------
|
||||
@ -19,10 +19,10 @@ The :example:`openthread` directory of ESP-IDF examples contains the following a
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
For manipulating the Thread network, the OpenThread api shall be used.
|
||||
The OpenThread api docs can be found at the `OpenThread official website <https://openthread.io/reference>`_.
|
||||
For manipulating the Thread network, the OpenThread API shall be used.
|
||||
The OpenThread API docs can be found at the `OpenThread official website <https://openthread.io/reference>`_.
|
||||
|
||||
ESP-IDF provides extra apis for launching and managing the OpenThread stack, binding to network interfaces and border routing features.
|
||||
ESP-IDF provides extra APIs for launching and managing the OpenThread stack, binding to network interfaces and border routing features.
|
||||
|
||||
.. include-build-file:: inc/esp_openthread.inc
|
||||
.. include-build-file:: inc/esp_openthread_types.inc
|
||||
|
@ -43,6 +43,7 @@ Thread
|
||||
esp_openthread
|
||||
|
||||
Thread is an IPv6-based mesh networking technology for IoT.
|
||||
|
||||
Code examples for the Thread API are provided in the :example:`openthread` directory of ESP-IDF examples.
|
||||
|
||||
ESP-NETIF
|
||||
@ -63,7 +64,7 @@ IP Network Layer
|
||||
|
||||
Code examples for TCP/IP socket APIs are provided in the :example:`protocols/sockets` directory of ESP-IDF examples.
|
||||
|
||||
Application Layer
|
||||
Application Layer
|
||||
=================
|
||||
|
||||
Documentation for Application layer network protocols (above the IP Network layer) are provided in :doc:`../protocols/index`.
|
||||
|
@ -63,7 +63,7 @@ API Reference
|
||||
|
||||
2. Update is done on each documentation build by invoking Sphinx extension :`esp_extensions/run_doxygen.py` for all header files listed in the ``INPUT`` statement of :idf_file:`docs/doxygen/Doxyfile`.
|
||||
|
||||
3. Each line of the ``INPUT`` statement (other than a comment that begins with ``##``) contains a path to header file ``*.h`` that will be used to generate corresponding ``*.inc`` files::
|
||||
3. Each line of the ``INPUT`` statement (other than a comment that begins with ``##``) contains a path to header file ``*.h`` that is used to generate corresponding ``*.inc`` files::
|
||||
|
||||
##
|
||||
## Wi-Fi - API Reference
|
||||
@ -73,7 +73,7 @@ API Reference
|
||||
|
||||
4. When the headers are expanded, any macros defined by default in ``sdkconfig.h`` as well as any macros defined in SOC-specific ``include/soc/*_caps.h`` headers will be expanded. This allows the headers to include/exclude material based on the ``IDF_TARGET`` value.
|
||||
|
||||
5. The ``*.inc`` files contain formatted reference of API members generated automatically on each documentation build. All ``*.inc`` files are placed in Sphinx ``_build`` directory. To see directives generated for e.g. ``esp_wifi.h``, run ``python gen-dxd.py esp32/include/esp_wifi.h``.
|
||||
5. The ``*.inc`` files contain formatted reference of API members generated automatically on each documentation build. All ``*.inc`` files are placed in Sphinx ``_build`` directory. To see directives generated for e.g., ``esp_wifi.h``, run ``python gen-dxd.py esp32/include/esp_wifi.h``.
|
||||
|
||||
6. To show contents of ``*.inc`` file in documentation, include it as follows::
|
||||
|
||||
|
@ -137,7 +137,7 @@ ESP-IDF 无法确保版本间的二进制兼容性。这意味着,如果使用
|
||||
其他不兼容情况
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
尽管我们致力于让 ESP-IDF 版本升级更加容易,但是在次要版本之间,ESP-IDF 的某些部分可能会以不兼容的方式发生更改。如有不属于下列情况的意外重大更新,欢迎向我们发送报告:
|
||||
尽管我们致力于优化 ESP-IDF 版本升级,但是在次要版本之间,ESP-IDF 的某些部分可能会不兼容。如有不属于下列情况的意外重大更新,欢迎向我们发送报告:
|
||||
|
||||
* :ref:`api_reference_private_apis`。
|
||||
* :ref:`api_reference_example_components`。
|
||||
|
@ -5,7 +5,7 @@
|
||||
简介
|
||||
=====
|
||||
|
||||
ESP-IDF 使用基于 kconfiglib_ 的 esp-idf-kconfig_ 包,而 kconfiglib_ 是 Kconfig_ 系统的 Python 扩展。 Kconfig 提供了编译时的项目配置机制,以及多种类型的配置选项(如整数、字符串和布尔值等)。Kconfig 文件指定了选项之间的依赖关系、默认值、组合方式等。
|
||||
ESP-IDF 使用基于 kconfiglib_ 的 esp-idf-kconfig_ 包,而 kconfiglib_ 是 Kconfig_ 系统的 Python 扩展。Kconfig 提供了编译时的项目配置机制,以及多种类型的配置选项(如整数、字符串和布尔值等)。Kconfig 文件指定了选项之间的依赖关系、默认值、组合方式等。
|
||||
|
||||
了解所有可用功能,请查看 Kconfig_ 和 `kconfiglib 扩展`_。
|
||||
|
||||
@ -21,7 +21,7 @@ ESP-IDF 使用基于 kconfiglib_ 的 esp-idf-kconfig_ 包,而 kconfiglib_ 是
|
||||
使用 sdkconfig.defaults
|
||||
==============================
|
||||
|
||||
在某些情况下,例如 ``sdkconfig`` 文件处于版本控制状态时,构建系统可能会不便于更改 ``sdkconfig`` 文件。在构建系统中创建 ``sdkconfig.defaults`` 文件可以避免上述情况发生。该文件可以手动或自动创建,且永远不会被构建系统更改。该文件包含所有不同于默认选项的重要选项,其格式与 ``sdkconfig`` 文件格式相同。如果用户记得所有已更改的配置则可以手动创建 ``sdkconfig.defaults``,或者运行 ``idf.py save-defconfig`` 命令来自动生成此文件。
|
||||
在某些情况下,例如 ``sdkconfig`` 文件处于版本控制状态时,构建系统可能会不便于更改 ``sdkconfig`` 文件。要避免上述情况,可以在构建系统中创建 ``sdkconfig.defaults`` 文件。该文件可以手动或自动创建,且构建系统永远不会对其进行更改。该文件包含所有不同于默认选项的重要选项,其格式与 ``sdkconfig`` 文件格式相同。如果用户记得所有已更改的配置,则可以手动创建 ``sdkconfig.defaults``,或运行 ``idf.py save-defconfig`` 命令来自动生成此文件。
|
||||
|
||||
``sdkconfig.defaults`` 创建后,用户可以删除 ``sdkconfig`` 或将其添加到版本控制系统的忽略列表中(例如 ``git`` 的 ``.gitignore`` 文件)。项目构建目标将自动创建 ``sdkconfig`` 文件,填充 ``sdkconfig.defaults`` 文件中的设置,并将其他设置配置为默认值。请注意,构建时 ``sdkconfig.defaults`` 中的设置不会覆盖 ``sdkconfig`` 的已有设置。了解更多信息,请查看 :ref:`custom-sdkconfig-defaults`。
|
||||
|
||||
@ -31,14 +31,14 @@ Kconfig 格式规定
|
||||
Kconfig 文件的格式规定如下:
|
||||
|
||||
- 在所有菜单中,选项名称的前缀需保持一致。目前,前缀长度应为至少 3 个字符。
|
||||
- 每级采用 4 个空格的缩进方式,子项需比父项多缩进一级。例如, ``menu`` 缩进 0 个空格, ``menu`` 中的 ``config`` 则缩进 4 个空格, ``config`` 中的 ``help`` 缩进 8 个空格, ``help`` 下的文本缩进 12 个空格。
|
||||
- 每级采用 4 个空格的缩进方式,子项需比父项多缩进一级。例如, ``menu`` 缩进 0 个空格,``menu`` 中的 ``config`` 则缩进 4 个空格, ``config`` 中的 ``help`` 缩进 8 个空格, ``help`` 下的文本缩进 12 个空格。
|
||||
- 行末不得出现尾随空格。
|
||||
- 选项最长为 40 个字符。
|
||||
- 每行最长为 120 个字符。
|
||||
|
||||
.. note::
|
||||
|
||||
菜单中不同配置的 ``help`` 小节将被视为 reStructuredText 格式,以便生成相应选项的参考文档。
|
||||
菜单中不同配置的 ``help`` 小节默认视为 reStructuredText 格式,以便生成相应选项的参考文档。
|
||||
|
||||
格式检查器
|
||||
--------------
|
||||
@ -50,7 +50,7 @@ Kconfig 文件的格式规定如下:
|
||||
Kconfig 选项的向后兼容性
|
||||
================================
|
||||
|
||||
标准 Kconfig_ 工具会忽略 ``sdkconfig`` 中的未知选项。因此,如果开发人员对某些选项进行了自定义设置,但这些选项在 ESP-IDF 新版本中被重命名,原有设置将被忽略。以下功能可以避免上述情况发生:
|
||||
标准 Kconfig_ 工具会忽略 ``sdkconfig`` 中的未知选项。因此,如果开发人员对某些选项进行了自定义设置,但这些选项在 ESP-IDF 新版本中重新命名,标准 Kconfig_ 工具将忽略原有设置。以下功能可以避免上述情况:
|
||||
|
||||
1. 工具链使用 ``kconfgen`` 预处理 ``sdkconfig`` 文件。例如, ``menuconfig`` 会读取这些文件,从而保留旧选项设置。
|
||||
2. ``kconfgen`` 递归查找 ESP-IDF 目录中所有包含新旧 Kconfig 选项名称的 ``sdkconfig.rename`` 文件。在 ``sdkconfig`` 文件中,新选项将替换旧选项。针对单个目标的重命名可以放在特定目标的重命名文件 ``sdkconfig.rename.TARGET`` 中,其中 ``TARGET`` 是目标名称,例如 ``sdkconfig.rename.esp32s2``。
|
||||
|
@ -3,7 +3,7 @@ ESP-WIFI-MESH 编程指南
|
||||
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
这是 ESP-WIFI-MESH 的编程指南,包括 API 参考和编码示例。本指南分为以下部分:
|
||||
本文是 ESP-WIFI-MESH 的编程指南,包括 API 参考和编码示例。本指南分为以下部分:
|
||||
|
||||
1. :ref:`mesh-programming-model`
|
||||
|
||||
@ -58,6 +58,7 @@ ESP-WIFI-MESH 软件栈基于 Wi-Fi 驱动程序和 FreeRTOS 构建,某些情
|
||||
Mesh 事件的典型应用场景包括:使用 :cpp:enumerator:`MESH_EVENT_PARENT_CONNECTED` 和 :cpp:enumerator:`MESH_EVENT_CHILD_CONNECTED` 事件来指示节点何时可以分别开始传输上行和下行的数据。同样,也可以使用 :cpp:enumerator:`IP_EVENT_STA_GOT_IP` 和 :cpp:enumerator:`IP_EVENT_STA_LOST_IP` 事件来指示根节点何时可以向外部 IP 网络传输数据。
|
||||
|
||||
.. warning::
|
||||
|
||||
在自组网模式下使用 ESP-WIFI-MESH 时,用户必须确保不得调用 Wi-Fi API。原因在于:自组网模式将在内部调用 Wi-Fi API 实现连接/断开/扫描等操作。 **此时,如果外部应用程序调用 Wi-Fi API(包括来自回调函数和 Wi-Fi 事件处理程序的调用)都可能会干扰 ESP-WIFI-MESH 的自组网行为**。因此,用户不应该在 :cpp:func:`esp_mesh_start` 和 :cpp:func:`esp_mesh_stop` 之间调用 Wi-Fi API。
|
||||
|
||||
LwIP & ESP-WIFI-MESH
|
||||
@ -68,7 +69,7 @@ LwIP & ESP-WIFI-MESH
|
||||
**可成为根节点的每个节点都需要通过调用** :cpp:func:`esp_netif_init` **来初始化 LwIP 软件栈**。为了防止非根节点访问 LwIP,应用程序不应使用 esp_netif API 创建或注册任何网络接口。
|
||||
|
||||
|
||||
ESP-WIFI-MESH 的根节点必须与路由器连接。因此,当一个节点成为根节点时,**该节点对应的处理程序必须启动 DHCP 客户端服务并立即获取 IP 地址。** 这样做将允许其他节点开始向/从外部 IP 网络发送/接收数据包。但是,如果使用静态 IP 设置,则不需要执行此步骤。
|
||||
ESP-WIFI-MESH 的根节点必须与路由器连接。因此,当一个节点成为根节点时,**该节点对应的处理程序必须启动 DHCP 客户端服务并立即获取 IP 地址**。这样做将允许其他节点开始向/从外部 IP 网络发送/接收数据包。如果使用静态 IP 设置,则不需要执行此步骤。
|
||||
|
||||
|
||||
.. ---------------------- Writing a Mesh Application --------------------------
|
||||
@ -84,13 +85,13 @@ ESP-WIFI-MESH 在正常启动前必须先初始化 LwIP 和 Wi-Fi 软件栈。
|
||||
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
|
||||
/*事件初始化*/
|
||||
/* 事件初始化 */
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
|
||||
/*Wi-Fi 初始化 */
|
||||
/* Wi-Fi 初始化 */
|
||||
wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
|
||||
ESP_ERROR_CHECK(esp_wifi_init(&config));
|
||||
/*注册 IP 事件处理程序 */
|
||||
/* 注册 IP 事件处理程序 */
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &ip_event_handler, NULL));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_FLASH));
|
||||
ESP_ERROR_CHECK(esp_wifi_start());
|
||||
@ -110,9 +111,9 @@ ESP-WIFI-MESH 在正常启动前必须先初始化 LwIP 和 Wi-Fi 软件栈。
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/*Mesh 初始化 */
|
||||
/* Mesh 初始化 */
|
||||
ESP_ERROR_CHECK(esp_mesh_init());
|
||||
/*注册 mesh 事件处理程序 */
|
||||
/* 注册 mesh 事件处理程序 */
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(MESH_EVENT, ESP_EVENT_ANY_ID, &mesh_event_handler, NULL));
|
||||
|
||||
.. _mesh-configuring-mesh:
|
||||
@ -197,7 +198,7 @@ ESP-WIFI-MESH 可通过 :cpp:func:`esp_mesh_set_config` 进行配置,并使用
|
||||
- 选择首选的父节点(见 :ref:`mesh-building-a-network` 中的 **父节点选择**)
|
||||
- 网络断开时自动重新连接(见 :ref:`mesh-managing-a-network` 中的 **中间父节点失败**)
|
||||
|
||||
启用自组网功能后,ESP-WIFI-MESH 软件栈将内部调用 Wi-Fi API。因此,**在启用自组网功能时,应用层不得调用 Wi-Fi API,否则会干扰 ESP-WIFI-MESH 的工作。**
|
||||
启用自组网功能后,ESP-WIFI-MESH 软件栈将内部调用 Wi-Fi API。因此,**在启用自组网功能时,应用层不得调用 Wi-Fi API,否则会干扰 ESP-WIFI-MESH 的工作**。
|
||||
|
||||
开关自组网
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -262,7 +263,7 @@ ESP-WIFI-MESH 将尝试在启用自组网时保持节点的当前 Wi-Fi 状态
|
||||
调用 Wi-Fi API
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
在有些情况下,应用程序可能希望在使用 ESP-WIFI-MESH 期间调用 Wi-Fi API。例如,应用程序可能需要手动扫描邻近的接入点 (AP)。**但在应用程序调用任何 Wi-Fi API 之前,必须先禁用自组网。** 否则,ESP-WIFI-MESH 软件栈可能会同时调用 Wi-Fi API,进而影响应用程序的正常调用。
|
||||
在有些情况下,应用程序可能希望在使用 ESP-WIFI-MESH 期间调用 Wi-Fi API。例如,应用程序可能需要手动扫描邻近的接入点 (AP)。**但在应用程序调用任何 Wi-Fi API 之前,必须先禁用自组网**。 否则,ESP-WIFI-MESH 软件栈可能会同时调用 Wi-Fi API,进而影响应用程序的正常调用。
|
||||
|
||||
应用程序不应在 :cpp:func:`esp_mesh_set_self_organized` 之间调用 Wi-Fi API。下方代码片段展示了应用程序如何在 ESP-WIFI-MESH 运行期间安全地调用 :cpp:func:`esp_wifi_scan_start`。
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
以太网
|
||||
=========
|
||||
|
||||
:link_to_translation:`en:[英文]`
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
.. -------------------------------- Overview -----------------------------------
|
||||
|
||||
@ -113,13 +113,13 @@ ESP-IDF 提供一系列功能强大且兼具一致性的 API,为内部以太
|
||||
|
||||
MII 和 RMII 的一个明显区别在于其所需的信号数。MII 通常需要多达 18 个信号,RMII 接口则仅需要 9 个信号。
|
||||
|
||||
在 RMII 模式下,接收器和发射器信号的参考时钟为 ``REF_CLK``。 **在访问 PHY 和 MAC 时,REF_CLK 必须保持稳定**。一般来说,根据您设计中 PHY 设备的特征,可通过以下三种方式生成 ``REF_CLK``:
|
||||
在 RMII 模式下,接收器和发射器信号的参考时钟为 ``REF_CLK``。 **在访问 PHY 和 MAC 时,REF_CLK 必须保持稳定**。一般来说,根据设计中 PHY 设备的特征,可通过以下三种方式生成 ``REF_CLK``:
|
||||
|
||||
* 一些 PHY 芯片可以从其外部连接的 25 MHz 晶体振荡器中获取 ``REF_CLK`` (如图中的选项 *a* 所示)。对于此类芯片,请在 :ref:`CONFIG_ETH_RMII_CLK_MODE` 中选择 ``CONFIG_ETH_RMII_CLK_INPUT``。
|
||||
* 一些 PHY 芯片可以从其外部连接的 25 MHz 晶体振荡器中获取 ``REF_CLK`` (如图中的选项 **a** 所示)。对于此类芯片,请在 :ref:`CONFIG_ETH_RMII_CLK_MODE` 中选择 ``CONFIG_ETH_RMII_CLK_INPUT``。
|
||||
|
||||
* 一些 PHY 芯片使用可以作为 MAC 端 ``REF_CLK`` 的外接 50 MHz 晶体振荡器或其他时钟源(如图中的选项 *b* 所示)。对于此类芯片,请同样在 :ref:`CONFIG_ETH_RMII_CLK_MODE` 中选择 ``CONFIG_ETH_RMII_CLK_INPUT``。
|
||||
* 一些 PHY 芯片使用可以作为 MAC 端 ``REF_CLK`` 的外接 50 MHz 晶体振荡器或其他时钟源(如图中的选项 **b** 所示)。对于此类芯片,请同样在 :ref:`CONFIG_ETH_RMII_CLK_MODE` 中选择 ``CONFIG_ETH_RMII_CLK_INPUT``。
|
||||
|
||||
* 一些 EMAC 控制器可以使用其内部的高精度 PLL 生成 ``REF_CLK`` (如图中的选项 *c* 所示)。此种情况下,请在 :ref:`CONFIG_ETH_RMII_CLK_MODE` 中选择 ``CONFIG_ETH_RMII_CLK_OUTPUT``。
|
||||
* 一些 EMAC 控制器可以使用其内部的高精度 PLL 生成 ``REF_CLK`` (如图中的选项 **c** 所示)。此种情况下,请在 :ref:`CONFIG_ETH_RMII_CLK_MODE` 中选择 ``CONFIG_ETH_RMII_CLK_OUTPUT``。
|
||||
|
||||
.. note::
|
||||
如上所述,``REF_CLK`` 默认通过项目配置进行配置。然而,通过设置 :cpp:member:`eth_esp32_emac_config_t::interface` 和 :cpp:member:`eth_esp32_emac_config_t::clock_config`,也可以实现在用户应用代码中覆盖该时钟。更多细节,请参见 :cpp:enum:`emac_rmii_clock_mode_t` 和 :cpp:enum:`emac_rmii_clock_gpio_t`。
|
||||
@ -127,15 +127,15 @@ ESP-IDF 提供一系列功能强大且兼具一致性的 API,为内部以太
|
||||
.. warning::
|
||||
如果配置 RMII 时钟模式为 ``CONFIG_ETH_RMII_CLK_OUTPUT``,那么就可以使用 ``GPIO0`` 输出 ``REF_CLK`` 信号。更多细节,请参见 :ref:`CONFIG_ETH_RMII_CLK_OUTPUT_GPIO0`。
|
||||
|
||||
值得一提的是,如果您在设计中并未使用 PSRAM,则 GPIO16 和 GPIO17 也可以用来输出参考时钟。更多细节,请参见 :ref:`CONFIG_ETH_RMII_CLK_OUT_GPIO`。
|
||||
值得一提的是,如果设计中并未使用 PSRAM,则 GPIO16 和 GPIO17 也可以用来输出参考时钟。更多细节,请参见 :ref:`CONFIG_ETH_RMII_CLK_OUT_GPIO`。
|
||||
|
||||
如果配置 RMII 时钟模式为 ``CONFIG_ETH_RMII_CLK_INPUT``,那么有且只有 ``GPIO0`` 可以用来输入 ``REF_CLK`` 信号。请注意, ``GPIO0`` 同时也是 ESP32 上一个重要的 strapping GPIO 管脚。如果 GPIO0 在上电时采样为低电平,ESP32 将进入下载模式,需进行手动复位重启系统。解决这个问题的方法是,在硬件中默认禁用 ``REF_CLK``,从而避免 strapping 管脚在启动阶段受到其他信号的干扰。随后,再在以太网驱动安装阶段重新启用 ``REF_CLK``。
|
||||
|
||||
可以通过以下方法禁用 ``REF_CLK`` 信号:
|
||||
|
||||
* 禁用或关闭晶体振荡器的电源(对应图中的选项 *b*)。
|
||||
* 禁用或关闭晶体振荡器的电源(对应图中的选项 **b**)。
|
||||
|
||||
* 强制复位 PHY 设备(对应图中的选项 *a*)。 **此种方法并不适用于所有 PHY 设备**,即便处于复位状态,某些 PHY 设备仍会向 GPIO0 输出信号。
|
||||
* 强制复位 PHY 设备(对应图中的选项 **a**)。 **此种方法并不适用于所有 PHY 设备**,即便处于复位状态,某些 PHY 设备仍会向 GPIO0 输出信号。
|
||||
|
||||
**无论选择哪种 RMII 时钟模式,都请确保硬件设计中 REF_CLK 的信号完整性!** 信号线越短越好,并请保持信号线与 RF 设备和电感器元件的距离。
|
||||
|
||||
@ -144,7 +144,7 @@ ESP-IDF 提供一系列功能强大且兼具一致性的 API,为内部以太
|
||||
|
||||
在数据平面使用的信号通过 MUX 连接至特定的 GPIO,这些信号无法配置至其他 GPIO。在控制平面使用的信号则可以通过 Matrix 矩阵路由到任何空闲 GPIO。相关的硬件设计示例,请参考 :doc:`ESP32-Ethernet-Kit <../../hw-reference/esp32/get-started-ethernet-kit>`。
|
||||
|
||||
根据您的以太网板设计,需要分别为 MAC 和 PHY 配置必要的参数,通过两者完成驱动程序的安装。
|
||||
根据以太网板设计,需要分别为 MAC 和 PHY 配置必要的参数,通过两者完成驱动程序的安装。
|
||||
|
||||
MAC 的相关配置可以在 :cpp:class:`eth_mac_config_t` 中找到,具体包括:
|
||||
|
||||
@ -166,13 +166,13 @@ PHY 的相关配置可以在 :cpp:class:`eth_phy_config_t` 中找到,具体包
|
||||
|
||||
.. list::
|
||||
|
||||
* :cpp:member:`eth_phy_config_t::phy_addr`:同一条 SMI 总线上可以存在多个 PHY 设备,所以有必要为各个 PHY 设备分配唯一地址。通常,这个地址是在硬件设计期间,通过拉高/拉低一些 PHY strapping 管脚来配置的。根据不同的以太网开发板,可配置值为 0 到 15。需注意,如果 SMI 总线上仅有一个 PHY 设备,将该值配置为 -1,即可使驱动程序自动检测 PHY 地址。
|
||||
* :cpp:member:`eth_phy_config_t::phy_addr`:同一条 SMI 总线上可以存在多个 PHY 设备,所以有必要为各个 PHY 设备分配唯一地址。通常,这个地址是在硬件设计期间,通过拉高/拉低一些 PHY strapping 管脚来配置的。根据不同的以太网开发板,可配置值为 ``0`` 到 ``15``。需注意,如果 SMI 总线上仅有一个 PHY 设备,将该值配置为 ``-1``,即可使驱动程序自动检测 PHY 地址。
|
||||
|
||||
* :cpp:member:`eth_phy_config_t::reset_timeout_ms`:复位超时值,单位为毫秒。通常,PHY 复位应在 100 ms 内完成。
|
||||
|
||||
* :cpp:member:`eth_phy_config_t::autonego_timeout_ms`:自动协商超时值,单位为毫秒。以太网驱动程序会自动与对等的以太网节点进行协商,以确定双工和速度模式。此值通常取决于您电路板上 PHY 设备的性能。
|
||||
* :cpp:member:`eth_phy_config_t::autonego_timeout_ms`:自动协商超时值,单位为毫秒。以太网驱动程序会自动与对等的以太网节点进行协商,以确定双工和速度模式。此值通常取决于电路板上 PHY 设备的性能。
|
||||
|
||||
* :cpp:member:`eth_phy_config_t::reset_gpio_num`:如果您的开发板同时将 PHY 复位管脚连接至了任意 GPIO 管脚,请使用该字段进行配置。否则,配置为 -1。
|
||||
* :cpp:member:`eth_phy_config_t::reset_gpio_num`:如果开发板同时将 PHY 复位管脚连接至了任意 GPIO 管脚,请使用该字段进行配置。否则,配置为 ``-1``。
|
||||
|
||||
ESP-IDF 在宏 :c:macro:`ETH_MAC_DEFAULT_CONFIG` 和 :c:macro:`ETH_PHY_DEFAULT_CONFIG` 中为 MAC 和 PHY 提供了默认配置。
|
||||
|
||||
@ -279,9 +279,9 @@ SPI-Ethernet 模块
|
||||
|
||||
* :cpp:member:`esp_eth_config_t::check_link_period_ms`:以太网驱动程序会启用操作系统定时器来定期检查链接状态。该字段用于设置间隔时间,单位为毫秒。
|
||||
|
||||
* :cpp:member:`esp_eth_config_t::stack_input`:在大多数的以太网物联网应用中,驱动器接收的以太网帧会被传递到上层(如 TCP/IP 栈)。经配置,该字段为负责处理传入帧的函数。您可以在安装驱动程序后,通过函数 :cpp:func:`esp_eth_update_input_path` 更新该字段。该字段支持在运行过程中进行更新。
|
||||
* :cpp:member:`esp_eth_config_t::stack_input`:在大多数的以太网物联网应用中,驱动器接收的以太网帧会被传递到上层(如 TCP/IP 栈)。经配置,该字段为负责处理传入帧的函数。可以在安装驱动程序后,通过函数 :cpp:func:`esp_eth_update_input_path` 更新该字段。该字段支持在运行过程中进行更新。
|
||||
|
||||
* :cpp:member:`esp_eth_config_t::on_lowlevel_init_done` 和 :cpp:member:`esp_eth_config_t::on_lowlevel_deinit_done`: 这两个字段用于指定钩子函数,当去初始化或初始化低级别硬件时,会调用钩子函数。
|
||||
* :cpp:member:`esp_eth_config_t::on_lowlevel_init_done` 和 :cpp:member:`esp_eth_config_t::on_lowlevel_deinit_done`:这两个字段用于指定钩子函数,当去初始化或初始化低级别硬件时,会调用钩子函数。
|
||||
|
||||
ESP-IDF 在宏 :c:macro:`ETH_DEFAULT_CONFIG` 中为安装驱动程序提供了一个默认配置。
|
||||
|
||||
@ -293,7 +293,7 @@ ESP-IDF 在宏 :c:macro:`ETH_DEFAULT_CONFIG` 中为安装驱动程序提供了
|
||||
esp_eth_handle_t eth_handle = NULL; // 驱动程序安装完毕后,将得到驱动程序的句柄
|
||||
esp_eth_driver_install(&config, ð_handle); // 安装驱动程序
|
||||
|
||||
以太网驱动程序包含事件驱动模型,该模型会向用户空间发送有用及重要的事件。安装以太网驱动程序之前,需要首先初始化事件循环。有关事件驱动编程的更多信息,请参考 :doc:`ESP Event <../system/esp_event>`.
|
||||
以太网驱动程序包含事件驱动模型,该模型会向用户空间发送有用及重要的事件。安装以太网驱动程序之前,需要首先初始化事件循环。有关事件驱动编程的更多信息,请参考 :doc:`事件循环库 <../system/esp_event>`。
|
||||
|
||||
.. highlight:: c
|
||||
|
||||
@ -421,7 +421,7 @@ ESP-IDF 在宏 :c:macro:`ETH_DEFAULT_CONFIG` 中为安装驱动程序提供了
|
||||
|
||||
受 RAM 大小限制,在网络拥堵时,MCU 上的以太网通常仅能处理有限数量的帧。发送站的数据传输速度可能快于对等端的接收能力。以太网数据流量控制机制允许接收节点向发送方发出信号,要求暂停传输,直到接收方跟上。这项功能是通过暂停帧实现的,该帧定义在 IEEE 802.3x 中。
|
||||
|
||||
暂停帧是一种特殊的以太网帧,用于携带暂停命令,其 EtherType 字段为 0x8808,控制操作码为 0x0001。只有配置为全双工操作的节点组可以发送暂停帧。当节点组希望暂停链路的另一端时,它会发送一个暂停帧到 48 位的保留组播地址 01-80-C2-00-00-01。暂停帧中也包括请求暂停的时间段,以两字节的整数形式发送,值的范围从 0 到 65535。
|
||||
暂停帧是一种特殊的以太网帧,用于携带暂停命令,其 EtherType 字段为 ``0x8808``,控制操作码为 ``0x0001``。只有配置为全双工操作的节点组可以发送暂停帧。当节点组希望暂停链路的另一端时,它会发送一个暂停帧到 48 位的保留组播地址 ``01-80-C2-00-00-01``。暂停帧中也包括请求暂停的时间段,以两字节的整数形式发送,值的范围从 ``0`` 到 ``65535``。
|
||||
|
||||
安装以太网驱动程序后,数据流量控制功能默认禁用,可以通过以下方式启用此功能:
|
||||
|
||||
@ -460,7 +460,7 @@ ESP-IDF 在宏 :c:macro:`ETH_DEFAULT_CONFIG` 中为安装驱动程序提供了
|
||||
好在 IEEE 802.3 在其 22.2.4 管理功能部分对 EMAC 和 PHY 之间的管理接口进行了标准化。该部分定义了所谓的 ”MII 管理接口”规范,用于控制 PHY 和收集 PHY 的状态,还定义了一组管理寄存器来控制芯片行为、链接属性、自动协商配置等。在 ESP-IDF 中,这项基本的管理功能是由 :component_file:`esp_eth/src/esp_eth_phy_802_3.c` 实现的,这也大大降低了创建新的自定义 PHY 芯片驱动的难度。
|
||||
|
||||
.. note::
|
||||
由于一些 PHY 芯片可能不符合 IEEE 802.3 第 22.2.4 节的规定,所以请首先查看 PHY 数据手册。不过,就算芯片不符合规定,您依旧可以创建自定义 PHY 驱动程序,只是由于需要自行定义所有的 PHY 管理功能,这个过程将变得较为复杂。
|
||||
由于一些 PHY 芯片可能不符合 IEEE 802.3 第 22.2.4 节的规定,所以请首先查看 PHY 数据手册。不过,就算芯片不符合规定,依旧可以创建自定义 PHY 驱动程序,只是由于需要自行定义所有的 PHY 管理功能,这个过程将变得较为复杂。
|
||||
|
||||
ESP-IDF 以太网驱动程序所需的大部分 PHY 管理功能都已涵盖在 :component_file:`esp_eth/src/esp_eth_phy_802_3.c` 中。不过对于以下几项,可能仍需针对不同芯片开发具体的管理功能:
|
||||
|
||||
@ -479,7 +479,7 @@ ESP-IDF 以太网驱动程序所需的大部分 PHY 管理功能都已涵盖在
|
||||
3. 定义针对芯片的特定管理回调功能。
|
||||
4. 初始化 IEEE 802.3 父对象并重新分配针对芯片的特定管理回调功能。
|
||||
|
||||
实现新的自定义 PHY 驱动程序后,你可以通过 `IDF组件管理中心 <https://components.espressif.com/>`_ 将驱动分享给其他用户。
|
||||
实现新的自定义 PHY 驱动程序后,你可以通过 `ESP-IDF 组件管理中心 <https://components.espressif.com/>`_ 将驱动分享给其他用户。
|
||||
|
||||
.. ---------------------------- API Reference ----------------------------------
|
||||
|
||||
|
@ -160,16 +160,16 @@ ESP-NETIF L2 TAP 接口使用手册
|
||||
^^^^^^^^^^^^^^
|
||||
要使用 ESP-NETIF L2 TAP 接口,需要首先通过 Kconfig 配置 :ref:`CONFIG_ESP_NETIF_L2_TAP` 启用接口,随后通过 :cpp:func:`esp_vfs_l2tap_intf_register()` 注册。请在完成上述步骤后再使用 VFS 函数。
|
||||
|
||||
open()
|
||||
^^^^^^
|
||||
``open()``
|
||||
^^^^^^^^^^
|
||||
ESP-NETIF L2 TAP 注册完成后,可使用路径名 "/dev/net/tap" 访问。同一路径名最多可以被打开 :ref:`CONFIG_ESP_NETIF_L2_TAP_MAX_FDS` 次,多个具有不同配置的文件描述符可以访问数据链路层的各个帧。
|
||||
|
||||
ESP-NETIF L2 TAP 可以使用 ``O_NONBLOCK`` 文件状态标志打开,确保 ``read()`` 不会阻塞。请注意,在当前实现中,当访问网络接口时,由于网络接口被多个 ESP-NETIF L2 TAP 文件描述符和 IP 栈共享,且缺乏列队机制,因此 ``write()`` 可能会受阻塞。使用 ``fcntl()`` 检索和修改文件状态标志。
|
||||
|
||||
成功时,``open()`` 返回新的文件描述符(非负整数)。出错时,返回 -1,并设置 ``errno`` 以标识错误。
|
||||
|
||||
ioctl()
|
||||
^^^^^^^
|
||||
``ioctl()``
|
||||
^^^^^^^^^^^
|
||||
由于新打开的 ESP-NETIF L2 TAP 文件描述符尚未绑定任意网络接口或配置任意帧类型过滤器,使用前,用户需通过以下选项完成配置:
|
||||
|
||||
* ``L2TAP_S_INTF_DEVICE`` - 将文件描述符绑定到特定网络接口的选项,该网络接口由其 ``if_key`` 标识。 ESP-NETIF 网络接口的 ``if_key`` 作为第三个参数传输给 ``ioctl()``。 ESP-IDF 中,默认网络接口 ``if_key`` 的使用存放在 :component_file:`esp_netif/include/esp_netif_defaults.h` 头文件中。
|
||||
@ -194,8 +194,8 @@ ioctl()
|
||||
| * ENODEV - 此文件描述符尝试分配给的网络接口不存在。
|
||||
| * ENOSYS - 不支持该操作,传递的配置选项不存在。
|
||||
|
||||
fcntl()
|
||||
^^^^^^^
|
||||
``fcntl()``
|
||||
^^^^^^^^^^^
|
||||
``fcntl()`` 配置已开启的 ESP-NETIF L2 TAP 文件描述符属性。
|
||||
|
||||
以下命令调控与文件描述符相关的状态标志:
|
||||
@ -207,16 +207,16 @@ fcntl()
|
||||
| * EBADF - 文件描述符无效。
|
||||
| * ENOSYS - 不支持该命令。
|
||||
|
||||
read()
|
||||
^^^^^^
|
||||
``read()``
|
||||
^^^^^^^^^^
|
||||
已开启并完成配置的 ESP-NETIF L2 TAP 文件描述符可通过 ``read()`` 获取入站帧。读取可以是阻塞或非阻塞的,具体取决于 ``O_NONBLOCK`` 文件状态标志的实际状态。当文件状态标志设置为阻塞时,读取程序将等待,直到接收到帧,并将上下文切换到其他任务。当文件状态标志设置为非阻塞时,立即返回读取程序。在此情况下,如果已经帧已经入队,则返回一帧,否则函数指示队列为空。与文件描述符关联的队列帧数量受 :ref:`CONFIG_ESP_NETIF_L2_TAP_RX_QUEUE_SIZE` Kconfig 选项限制。一旦队列里帧的数量达到配置的阈值,新到达的帧将被丢弃,直到队列有足够的空间接受传入的流量(队尾丢弃队列管理)。
|
||||
|
||||
| 成功时,read() 函数返回读取的字节数。当目标缓冲区的大小为 0 时,函数返回 0。出错时,函数返回 -1,并设置 ``errno`` 以指示错误类型。
|
||||
| * EBADF - 文件描述符无效。
|
||||
| * EAGAIN - 文件描述符标记为非阻塞 (``O_NONBLOCK``),但读取受阻塞。
|
||||
|
||||
write()
|
||||
^^^^^^^
|
||||
``write()``
|
||||
^^^^^^^^^^^
|
||||
通过已开启并完成配置的 ESP-NETIF L2 TAP 文件描述符可以将原始数据链路层帧发送到网络接口,用户应用程序负责构建除物理接口设备自动添加的字段外的整个帧。在以太网链路中,用户应用程序需要构建以下字段:源或目的 MAC 地址、以太网类型、实际协议头和用户数据,字段长度如下表:
|
||||
|
||||
.. list-table::
|
||||
@ -240,15 +240,15 @@ write()
|
||||
| * EBADMSG - 帧的以太网类型与文件描述符配置的过滤器不同。
|
||||
| * EIO - 网络接口不可用或正忙。
|
||||
|
||||
close()
|
||||
^^^^^^^
|
||||
``close()``
|
||||
^^^^^^^^^^^
|
||||
已开启的 ESP-NETIF L2 TAP 文件描述符可以通过 ``close()`` 函数关闭,释放其分配到的资源。ESP-NETIF L2 TAP 实现的 ``close()`` 函数可能会受阻塞,但它是线程安全的,可以从与实际使用文件描述符的任务不同的任务中调用。如果出现一个任务在 I/O 操作中被阻塞、另一个任务试图关闭文件描述符的情况,则第一个任务会解除阻塞,其读取程序以错误结束。
|
||||
|
||||
| 成功时,``close()`` 返回 0。出错时,则返回 -1, 并设置 ``errno`` 以指示错误类型。
|
||||
| * EBADF - 文件描述符无效。
|
||||
|
||||
select()
|
||||
^^^^^^^^
|
||||
``select()``
|
||||
^^^^^^^^^^^^
|
||||
``select()`` 函数按标准方法使用,启用 :ref:`CONFIG_VFS_SUPPORT_SELECT` 即可使用该函数。
|
||||
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
ESP-NOW
|
||||
========
|
||||
|
||||
:link_to_translation:`en:[英文]`
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
概述
|
||||
--------
|
||||
|
||||
ESP-NOW 是一种由乐鑫公司定义的无连接 Wi-Fi 通信协议。在 ESP-NOW 中,应用程序数据被封装在各个供应商的动作帧中,然后在无连接的情况下,从一个 Wi-Fi 设备传输到另一个 Wi-Fi 设备。
|
||||
|
||||
CTR 与 CBC-MAC 协议 (CCMP) 可用来保护动作帧的安全。ESP-NOW 广泛应用于智能照明、远程控制、传感器等领域。
|
||||
|
||||
帧格式
|
||||
@ -24,7 +25,7 @@ ESP-NOW 使用各个供应商的动作帧传输数据,默认比特率为 1 Mbp
|
||||
24 字节 1 字节 3 字节 4 字节 7~257 字节 4 字节
|
||||
|
||||
- 分类代码:分类代码字段可用于指示各个供应商的类别(比如 127)。
|
||||
- 组织标识符:组织标识符包含一个唯一标识符 (比如 0x18fe34),为乐鑫指定的 MAC 地址的前三个字节。
|
||||
- 组织标识符:组织标识符包含一个唯一标识符(比如 0x18fe34),为乐鑫指定的 MAC 地址的前三个字节。
|
||||
- 随机值:防止重放攻击。
|
||||
- 供应商特定内容:供应商特定内容包含供应商特定字段,如下所示:
|
||||
|
||||
@ -39,7 +40,7 @@ ESP-NOW 使用各个供应商的动作帧传输数据,默认比特率为 1 Mbp
|
||||
|
||||
- 元素 ID:元素 ID 字段可用于指示特定于供应商的元素。
|
||||
- 长度:长度是组织标识符、类型、版本和正文的总长度。
|
||||
- 组织标识符:组织标识符包含一个唯一标识符 (比如 0x18fe34),为乐鑫指定的 MAC 地址的前三个字节。
|
||||
- 组织标识符:组织标识符包含一个唯一标识符(比如 0x18fe34),为乐鑫指定的 MAC 地址的前三个字节。
|
||||
- 类型:类型字段设置为 4,代表 ESP-NOW。
|
||||
- 版本:版本字段设置为 ESP-NOW 的版本。
|
||||
- 正文:正文包含 ESP-NOW 数据。
|
||||
@ -50,6 +51,7 @@ ESP-NOW 使用各个供应商的动作帧传输数据,默认比特率为 1 Mbp
|
||||
--------
|
||||
|
||||
ESP-NOW 采用 CCMP 方法保护供应商特定动作帧的安全,具体可参考 IEEE Std. 802.11-2012。Wi-Fi 设备维护一个初始主密钥 (PMK) 和若干本地主密钥 (LMK),长度均为 16 个字节。
|
||||
|
||||
* PMK 可使用 AES-128 算法加密 LMK。请调用 :cpp:func:`esp_now_set_pmk()` 设置 PMK。如果未设置 PMK,将使用默认 PMK。
|
||||
* LMK 可通过 CCMP 方法对供应商特定的动作帧进行加密,最多拥有 6 个不同的 LMK。如果未设置配对设备的 LMK,则动作帧不进行加密。
|
||||
|
||||
@ -59,12 +61,13 @@ ESP-NOW 采用 CCMP 方法保护供应商特定动作帧的安全,具体可参
|
||||
------------------------------------
|
||||
|
||||
调用 :cpp:func:`esp_now_init()` 初始化 ESP-NOW,调用 :cpp:func:`esp_now_deinit()` 反初始化 ESP-NOW。ESP-NOW 数据必须在 Wi-Fi 启动后传输,因此建议在初始化 ESP-NOW 之前启动 Wi-Fi,并在反初始化 ESP-NOW 之后停止 Wi-Fi。
|
||||
|
||||
当调用 :cpp:func:`esp_now_deinit()` 时,配对设备的所有信息都将被删除。
|
||||
|
||||
添加配对设备
|
||||
-----------------
|
||||
|
||||
在将数据发送到其他设备之前,请先调用 :cpp:func:`esp_now_add_peer()` 将其添加到配对设备列表中。如果启用了加密,则必须设置 LMK。ESP-NOW 数据可以从 Station 或 Softap 接口发送。确保在发送 ESP-NOW 数据之前已启用该接口。
|
||||
在将数据发送到其他设备之前,请先调用 :cpp:func:`esp_now_add_peer()` 将其添加到配对设备列表中。如果启用了加密,则必须设置 LMK。ESP-NOW 数据可以从 Station 或 SoftAP 接口发送。确保在发送 ESP-NOW 数据之前已启用该接口。
|
||||
|
||||
.. only:: esp32c2
|
||||
|
||||
@ -74,7 +77,7 @@ ESP-NOW 采用 CCMP 方法保护供应商特定动作帧的安全,具体可参
|
||||
|
||||
配对设备的最大数量是 20,其中加密设备的数量不超过 17,默认值是 7。如果想要修改加密设备的数量,在 Wi-Fi menuconfig 设置 :ref:`CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM`。
|
||||
|
||||
在发送广播数据之前必须添加具有广播 MAC 地址的设备。配对设备的信道范围是从 0 ~14。如果信道设置为 0,数据将在当前信道上发送。否则,必须使用本地设备所在的通道。
|
||||
在发送广播数据之前必须添加具有广播 MAC 地址的设备。配对设备的信道范围是从 0 ~ 14。如果信道设置为 0,数据将在当前信道上发送。否则,必须使用本地设备所在的通道。
|
||||
|
||||
发送 ESP-NOW 数据
|
||||
-----------------
|
||||
@ -94,15 +97,15 @@ ESP-NOW 采用 CCMP 方法保护供应商特定动作帧的安全,具体可参
|
||||
|
||||
.. only:: esp32 or esp32s2 or esp32s3 or esp32c2 or esp32c3
|
||||
|
||||
调用 :cpp:func:`esp_wifi_config_espnow_rate()` 配置指定接口的 ESPNOW 速率。确保在配置速率之前使能接口。这个 API 应该在 :cpp:func:`esp_wifi_start()` 之后调用。
|
||||
调用 :cpp:func:`esp_wifi_config_espnow_rate()` 配置指定接口的 ESP-NOW 速率。确保在配置速率之前启用接口。这个 API 应该在 :cpp:func:`esp_wifi_start()` 之后调用。
|
||||
|
||||
.. only:: esp32c6
|
||||
|
||||
调用 :cpp:func:`esp_now_set_peer_rate_config()` 配置指定peer的 ESPNOW 速率。确保在配置速率之前添加peer。这个 API 应该在 :cpp:func:`esp_wifi_start()` 和 :cpp:func:`esp_now_add_peer()` 之后调用。
|
||||
调用 :cpp:func:`esp_now_set_peer_rate_config()` 配置指定 peer 的 ESP-NOW 速率。确保在配置速率之前添加 peer。这个 API 应该在 :cpp:func:`esp_wifi_start()` 和 :cpp:func:`esp_now_add_peer()` 之后调用。
|
||||
|
||||
.. note::
|
||||
|
||||
:cpp:func:`esp_wifi_config_espnow_rate()` 已经被废弃了,请用 :cpp:func:`esp_now_set_peer_rate_config()`
|
||||
:cpp:func:`esp_wifi_config_espnow_rate()` 已弃用,请使用 :cpp:func:`esp_now_set_peer_rate_config()`
|
||||
|
||||
配置 ESP-NOW 功耗参数
|
||||
----------------------
|
||||
|
@ -43,6 +43,7 @@ Thread
|
||||
esp_openthread
|
||||
|
||||
Thread 是一种基于 IPv6 的物联网网状网络技术。
|
||||
|
||||
本部分的Thread API 示例代码存放在 ESP-IDF 示例项目的 :example:`openthread` 目录下。
|
||||
|
||||
IP 网络层协议
|
||||
|
Loading…
Reference in New Issue
Block a user