kopia lustrzana https://github.com/espressif/esp-idf
Merge branch 'docs/provide_translation_for_esp_eth' into 'master'
docs: Provide CN translation for esp_eth Closes DOC-3901 See merge request espressif/esp-idf!21029pull/10391/head
commit
2f29408f3f
|
@ -1,5 +1,6 @@
|
|||
Ethernet
|
||||
========
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
.. -------------------------------- Overview -----------------------------------
|
||||
|
@ -23,13 +24,11 @@ This programming guide is split into the following sections:
|
|||
Basic Ethernet Concepts
|
||||
-----------------------
|
||||
|
||||
Ethernet is an asynchronous Carrier Sense Multiple Access with Collision Detect (CSMA/CD) protocol/interface.
|
||||
It is generally not well suited for low power applications. However, with ubiquitous deployment, internet connectivity, high data rates and limitless rage expandability, Ethernet can accommodate nearly all wired communications.
|
||||
Ethernet is an asynchronous Carrier Sense Multiple Access with Collision Detect (CSMA/CD) protocol/interface. It is generally not well suited for low-power applications. However, with ubiquitous deployment, internet connectivity, high data rates, and limitless-range expandability, Ethernet can accommodate nearly all wired communications.
|
||||
|
||||
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, 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.
|
||||
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 blow:
|
||||
Thus the traffic on the twist-pair cabling will appear as shown below:
|
||||
|
||||
.. rackdiag:: ../../../_static/diagrams/ethernet/data_frame_format.diag
|
||||
:caption: Ethernet Data Frame Format
|
||||
|
@ -38,7 +37,8 @@ Thus the traffic on the twist-pair cabling will appear as shown blow:
|
|||
Preamble and Start-of-Frame Delimiter
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The preamble contains seven bytes of ``55H``, it allows the receiver to lock onto the stream of data before the actual frame arrives.
|
||||
The preamble contains seven bytes of ``55H``. It allows the receiver to lock onto the stream of data before the actual frame arrives.
|
||||
|
||||
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.
|
||||
|
@ -46,31 +46,23 @@ When transmitting and receiving data, the preamble and SFD bytes will automatica
|
|||
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 multi-cast 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 multi-cast 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 uni-cast address and will be designed for usage by only the addressed node.
|
||||
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.
|
||||
|
||||
Normally the EMAC controller incorporates receive filters which can be used to discard or accept packets with multi-cast, broadcast and/or uni-cast destination addresses.
|
||||
When transmitting packets, the host controller is responsible for writing the desired destination address into the transmit buffer.
|
||||
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.
|
||||
|
||||
Source Address
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
The source address field contains a 6-byte length MAC address of the node which created the Ethernet packet.
|
||||
Users of Ethernet must generate a unique MAC address for each controller used.
|
||||
MAC addresses consist of two portions. The first three bytes are known as the Organizationally Unique Identifier (OUI). OUIs are distributed by the IEEE.
|
||||
The last three bytes are address bytes at the discretion of the company that purchased the OUI. More information about MAC Address used in ESP-IDF, please see :ref:`MAC Address Allocation <MAC-Address-Allocation>`.
|
||||
The source address field contains a 6-byte length MAC address of the node which created the Ethernet packet. Users of Ethernet must generate a unique MAC address for each controller used. MAC addresses consist of two portions. The first three bytes are known as the Organizationally Unique Identifier (OUI). OUIs are distributed by the IEEE. The last three bytes are address bytes at the discretion of the company that purchased the OUI. For more information about MAC Address used in ESP-IDF, please see :ref:`MAC Address Allocation <MAC-Address-Allocation>`.
|
||||
|
||||
When transmitting packets, the assigned source MAC address must be written into the transmit buffer by the host controller.
|
||||
|
||||
Type / Length
|
||||
Type/Length
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
The type/length field is a 2-byte field, if the value in this field is <= 1500 (decimal), it is considered a length field and it specifies the amount of non-padding data which follows in the data field.
|
||||
If the value is >= 1536, it represents the protocol the following packet data belongs to. The following are the most common type values:
|
||||
The type/length field is a 2-byte field. If the value in this field is <= 1500 (decimal), it is considered a length field and it specifies the amount of non-padding data which follows in the data field. If the value is >= 1536, it represents the protocol the following packet data belongs to. The followings are the most common type values:
|
||||
|
||||
* IPv4 = 0800H
|
||||
* IPv6 = 86DDH
|
||||
|
@ -82,25 +74,22 @@ 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.
|
||||
|
||||
This field contains the client data, such as an IP datagram.
|
||||
|
||||
Padding and FCS
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
The padding field is a variable length field added to meet IEEE 802.3 specification requirements when small data payloads are used.
|
||||
The DA, SA, type, payload and padding of an Ethernet packet must be no smaller than 60 bytes.
|
||||
Adding the required 4-byte FCS field, packets must be no smaller than 64 bytes.
|
||||
If the data field is less than 46 bytes long, a padding field is required.
|
||||
The padding field is a variable length field added to meet the IEEE 802.3 specification requirements when small data payloads are used.
|
||||
|
||||
The FCS field is a 4-byte field which 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 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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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're two other common frame types in 10/100 Mbps Ethernet: control frames and VLAN-tagged frames. They're not supported in ESP-IDF.
|
||||
|
||||
.. ------------------------------ Driver Operation --------------------------------
|
||||
|
||||
|
@ -109,76 +98,81 @@ However, the padding and CRC fields will be written into the receive buffer when
|
|||
Configure MAC and PHY
|
||||
---------------------
|
||||
|
||||
Ethernet driver is composed of two parts: MAC and PHY.
|
||||
The Ethernet driver is composed of two parts: MAC and PHY.
|
||||
|
||||
.. only:: SOC_EMAC_SUPPORTED
|
||||
|
||||
The communication between MAC and PHY can have diverse choices: **MII** (Media Independent Interface), **RMII** (Reduced Media Independent Interface) and etc.
|
||||
The communication between MAC and PHY can have diverse choices: **MII** (Media Independent Interface), **RMII** (Reduced Media Independent Interface), etc.
|
||||
|
||||
.. figure:: ../../../_static/rmii-interface.png
|
||||
:align: center
|
||||
:scale: 80 %
|
||||
:alt: Ethernet RMII Interface
|
||||
:figclass: align-center
|
||||
|
||||
Ethernet RMII Interface
|
||||
|
||||
One of the obvious difference between MII and RMII is the signal consumption. For MII, it usually costs up to 18 signals. Instead, RMII interface can reduce the consumption to 9.
|
||||
One of the obvious differences between MII and RMII is signal consumption. MII usually costs up to 18 signals, while the RMII interface can reduce the consumption to 9.
|
||||
|
||||
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're three ways to generate the ``REF_CLK`` depending on the PHY device in your design:
|
||||
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 chip can derive the ``REF_CLK`` from its external connected 25MHz 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 external connected 50MHz crystal oscillator or other clock source, which can also be used as the ``REF_CLK`` for 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 controller can generate the ``REF_CLK`` using its 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 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 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.
|
||||
|
||||
.. 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.
|
||||
|
||||
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 of this issue is disabling the ``REF_CLK`` in hardware by default, so that the strapping pin won't be interfered by other signals in boot stage. Then re-enable the ``REF_CLK`` in 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 won't be 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).
|
||||
* Force the PHY device in reset status (as the case *a* in the picture). **This could fail for some PHY device** (i.e. it still outputs signal 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. Keep it away from inductor elements.
|
||||
* 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 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 data plane are fixed to specific GPIOs via MUX, they can't be modified to other GPIOs.
|
||||
Signals used in 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'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.
|
||||
|
||||
We need to setup necessary parameters for MAC and PHY respectively based on your Ethernet board design and then combine the two together, completing the driver installation.
|
||||
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.
|
||||
|
||||
Configuration for MAC is described in :cpp:class:`eth_mac_config_t`, including:
|
||||
|
||||
.. list::
|
||||
|
||||
* :cpp:member:`eth_mac_config_t::sw_reset_timeout_ms`: software reset timeout value, in milliseconds, typically MAC reset should be finished within 100ms.
|
||||
* :cpp:member:`eth_mac_config_t::rx_task_stack_size` and :cpp:member:`eth_mac_config_t::rx_task_prio`: the MAC driver creates a dedicated task to process incoming packets, these two parameters are used to set the stack size and priority of the task.
|
||||
* :cpp:member:`eth_mac_config_t::flags`: specifying extra features that the MAC driver should have, it could be useful in some special situations. The value of this field can be OR'd with macros prefixed with ``ETH_MAC_FLAG_``. For example, if the MAC driver should work when cache is disabled, then you should configure this field with :c:macro:`ETH_MAC_FLAG_WORK_WITH_CACHE_DISABLE`.
|
||||
* :cpp:member:`eth_mac_config_t::sw_reset_timeout_ms`: software reset timeout value, in milliseconds. Typically, MAC reset should be finished within 100 ms.
|
||||
|
||||
* :cpp:member:`eth_mac_config_t::rx_task_stack_size` and :cpp:member:`eth_mac_config_t::rx_task_prio`: the MAC driver creates a dedicated task to process incoming packets. These two parameters are used to set the stack size and priority of the task.
|
||||
|
||||
* :cpp:member:`eth_mac_config_t::flags`: specifying extra features that the MAC driver should have, it could be useful in some special situations. The value of this field can be OR'd with macros prefixed with ``ETH_MAC_FLAG_``. For example, if the MAC driver should work when the cache is disabled, then you should configure this field with :c:macro:`ETH_MAC_FLAG_WORK_WITH_CACHE_DISABLE`.
|
||||
|
||||
:SOC_EMAC_SUPPORTED: * :cpp:member:`eth_esp32_emac_config_t::smi_mdc_gpio_num` and :cpp:member:`eth_esp32_emac_config_t::smi_mdio_gpio_num`: the GPIO number used to connect the SMI signals.
|
||||
|
||||
:SOC_EMAC_SUPPORTED: * :cpp:member:`eth_esp32_emac_config_t::interface`: configuration of MAC Data interface to PHY (MII/RMII).
|
||||
|
||||
:SOC_EMAC_SUPPORTED: * :cpp:member:`eth_esp32_emac_config_t::clock_config`: configuration of EMAC Interface clock (``REF_CLK`` mode and GPIO number in case of RMII).
|
||||
|
||||
Configuration for PHY is described in :cpp:class:`eth_phy_config_t`, including:
|
||||
|
||||
.. list::
|
||||
|
||||
* :cpp:member:`eth_phy_config_t::phy_addr`: multiple PHY device 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 100ms.
|
||||
* :cpp:member:`eth_phy_config_t::autonego_timeout_ms`: auto-negotiation timeout value, in milliseconds. 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::reset_gpio_num`: if your board also connect 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::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::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`.
|
||||
|
||||
|
@ -186,7 +180,7 @@ ESP-IDF provides a default configuration for MAC and PHY in macro :c:macro:`ETH_
|
|||
Create MAC and PHY Instance
|
||||
---------------------------
|
||||
|
||||
Ethernet driver is implemented in an Object-Oriented style. Any operation on MAC and PHY should be based on the instance of them two.
|
||||
The Ethernet driver is implemented in an Object-Oriented style. Any operation on MAC and PHY should be based on the instance of the two.
|
||||
|
||||
.. only:: SOC_EMAC_SUPPORTED
|
||||
|
||||
|
@ -214,7 +208,7 @@ Ethernet driver is implemented in an Object-Oriented style. Any operation on MAC
|
|||
Optional Runtime MAC Clock Configuration
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
EMAC ``REF_CLK`` can be optionally configured from user application code.
|
||||
EMAC ``REF_CLK`` can be optionally configured from the user application code.
|
||||
|
||||
.. highlight:: c
|
||||
|
||||
|
@ -241,7 +235,7 @@ SPI-Ethernet Module
|
|||
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); // apply default PHY configuration
|
||||
phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR; // alter the PHY address according to your board design
|
||||
phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO; // alter the GPIO used for PHY reset
|
||||
// Install GPIO interrupt service (as the SPI-Ethernet module is interrupt driven)
|
||||
// Install GPIO interrupt service (as the SPI-Ethernet module is interrupt-driven)
|
||||
gpio_install_isr_service(0);
|
||||
// SPI bus configuration
|
||||
spi_device_handle_t spi_handle = NULL;
|
||||
|
@ -268,8 +262,9 @@ SPI-Ethernet Module
|
|||
|
||||
|
||||
.. note::
|
||||
* When creating MAC and PHY instance 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.
|
||||
* 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 spec and the examples in esp-idf.
|
||||
* 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.
|
||||
|
||||
* 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
|
||||
|
@ -278,10 +273,14 @@ 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`:
|
||||
|
||||
* :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::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 of Ethernet IoT applications, any Ethernet frame that received by driver should be passed to upper layer (e.g. TCP/IP stack). This field is set to a function which 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.
|
||||
|
||||
* :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.
|
||||
|
||||
ESP-IDF provides a default configuration for driver installation in macro :c:macro:`ETH_DEFAULT_CONFIG`.
|
||||
|
||||
|
@ -290,10 +289,10 @@ ESP-IDF provides a default configuration for driver installation in macro :c:mac
|
|||
::
|
||||
|
||||
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy); // apply default driver configuration
|
||||
esp_eth_handle_t eth_handle = NULL; // after driver installed, we will get the handle of the driver
|
||||
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
|
||||
|
||||
Ethernet driver also includes event-driven model, which will send useful and important event 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 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>`.
|
||||
|
||||
.. highlight:: c
|
||||
|
||||
|
@ -328,8 +327,8 @@ Ethernet driver also includes event-driven model, which will send useful and imp
|
|||
}
|
||||
}
|
||||
|
||||
esp_event_loop_create_default(); // create a default event loop that running in background
|
||||
esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, NULL); // register Ethernet event handler (to deal with user specific stuffs when event like link up/down happened)
|
||||
esp_event_loop_create_default(); // create a default event loop that runs in the background
|
||||
esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, NULL); // register Ethernet event handler (to deal with user-specific stuff when events like link up/down happened)
|
||||
|
||||
Start Ethernet Driver
|
||||
---------------------
|
||||
|
@ -347,16 +346,15 @@ 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). We can detect link up and down event, we can gain MAC address in user space, but we can't obtain IP address, let alone send 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'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>`.
|
||||
|
||||
To connect Ethernet driver to TCP/IP stack, these three steps need to follow:
|
||||
To connect the Ethernet driver to TCP/IP stack, follow these three steps:
|
||||
|
||||
1. Create network interface for Ethernet driver
|
||||
2. Attach the network interface to Ethernet driver
|
||||
1. Create a network interface for the Ethernet driver
|
||||
2. Attach the network interface to the Ethernet driver
|
||||
3. Register IP event handlers
|
||||
|
||||
More information about network interface, please refer to :doc:`Network Interface <esp_netif>`.
|
||||
For more information about the network interface, please refer to :doc:`Network Interface <esp_netif>`.
|
||||
|
||||
.. highlight:: c
|
||||
|
||||
|
@ -386,11 +384,11 @@ More information about network interface, please refer to :doc:`Network Interfac
|
|||
esp_eth_start(eth_handle); // start Ethernet driver state machine
|
||||
|
||||
.. warning::
|
||||
It is recommended to fully initialize the Ethernet driver and network interface prior registering user's Ethernet/IP event handlers, i.e. register the event handlers as the last thing prior starting the Ethernet driver. Such approach ensures that Ethernet/IP events get executed first by the Ethernet driver or network interface and so the system is in expected state when executing 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:
|
||||
|
||||
Misc control of Ethernet driver
|
||||
Misc Control of Ethernet Driver
|
||||
-------------------------------
|
||||
|
||||
The following functions should only be invoked after the Ethernet driver has been installed.
|
||||
|
@ -417,14 +415,14 @@ The following functions should only be invoked after the Ethernet driver has bee
|
|||
|
||||
.. _flow-control:
|
||||
|
||||
Flow control
|
||||
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. Ethernet flow control mechanism allows the receiving node to signal the sender requesting suspension of transmissions until the receiver catches up. The magic behind that is the pause frame, which was defined in IEEE 802.3x.
|
||||
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.
|
||||
|
||||
After Ethernet driver installation, the flow control feature is disabled by default. You can enable it by:
|
||||
After the Ethernet driver installation, the flow control feature is disabled by default. You can enable it by:
|
||||
|
||||
.. highlight:: c
|
||||
|
||||
|
@ -433,17 +431,17 @@ After Ethernet driver installation, the flow control feature is disabled by defa
|
|||
bool flow_ctrl_enable = true;
|
||||
esp_eth_ioctl(eth_handle, ETH_CMD_S_FLOW_CTRL, &flow_ctrl_enable);
|
||||
|
||||
One thing should be kept in mind, is that the pause frame ability will be advertised to peer end by PHY during auto negotiation. Ethernet driver sends 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 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.
|
||||
|
||||
.. -------------------------------- Examples -----------------------------------
|
||||
|
||||
Application Examples
|
||||
--------------------
|
||||
|
||||
* Ethernet basic example: :example:`ethernet/basic`.
|
||||
* Ethernet iperf example: :example:`ethernet/iperf`.
|
||||
* Ethernet to Wi-Fi AP "router": :example:`ethernet/eth2ap`.
|
||||
* Most of protocol examples should also work for Ethernet: :example:`protocols`.
|
||||
* Ethernet basic example: :example:`ethernet/basic`
|
||||
* Ethernet iperf example: :example:`ethernet/iperf`
|
||||
* Ethernet to Wi-Fi AP "router": :example:`ethernet/eth2ap`
|
||||
* Most protocol examples should also work for Ethernet: :example:`protocols`
|
||||
|
||||
.. ------------------------------ Advanced Topics -------------------------------
|
||||
|
||||
|
@ -455,31 +453,31 @@ Advanced Topics
|
|||
Custom PHY Driver
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
There are multiple PHY manufactures with their wide portfolios of chips available. The ESP-IDF already supports several PHY chips however one can easily get to a point where none of them satisfies user's actual needs due to either price, features, stock availability etc.
|
||||
There are multiple PHY manufacturers with wide portfolios of chips available. The ESP-IDF already supports several PHY chips however one can easily get to a point where none of them satisfies the user's actual needs due to price, features, stock availability, etc.
|
||||
|
||||
Luckily, a management interface between EMAC and PHY is standardized by IEEE 802.3 in 22.2.4 Management functions section. It defines provisions of so called “MII Management Interface” for the purposes of controlling the PHY and gathering 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 a creation of new custom PHY chip driver quite a simple task.
|
||||
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, it will just require more effort. You will have to define all PHY management functions.
|
||||
|
||||
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:
|
||||
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:
|
||||
|
||||
* link status which is almost always chip specific,
|
||||
* chip initialization, even though it is not strictly required, should be customized to at least ensure that expected chip is used and
|
||||
* chip specific features configuration.
|
||||
* Link status which is almost always chip-specific
|
||||
* Chip initialization, even though not strictly required, should be customized to at least ensure that the expected chip is used
|
||||
* Chip-specific features configuration
|
||||
|
||||
**Steps to create custom PHY driver:**
|
||||
**Steps to create a custom PHY driver:**
|
||||
|
||||
1. Define vendor specific registry layout based on PHY datasheet. See :component_file:`esp_eth/src/esp_eth_phy_ip101.c` as an example.
|
||||
2. Prepare derived PHY management object infostructure which
|
||||
1. Define vendor-specific registry layout based on the PHY datasheet. See :component_file:`esp_eth/src/esp_eth_phy_ip101.c` as an example.
|
||||
2. Prepare derived PHY management object info structure which:
|
||||
|
||||
* must contain at least parent IEEE 802.3 :cpp:class:`phy_802_3_t` object and
|
||||
* must contain at least parent IEEE 802.3 :cpp:class:`phy_802_3_t` object
|
||||
* optionally contain additional variables needed to support non-IEEE 802.3 or customized functionality. See :component_file:`esp_eth/src/esp_eth_phy_ksz80xx.c` as an example.
|
||||
|
||||
3. Define chip specific management call-back functions.
|
||||
4. Initialize parent IEEE 802.3 object and re-assign chip specific management call-back functions.
|
||||
3. Define chip-specific management call-back functions.
|
||||
4. Initialize parent IEEE 802.3 object and re-assign chip-specific management call-back functions.
|
||||
|
||||
Once you finish the new custom PHY driver implementation, consider sharing it among with other users via `IDF Component Registry <https://components.espressif.com/>`_.
|
||||
Once you finish the new custom PHY driver implementation, consider sharing it among other users via `IDF Component Registry <https://components.espressif.com/>`_.
|
||||
|
||||
.. ---------------------------- API Reference ----------------------------------
|
||||
|
||||
|
|
|
@ -3,59 +3,491 @@
|
|||
|
||||
:link_to_translation:`en:[英文]`
|
||||
|
||||
应用示例
|
||||
-------------------
|
||||
.. -------------------------------- Overview -----------------------------------
|
||||
|
||||
- 以太网基本示例::example:`ethernet/basic`.
|
||||
- 以太网 iperf 示例::example:`ethernet/iperf`.
|
||||
概述
|
||||
--------
|
||||
|
||||
以太网驱动程序模型
|
||||
ESP-IDF 提供一系列功能强大且兼具一致性的 API,为内部以太网 MAC (EMAC) 控制器和外部 SPI-Ethernet 模块提供支持。
|
||||
|
||||
本编程指南分为以下几个部分:
|
||||
|
||||
1. :ref:`basic-ethernet-concepts`
|
||||
2. :ref:`driver-configuration-and-installation`
|
||||
3. :ref:`connect-driver-to-stack`
|
||||
4. :ref:`misc-operation-of-driver`
|
||||
|
||||
.. --------------------------- Basic Ethernet Concepts ------------------------------
|
||||
|
||||
.. _basic-ethernet-concepts:
|
||||
|
||||
以太网基本概念
|
||||
-----------------------
|
||||
|
||||
以太网是一种异步的带冲突检测的载波侦听多路访问 (CSMA/CD) 协议/接口。通常来说,以太网不太适用于低功率应用。然而,得益于其广泛的部署、高效的网络连接、高数据率以及范围不限的可扩展性,几乎所有的有线通信都可以通过以太网进行。
|
||||
|
||||
符合 IEEE 802.3 标准的正常以太网帧的长度在 64 至 1518 字节之间,由五个或六个不同的字段组成:目的地 MAC 地址 (DA)、源 MAC 地址 (SA)、类型/长度字段、数据有效载荷字段、可选的填充字段和帧校验序列字段 (CRC)。此外,在以太网上传输时,以太网数据包的开头需附加 7 字节的前导码和 1 字节的帧起始符 (SOF)。
|
||||
|
||||
因此,双绞线上的通信如图所示:
|
||||
|
||||
.. rackdiag:: ../../../_static/diagrams/ethernet/data_frame_format.diag
|
||||
:caption: 以太网数据帧格式
|
||||
:align: center
|
||||
|
||||
前导码和帧起始符
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
前导码包含 7 字节的 ``55H``,作用是使接收器在实际帧到达之前锁定数据流。
|
||||
|
||||
帧前界定符 (SFD) 为二进制序列 ``10101011`` (物理介质层可见)。有时它也被视作前导码的一部分。
|
||||
|
||||
在传输和接收数据时,协议将自动从数据包中生成/移除前导码和帧起始符。
|
||||
|
||||
目的地址 (DA)
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
目的地址字段包含一个 6 字节长的设备 MAC 地址,数据包将发送到该地址。如果 MAC 地址第一个字节中的最低有效位是 1,则该地址为组播地址。例如,01-00-00-F0-00 和 33-45-67-89-AB-CD 是组播地址,而 00-00-00-F0-00 和 32-45-67-89-AB-CD 不是。
|
||||
|
||||
带有组播地址的数据包将到达选定的一组以太网节点,并发挥重要作用。如果目的地址字段是保留的多播地址,即 FF-FF-FF-FF-FF-FF,则该数据包是一个广播数据包,指向共享网络中的每个对象。如果 MAC 地址的第一个字节中的最低有效位为 0,则该地址为单播地址,仅供寻址节点使用。
|
||||
|
||||
通常,EMAC 控制器会集成接收过滤器,用于丢弃或接收带有组播、广播和/或单播目的地址的数据包。传输数据包时,由主机控制器将所需的目标地址写入传输缓冲区。
|
||||
|
||||
源地址 (SA)
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
源地址字段包含一个 6 字节长的节点 MAC 地址,以太网数据包通过该节点创建。以太网的用户需为所使用的任意控制器生成唯一的 MAC 地址。MAC 地址由两部分组成:前三个字节称为组织唯一标识符 (OUI),由 IEEE 分配;后三个字节是地址字节,由购买 OUI 的公司配置。有关 ESP-IDF 中使用的 MAC 地址的详细信息,请参见 :ref:`MAC 地址分配 <MAC-Address-Allocation>`。
|
||||
|
||||
传输数据包时,由主机控制器将分配的源 MAC 地址写入传输缓冲区。
|
||||
|
||||
类型/长度
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
类型/长度字段长度为 2 字节。如果其值 <= 1500(十进制),则该字段为长度字段,指定在数据字段后的非填充数据量;如果其值 >= 1536,则该字段值表示后续数据包所属的协议。以下为该字段的常见值:
|
||||
|
||||
* IPv4 = 0800H
|
||||
* IPv6 = 86DDH
|
||||
* ARP = 0806H
|
||||
|
||||
使用专有网络的用户可以将此字段配置为长度字段。然而,对于使用互联网协议 (IP) 或地址解析协议 (ARP) 等协议的应用程序,在传输数据包时,应将此字段配置为协议规范定义的适当类型。
|
||||
|
||||
数据有效载荷
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
数据有效载荷字段是一个可变长度的字段,长度从 0 到 1500 字节不等。更大的数据包会因违反以太网标准而被大多数以太网节点丢弃。
|
||||
|
||||
数据有效载荷字段包含客户端数据,如 IP 数据报。
|
||||
|
||||
填充及帧校验序列 (FCS)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
填充字段是一个可变长度的字段。数据有效载荷较小时,将添加填充字段以满足 IEEE 802.3 规范的要求。
|
||||
|
||||
以太网数据包的 DA、SA、类型、数据有效载荷和填充字段共计必须不小于 60 字节。加上所需的 4 字节 FCS 字段,数据包的长度必须不小于 64 字节。如果数据有效载荷字段小于 46 字节,则需要加上一个填充字段。
|
||||
|
||||
帧校验序列字段 (FCS) 长度为 4 字节,其中包含一个行业标准的 32 位 CRC,该 CRC 是根据 DA、SA、类型、数据有效载荷和填充字段的数据计算的。鉴于计算 CRC 的复杂性,硬件通常会自动生成一个有效的 CRC 进行传输。否则,需由主机控制器生成 CRC 并将其写入传输缓冲区。
|
||||
|
||||
通常情况下,主机控制器无需关注填充字段和 CRC 字段,因为这两部分可以在传输或接收时由硬件 EMAC 自动生成或验证。然而,当数据包到达时,填充字段和 CRC 字段将被写入接收缓冲区。因此,如果需要的话,主机控制器也可以对它们进行评估。
|
||||
|
||||
.. note::
|
||||
除了上述的基本数据帧,在 10/100 Mbps 以太网中还有两种常见的帧类型:控制帧和 VLAN 标记帧。ESP-IDF 不支持这两种帧类型。
|
||||
|
||||
.. ------------------------------ Driver Operation --------------------------------
|
||||
|
||||
.. _driver-configuration-and-installation:
|
||||
|
||||
配置 MAC 和 PHY
|
||||
---------------------
|
||||
|
||||
* :component_file:`esp_eth/include/esp_eth.h`
|
||||
以太网驱动器由两部分组成:MAC 和 PHY。
|
||||
|
||||
以太网通用接口
|
||||
-------------------------
|
||||
.. only:: SOC_EMAC_SUPPORTED
|
||||
|
||||
* :component_file:`esp_eth/include/esp_eth_com.h`
|
||||
MAC 和 PHY 之间的通信可以通过多种方式进行,如: **MII** (媒体独立接口)、 **RMII** (简化媒体独立接口)等。
|
||||
|
||||
以太网 MAC 接口
|
||||
----------------------
|
||||
.. figure:: ../../../_static/rmii-interface.png
|
||||
:scale: 80 %
|
||||
:alt: 以太网 RMII 接口
|
||||
:figclass: align-center
|
||||
|
||||
* :component_file:`esp_eth/include/esp_eth_mac.h`
|
||||
以太网 RMII 接口
|
||||
|
||||
以太网 PHY 接口
|
||||
----------------------
|
||||
MII 和 RMII 的一个明显区别在于其所需的信号数。MII 通常需要多达 18 个信号,RMII 接口则仅需要 9 个信号。
|
||||
|
||||
* :component_file:`esp_eth/include/esp_eth_phy.h`
|
||||
在 RMII 模式下,接收器和发射器信号的参考时钟为 ``REF_CLK``。 **在访问 PHY 和 MAC 时,REF_CLK 必须保持稳定**。一般来说,根据您设计中 PHY 设备的特征,可通过以下三种方式生成 ``REF_CLK``:
|
||||
|
||||
以太网 PHY 公共寄存器
|
||||
-----------------------------
|
||||
* 一些 PHY 芯片可以从其外部连接的 25 MHz 晶体振荡器中获取 ``REF_CLK`` (如图中的选项 *a* 所示)。对于此类芯片,请在 :ref:`CONFIG_ETH_RMII_CLK_MODE` 中选择 ``CONFIG_ETH_RMII_CLK_INPUT``。
|
||||
|
||||
* :component_file:`esp_eth/include/eth_phy_802_3_regs.h`
|
||||
* 一些 PHY 芯片使用可以作为 MAC 端 ``REF_CLK`` 的外接 50 MHz 晶体振荡器或其他时钟源(如图中的选项 *b* 所示)。对于此类芯片,请同样在 :ref:`CONFIG_ETH_RMII_CLK_MODE` 中选择 ``CONFIG_ETH_RMII_CLK_INPUT``。
|
||||
|
||||
API 参考 -- 驱动程序模型
|
||||
----------------------------
|
||||
* 一些 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`。
|
||||
|
||||
.. 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`。
|
||||
|
||||
如果配置 RMII 时钟模式为 ``CONFIG_ETH_RMII_CLK_INPUT``,那么有且只有 ``GPIO0`` 可以用来输入 ``REF_CLK`` 信号。请注意, ``GPIO0`` 同时也是 ESP32 上一个重要的 strapping GPIO 管脚。如果 GPIO0 在上电时采样为低电平,ESP32 将进入下载模式,需进行手动复位重启系统。解决这个问题的方法是,在硬件中默认禁用 ``REF_CLK``,从而避免 strapping 管脚在启动阶段受到其他信号的干扰。随后,再在以太网驱动安装阶段重新启用 ``REF_CLK``。
|
||||
|
||||
可以通过以下方法禁用 ``REF_CLK`` 信号:
|
||||
|
||||
* 禁用或关闭晶体振荡器的电源(对应图中的选项 *b*)。
|
||||
|
||||
* 强制复位 PHY 设备(对应图中的选项 *a*)。 **此种方法并不适用于所有 PHY 设备**,即便处于复位状态,某些 PHY 设备仍会向 GPIO0 输出信号。
|
||||
|
||||
**无论选择哪种 RMII 时钟模式,都请确保硬件设计中 REF_CLK 的信号完整性!** 信号线越短越好,并请保持信号线与 RF 设备和电感器元件的距离。
|
||||
|
||||
.. note::
|
||||
ESP-IDF 只支持 RMII 接口(即在 Kconfig 选项 :ref:`CONFIG_ETH_PHY_INTERFACE` 中始终选择 ``CONFIG_ETH_PHY_INTERFACE_RMII``)。
|
||||
|
||||
在数据平面使用的信号通过 MUX 连接至特定的 GPIO,这些信号无法配置至其他 GPIO。在控制平面使用的信号则可以通过 Matrix 矩阵路由到任何空闲 GPIO。相关的硬件设计示例,请参考 :doc:`ESP32-Ethernet-Kit <../../hw-reference/esp32/get-started-ethernet-kit>`。
|
||||
|
||||
根据您的以太网板设计,需要分别为 MAC 和 PHY 配置必要的参数,通过两者完成驱动程序的安装。
|
||||
|
||||
MAC 的相关配置可以在 :cpp:class:`eth_mac_config_t` 中找到,具体包括:
|
||||
|
||||
.. list::
|
||||
|
||||
* :cpp:member:`eth_mac_config_t::sw_reset_timeout_ms`:软件复位超时值,单位为毫秒。通常,MAC 复位应在 100 ms 内完成。
|
||||
|
||||
* :cpp:member:`eth_mac_config_t::rx_task_stack_size` 和 :cpp:member:`eth_mac_config_t::rx_task_prio`:MAC 驱动会创建一个专门的任务来处理传入的数据包,这两个参数用于设置该任务的堆栈大小和优先级。
|
||||
|
||||
* :cpp:member:`eth_mac_config_t::flags`:指定 MAC 驱动应支持的额外功能,尤其适用于某些特殊情况。这个字段的值支持与以 ``ETH_MAC_FLAG_`` 为前缀的宏进行 OR 运算。例如,如果 MAC 驱动应在禁用缓存后开始工作,那么则需要用 :c:macro:`ETH_MAC_FLAG_WORK_WITH_CACHE_DISABLE` 配置这个字段。
|
||||
|
||||
:SOC_EMAC_SUPPORTED: * :cpp:member:`eth_esp32_emac_config_t::smi_mdc_gpio_num` 和 :cpp:member:`eth_esp32_emac_config_t::smi_mdio_gpio_num`:连接 SMI 信号的 GPIO 编号。
|
||||
|
||||
:SOC_EMAC_SUPPORTED: * :cpp:member:`eth_esp32_emac_config_t::interface`:配置到 PHY (MII/RMII) 的 MAC 数据接口。
|
||||
|
||||
:SOC_EMAC_SUPPORTED: * :cpp:member:`eth_esp32_emac_config_t::clock_config`:配置 EMAC 接口时钟(RMII 模式下的 ``REF_CLK`` 模式以及 GPIO 编号)。
|
||||
|
||||
MAC 的相关配置可以在 :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::reset_timeout_ms`:复位超时值,单位为毫秒。通常,PHY 复位应在 100 ms 内完成。
|
||||
|
||||
* :cpp:member:`eth_phy_config_t::autonego_timeout_ms`:自动协商超时值,单位为毫秒。以太网驱动程序会自动与对等的以太网节点进行协商,以确定双工和速度模式。此值通常取决于您电路板上 PHY 设备的性能。
|
||||
|
||||
* :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 提供了默认配置。
|
||||
|
||||
|
||||
创建 MAC 和 PHY 实例
|
||||
---------------------------
|
||||
|
||||
以太网驱动是以面向对象的方式实现的。对 MAC 和 PHY 的任何操作都应基于实例。
|
||||
|
||||
.. only:: SOC_EMAC_SUPPORTED
|
||||
|
||||
内部 EMAC + 外部 PHY
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. highlight:: c
|
||||
|
||||
::
|
||||
|
||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); // 应用默认的 MAC 配置
|
||||
mac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO; // 更改用于 MDC 信号的 GPIO
|
||||
mac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; // 更改用于 MDIO 信号的 GPIO
|
||||
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config); // 创建 MAC 实例
|
||||
|
||||
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); // 应用默认的 PHY 配置
|
||||
phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR; // 根据开发板设计更改 PHY 地址
|
||||
phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO; // 更改用于 PHY 复位的 GPIO
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config); // 创建 PHY 实例
|
||||
// ESP-IDF 为数种以太网 PHY 芯片驱动提供官方支持
|
||||
// esp_eth_phy_t *phy = esp_eth_phy_new_rtl8201(&phy_config);
|
||||
// esp_eth_phy_t *phy = esp_eth_phy_new_lan8720(&phy_config);
|
||||
// esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config);
|
||||
|
||||
可选的运行时 MAC 时钟配置
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
可以通过用户应用程序代码,选择性配置 EMAC 中的 ``REF_CLK``。
|
||||
|
||||
.. highlight:: c
|
||||
|
||||
::
|
||||
|
||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); // 应用默认的 MAC 配置
|
||||
|
||||
// ...
|
||||
|
||||
mac_config.interface = EMAC_DATA_INTERFACE_RMII; // 更改 EMAC 数据接口
|
||||
mac_config.clock_config.rmii.clock_mode = EMAC_CLK_OUT; // 配置 EMAC REF_CLK 模式
|
||||
mac_config.clock_config.rmii.clock_gpio = EMAC_CLK_OUT_GPIO; // 配置用于输入/输出 EMAC REF_CLK 的 GPIO 编号
|
||||
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config); // 创建 MAC 实例
|
||||
|
||||
|
||||
SPI-Ethernet 模块
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. highlight:: c
|
||||
|
||||
::
|
||||
|
||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); // 应用默认的 MAC 配置
|
||||
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); // 应用默认的 PHY 配置
|
||||
phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR; // 根据开发板设计更改 PHY 地址
|
||||
phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO; // 更改用于 PHY 复位的 GPIO
|
||||
// 安装 GPIO 中断服务(因为 SPI-Ethernet 模块为中断驱动)
|
||||
gpio_install_isr_service(0);
|
||||
// 配置 SPI 总线
|
||||
spi_device_handle_t spi_handle = NULL;
|
||||
spi_bus_config_t buscfg = {
|
||||
.miso_io_num = CONFIG_EXAMPLE_ETH_SPI_MISO_GPIO,
|
||||
.mosi_io_num = CONFIG_EXAMPLE_ETH_SPI_MOSI_GPIO,
|
||||
.sclk_io_num = CONFIG_EXAMPLE_ETH_SPI_SCLK_GPIO,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1,
|
||||
};
|
||||
ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, 1));
|
||||
// 配置 SPI 从机设备
|
||||
spi_device_interface_config_t spi_devcfg = {
|
||||
.mode = 0,
|
||||
.clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
|
||||
.spics_io_num = CONFIG_EXAMPLE_ETH_SPI_CS_GPIO,
|
||||
.queue_size = 20
|
||||
};
|
||||
/* dm9051 ethernet driver is based on spi driver */
|
||||
eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg);
|
||||
dm9051_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO;
|
||||
esp_eth_mac_t *mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config);
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_dm9051(&phy_config);
|
||||
|
||||
|
||||
.. note::
|
||||
* 当为 SPI-Ethernet 模块(例如 DM9051)创建 MAC 和 PHY 实例时,由于 PHY 是集成在模块中的,因此调用的实例创建函数的后缀须保持一致(例如 `esp_eth_mac_new_dm9051` 和 `esp_eth_phy_new_dm9051` 搭配使用)。
|
||||
|
||||
* 针对不同的以太网模块,或是为了满足特定 PCB 上的 SPI 时序,SPI 从机设备配置(即 `spi_device_interface_config_t`)可能略有不同。具体配置请查看模块规格以及 ESP-IDF 中的示例。
|
||||
|
||||
|
||||
安装驱动程序
|
||||
--------------
|
||||
|
||||
安装以太网驱动程序需要结合 MAC 和 PHY 实例,并在 :cpp:class:`esp_eth_config_t` 中配置一些额外的高级选项(即不仅限于 MAC 或 PHY 的选项):
|
||||
|
||||
* :cpp:member:`esp_eth_config_t::mac`:由 MAC 生成器创建的实例(例如 :cpp:func:`esp_eth_mac_new_esp32`)。
|
||||
|
||||
* :cpp:member:`esp_eth_config_t::phy`:由 PHY 生成器创建的实例(例如 :cpp:func:`esp_eth_phy_new_ip101`)。
|
||||
|
||||
* :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::on_lowlevel_init_done` 和 :cpp:member:`esp_eth_config_t::on_lowlevel_deinit_done`: 这两个字段用于指定钩子函数,当去初始化或初始化低级别硬件时,会调用钩子函数。
|
||||
|
||||
ESP-IDF 在宏 :c:macro:`ETH_DEFAULT_CONFIG` 中为安装驱动程序提供了一个默认配置。
|
||||
|
||||
.. highlight:: c
|
||||
|
||||
::
|
||||
|
||||
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy); // 应用默认驱动程序配置
|
||||
esp_eth_handle_t eth_handle = NULL; // 驱动程序安装完毕后,将得到驱动程序的句柄
|
||||
esp_eth_driver_install(&config, ð_handle); // 安装驱动程序
|
||||
|
||||
以太网驱动程序包含事件驱动模型,该模型会向用户空间发送有用及重要的事件。安装以太网驱动程序之前,需要首先初始化事件循环。有关事件驱动编程的更多信息,请参考 :doc:`ESP Event <../system/esp_event>`.
|
||||
|
||||
.. highlight:: c
|
||||
|
||||
::
|
||||
|
||||
/** 以太网事件的事件处理程序 */
|
||||
static void eth_event_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
uint8_t mac_addr[6] = {0};
|
||||
/* 可从事件数据中获得以太网驱动句柄 */
|
||||
esp_eth_handle_t eth_handle = *(esp_eth_handle_t *)event_data;
|
||||
|
||||
switch (event_id) {
|
||||
case ETHERNET_EVENT_CONNECTED:
|
||||
esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr);
|
||||
ESP_LOGI(TAG, "Ethernet Link Up");
|
||||
ESP_LOGI(TAG, "Ethernet HW Addr %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||
break;
|
||||
case ETHERNET_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(TAG, "Ethernet Link Down");
|
||||
break;
|
||||
case ETHERNET_EVENT_START:
|
||||
ESP_LOGI(TAG, "Ethernet Started");
|
||||
break;
|
||||
case ETHERNET_EVENT_STOP:
|
||||
ESP_LOGI(TAG, "Ethernet Stopped");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
esp_event_loop_create_default(); // 创建一个在后台运行的默认事件循环
|
||||
esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, NULL); // 注册以太网事件处理程序(用于在发生 link up/down 等事件时,处理特定的用户相关内容)
|
||||
|
||||
启动以太网驱动程序
|
||||
---------------------
|
||||
|
||||
安装驱动程序后,可以立即启动以太网。
|
||||
|
||||
.. highlight:: c
|
||||
|
||||
::
|
||||
|
||||
esp_eth_start(eth_handle); // 启动以太网驱动程序状态机
|
||||
|
||||
.. _connect-driver-to-stack:
|
||||
|
||||
连接驱动程序至 TCP/IP 协议栈
|
||||
------------------------------
|
||||
|
||||
现在,以太网驱动程序已经完成安装。但对应 OSI(开放式系统互连模型)来看,目前阶段仍然属于第二层(即数据链路层)。这意味着可以检测到 link up/down 事件,获得用户空间的 MAC 地址,但无法获得 IP 地址,当然也无法发送 HTTP 请求。ESP-IDF 中使用的 TCP/IP 协议栈是 LwIP,关于 LwIP 的更多信息,请参考 :doc:`LwIP <../../api-guides/lwip>`。
|
||||
|
||||
要将以太网驱动程序连接至 TCP/IP 协议栈,需要以下三步:
|
||||
|
||||
1. 为以太网驱动程序创建网络接口
|
||||
2. 将网络接口连接到以太网驱动程序
|
||||
3. 注册 IP 事件处理程序
|
||||
|
||||
有关网络接口的更多信息,请参考 :doc:`Network Interface <esp_netif>`。
|
||||
|
||||
.. highlight:: c
|
||||
|
||||
::
|
||||
|
||||
/** IP_EVENT_ETH_GOT_IP 的事件处理程序 */
|
||||
static void got_ip_event_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data;
|
||||
const esp_netif_ip_info_t *ip_info = &event->ip_info;
|
||||
|
||||
ESP_LOGI(TAG, "Ethernet Got IP Address");
|
||||
ESP_LOGI(TAG, "~~~~~~~~~~~");
|
||||
ESP_LOGI(TAG, "ETHIP:" IPSTR, IP2STR(&ip_info->ip));
|
||||
ESP_LOGI(TAG, "ETHMASK:" IPSTR, IP2STR(&ip_info->netmask));
|
||||
ESP_LOGI(TAG, "ETHGW:" IPSTR, IP2STR(&ip_info->gw));
|
||||
ESP_LOGI(TAG, "~~~~~~~~~~~");
|
||||
}
|
||||
|
||||
esp_netif_init()); // 初始化 TCP/IP 网络接口(在应用程序中应仅调用一次)
|
||||
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH(); // 应用以太网的默认网络接口配置
|
||||
esp_netif_t *eth_netif = esp_netif_new(&cfg); // 为以太网驱动程序创建网络接口
|
||||
|
||||
esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle)); // 将以太网驱动程序连接至 TCP/IP 协议栈
|
||||
esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL); // 注册用户定义的 IP 事件处理程序
|
||||
esp_eth_start(eth_handle); // 启动以太网驱动程序状态机
|
||||
|
||||
.. warning::
|
||||
推荐在完成整个以太网驱动和网络接口的初始化后,再注册用户定义的以太网/IP 事件处理程序,也就是把注册事件处理程序作为启动以太网驱动程序的最后一步。这样可以确保以太网驱动程序或网络接口将首先执行以太网/IP 事件,从而保证在执行用户定义的处理程序时,系统处于预期状态。
|
||||
|
||||
.. _misc-operation-of-driver:
|
||||
|
||||
以太网驱动程序的杂项控制
|
||||
-------------------------------
|
||||
|
||||
以下功能只支持在安装以太网驱动程序后调用。
|
||||
|
||||
* 关闭以太网驱动程序::cpp:func:`esp_eth_stop`
|
||||
* 更新以太网数据输入路径::cpp:func:`esp_eth_update_input_path`
|
||||
* 获取/设置以太网驱动程序杂项内容::cpp:func:`esp_eth_ioctl`
|
||||
|
||||
.. highlight:: c
|
||||
|
||||
::
|
||||
|
||||
/* 获取 MAC 地址 */
|
||||
uint8_t mac_addr[6];
|
||||
memset(mac_addr, 0, sizeof(mac_addr));
|
||||
esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr);
|
||||
ESP_LOGI(TAG, "Ethernet MAC Address: %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||
|
||||
/* 获取 PHY 地址 */
|
||||
int phy_addr = -1;
|
||||
esp_eth_ioctl(eth_handle, ETH_CMD_G_PHY_ADDR, &phy_addr);
|
||||
ESP_LOGI(TAG, "Ethernet PHY Address: %d", phy_addr);
|
||||
|
||||
.. _flow-control:
|
||||
|
||||
数据流量控制
|
||||
------------
|
||||
|
||||
受 RAM 大小限制,在网络拥堵时,MCU 上的以太网通常仅能处理有限数量的帧。发送站的数据传输速度可能快于对等端的接收能力。以太网数据流量控制机制允许接收节点向发送方发出信号,要求暂停传输,直到接收方跟上。这项功能是通过暂停帧实现的,该帧定义在 IEEE 802.3x 中。
|
||||
|
||||
暂停帧是一种特殊的以太网帧,用于携带暂停命令,其 EtherType 字段为 0x8808,控制操作码为 0x0001。只有配置为全双工操作的节点组可以发送暂停帧。当节点组希望暂停链路的另一端时,它会发送一个暂停帧到 48 位的保留组播地址 01-80-C2-00-00-01。暂停帧中也包括请求暂停的时间段,以两字节的整数形式发送,值的范围从 0 到 65535。
|
||||
|
||||
安装以太网驱动程序后,数据流量控制功能默认禁用,可以通过以下方式启用此功能:
|
||||
|
||||
.. highlight:: c
|
||||
|
||||
::
|
||||
|
||||
bool flow_ctrl_enable = true;
|
||||
esp_eth_ioctl(eth_handle, ETH_CMD_S_FLOW_CTRL, &flow_ctrl_enable);
|
||||
|
||||
需注意,暂停帧是在自动协商期间由 PHY 向对等端公布的。只有当链路的两边都支持暂停帧时,以太网驱动程序才会发送暂停帧。
|
||||
|
||||
.. -------------------------------- Examples -----------------------------------
|
||||
|
||||
应用示例
|
||||
--------------------
|
||||
|
||||
* 以太网基本示例::example:`ethernet/basic`
|
||||
* 以太网 iperf 示例::example:`ethernet/iperf`
|
||||
* 以太网到 Wi-Fi AP “路由器”::example:`ethernet/eth2ap`
|
||||
* 大多数协议示例也适用于以太网::example:`protocols`
|
||||
|
||||
.. ------------------------------ Advanced Topics -------------------------------
|
||||
|
||||
.. _advanced-topics:
|
||||
|
||||
进阶操作
|
||||
---------------
|
||||
|
||||
自定义 PHY 驱动程序
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
目前市面上已有多家 PHY 制造商提供了大量的芯片组合。ESP-IDF 现已支持数种 PHY 芯片,但是由于价格、功能、库存等原因,有时用户还是无法找到一款能满足其实际需求的芯片。
|
||||
|
||||
好在 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 管理功能,这个过程将变得较为复杂。
|
||||
|
||||
ESP-IDF 以太网驱动程序所需的大部分 PHY 管理功能都已涵盖在 :component_file:`esp_eth/src/esp_eth_phy_802_3.c` 中。不过对于以下几项,可能仍需针对不同芯片开发具体的管理功能:
|
||||
|
||||
* 链接状态。此项总是由使用的具体芯片决定
|
||||
* 芯片初始化。即使不存在严格的限制,也应进行自定义,以确保使用的是符合预期的芯片
|
||||
* 芯片的具体功能配置
|
||||
|
||||
**创建自定义 PHY 驱动程序的步骤:**
|
||||
|
||||
1. 请根据 PHY 数据手册,定义针对供应商的特定注册表布局。示例请参见 :component_file:`esp_eth/src/esp_eth_phy_ip101.c`。
|
||||
2. 准备衍生的 PHY 管理对象信息结构,该结构:
|
||||
|
||||
* 必须至少包含 IEEE 802.3 :cpp:class:`phy_802_3_t` 父对象
|
||||
* 可选包含支持非 IEEE 802.3 或自定义功能所需的额外变量。示例请参见 :component_file:`esp_eth/src/esp_eth_phy_ksz80xx.c`。
|
||||
|
||||
3. 定义针对芯片的特定管理回调功能。
|
||||
4. 初始化 IEEE 802.3 父对象并重新分配针对芯片的特定管理回调功能。
|
||||
|
||||
实现新的自定义 PHY 驱动程序后,你可以通过 `IDF组件管理中心 <https://components.espressif.com/>`_ 将驱动分享给其他用户。
|
||||
|
||||
.. ---------------------------- API Reference ----------------------------------
|
||||
|
||||
API 参考
|
||||
-------------
|
||||
|
||||
.. include-build-file:: inc/esp_eth.inc
|
||||
|
||||
API 参考 -- 通用接口
|
||||
--------------------------------
|
||||
|
||||
.. include-build-file:: inc/esp_eth_driver.inc
|
||||
.. include-build-file:: inc/esp_eth_com.inc
|
||||
|
||||
API 参考 -- MAC 接口
|
||||
-----------------------------
|
||||
|
||||
.. include-build-file:: inc/esp_eth_mac.inc
|
||||
|
||||
API 参考 -- PHY 接口
|
||||
-----------------------------
|
||||
|
||||
.. include-build-file:: inc/esp_eth_phy.inc
|
||||
|
||||
API 参考 -- esp_netif 相关使用
|
||||
----------------------------------
|
||||
|
||||
.. include-build-file:: inc/esp_eth_phy_802_3.inc
|
||||
.. include-build-file:: inc/esp_eth_netif_glue.inc
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue