From c7fd71a893e5e72c3427d3a6fc1ce34403bb01eb Mon Sep 17 00:00:00 2001 From: intern Date: Mon, 24 Jan 2022 14:07:30 +0800 Subject: [PATCH] docs: update wifi and nvs cn trans --- docs/en/api-guides/wifi.rst | 2079 +++++++++-------- docs/en/api-reference/storage/nvs_flash.rst | 3 - docs/zh_CN/api-guides/wifi.rst | 1935 +++++++++------ .../zh_CN/api-reference/storage/nvs_flash.rst | 266 ++- 4 files changed, 2466 insertions(+), 1817 deletions(-) diff --git a/docs/en/api-guides/wifi.rst b/docs/en/api-guides/wifi.rst index 94695a20fa..51a3f11fb6 100644 --- a/docs/en/api-guides/wifi.rst +++ b/docs/en/api-guides/wifi.rst @@ -22,7 +22,9 @@ How To Write a Wi-Fi Application Preparation +++++++++++ -Generally, the most effective way to begin your own Wi-Fi application is to select an example which is similar to your own application, and port the useful part into your project. It is not a MUST but it is strongly recommended that you take some time to read this article first, especially if you want to program a robust Wi-Fi application. This article is supplementary to the Wi-Fi APIs/Examples. It describes the principles of using the Wi-Fi APIs, the limitations of the current Wi-Fi API implementation, and the most common pitfalls in using Wi-Fi. This article also reveals some design details of the Wi-Fi driver. We recommend you to select an :example:`example `. +Generally, the most effective way to begin your own Wi-Fi application is to select an example which is similar to your own application, and port the useful part into your project. It is not a MUST but it is strongly recommended that you take some time to read this article first, especially if you want to program a robust Wi-Fi application. + +This article is supplementary to the Wi-Fi APIs/Examples. It describes the principles of using the Wi-Fi APIs, the limitations of the current Wi-Fi API implementation, and the most common pitfalls in using Wi-Fi. This article also reveals some design details of the Wi-Fi driver. We recommend you to select an :example:`example `. Setting Wi-Fi Compile-time Options ++++++++++++++++++++++++++++++++++++ @@ -62,8 +64,7 @@ Whether the error is critical or not depends on the API and the application scen - for non-recoverable, yet non-critical, errors, in which case printing the error code is a good method for error handling. - for non-recoverable, critical errors, in which case "assert" may be a good method for error handling. For example, if :cpp:func:`esp_wifi_set_mode` returns ESP_ERR_WIFI_NOT_INIT, it means that the Wi-Fi driver is not initialized by :cpp:func:`esp_wifi_init` successfully. You can detect this kind of error very quickly in the application development phase. -In esp_err.h, ESP_ERROR_CHECK checks the return values. It is a rather commonplace error-handling code and can be used -as the default error-handling code in the application development phase. However, we strongly recommend that API users write their own error-handling code. +In esp_err.h, ESP_ERROR_CHECK checks the return values. It is a rather commonplace error-handling code and can be used as the default error-handling code in the application development phase. However, we strongly recommend that API users write their own error-handling code. {IDF_TARGET_NAME} Wi-Fi API Parameter Initialization ---------------------------------------------------- @@ -419,40 +420,24 @@ Currently, the :cpp:func:`esp_wifi_scan_start()` API is supported only in Statio Scan Type +++++++++++++++++++++++++ -+------------------+--------------------------------------------------------------+ -| Mode | Description | -+==================+==============================================================+ -| Active Scan | Scan by sending a probe request. | -| | The default scan is an active scan. | -| | | -+------------------+--------------------------------------------------------------+ -| Passive Scan | No probe request is sent out. Just switch to the specific | -| | channel and wait for a beacon. | -| | Application can enable it via the scan_type field of | -| | wifi_scan_config_t. | -| | | -+------------------+--------------------------------------------------------------+ -| Foreground Scan | This scan is applicable when there is no Wi-Fi connection | -| | in Station mode. Foreground or background scanning is | -| | controlled by the Wi-Fi driver and cannot be configured by | -| | the application. | -+------------------+--------------------------------------------------------------+ -| Background Scan | This scan is applicable when there is a Wi-Fi connection in | -| | Station mode or in Station+AP mode. | -| | Whether it is a foreground scan or background scan depends on| -| | the Wi-Fi driver and cannot be configured by the application.| -| | | -+------------------+--------------------------------------------------------------+ -| All-Channel Scan | It scans all of the channels. | -| | If the channel field of wifi_scan_config_t is set | -| | to 0, it is an all-channel scan. | -| | | -+------------------+--------------------------------------------------------------+ -| Specific Channel | It scans specific channels only. | -| Scan | If the channel field of wifi_scan_config_t set to | -| | 1, it is a specific-channel scan. | -| | | -+------------------+--------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 50 + + * - Mode + - Description + * - Active Scan + - Scan by sending a probe request. The default scan is an active scan. + * - Passive Scan + - No probe request is sent out. Just switch to the specific channel and wait for a beacon. Application can enable it via the scan_type field of wifi_scan_config_t. + * - Foreground Scan + - This scan is applicable when there is no Wi-Fi connection in station mode. Foreground or background scanning is controlled by the Wi-Fi driver and cannot be configured by the application. + * - Background Scan + - This scan is applicable when there is a Wi-Fi connection in station mode or in station/AP mode. Whether it is a foreground scan or background scan depends on the Wi-Fi driver and cannot be configured by the application. + * - All-Channel Scan + - It scans all of the channels. If the channel field of wifi_scan_config_t is set to 0, it is an all-channel scan. + * - Specific Channel Scan + - It scans specific channels only. If the channel field of wifi_scan_config_t set to 1-14, it is a specific-channel scan. The scan modes in above table can be combined arbitrarily, so we totally have 8 different scans: @@ -470,51 +455,35 @@ Scan Configuration The scan type and other per-scan attributes are configured by :cpp:func:`esp_wifi_scan_start`. The table below provides a detailed description of wifi_scan_config_t. -+------------------+--------------------------------------------------------------+ -| Field | Description | -+==================+==============================================================+ -| ssid | If the SSID is not NULL, it is only the AP with the same | -| | SSID that can be scanned. | -| | | -+------------------+--------------------------------------------------------------+ -| bssid | If the BSSID is not NULL, it is only the AP with the same | -| | BSSID that can be scanned. | -| | | -+------------------+--------------------------------------------------------------+ -| channel | If "channel" is 0, there will be an all-channel scan; | -| | otherwise, there will be a specific-channel scan. | -| | | -+------------------+--------------------------------------------------------------+ -| show_hidden | If "show_hidden" is 0, the scan ignores the AP with a hidden | -| | SSID; otherwise, the scan considers the hidden AP a normal | -| | one. | -+------------------+--------------------------------------------------------------+ -| scan_type | If "scan_type" is WIFI_SCAN_TYPE_ACTIVE, the scan is | -| | "active"; otherwise, it is a "passive" one. | -| | | -+------------------+--------------------------------------------------------------+ -| scan_time | This field is used to control how long the scan dwells on | -| | each channel. | -| | | -| | For passive scans, scan_time.passive designates the dwell | -| | time for each channel. | -| | | -| | For active scans, dwell times for each channel are listed | -| | in the table below. Here, min is short for scan | -| | time.active.min and max is short for scan_time.active.max. | -| | | -| | - min=0, max=0: scan dwells on each channel for 120 ms. | -| | - min>0, max=0: scan dwells on each channel for 120 ms. | -| | - min=0, max>0: scan dwells on each channel for ``max`` ms. | -| | - min>0, max>0: the minimum time the scan dwells on each | -| | channel is ``min`` ms. If no AP is found during this time | -| | frame, the scan switches to the next channel. Otherwise, | -| | the scan dwells on the channel for ``max`` ms. | -| | | -| | If you want to improve the performance of the | -| | the scan, you can try to modify these two parameters. | -| | | -+------------------+--------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 50 + + * - Field + - Description + * - ssid + - If the SSID is not NULL, it is only the AP with the same SSID that can be scanned. + * - bssid + - If the BSSID is not NULL, it is only the AP with the same BSSID that can be scanned. + * - channel + - If “channel” is 0, there will be an all-channel scan; otherwise, there will be a specific-channel scan. + * - show_hidden + - If “show_hidden” is 0, the scan ignores the AP with a hidden SSID; otherwise, the scan considers the hidden AP a normal one. + * - scan_type + - If “scan_type” is WIFI_SCAN_TYPE_ACTIVE, the scan is “active”; otherwise, it is a “passive” one. + * - scan_time + - This field is used to control how long the scan dwells on each channel. + + For passive scans, scan_time.passive designates the dwell time for each channel. + + For active scans, dwell times for each channel are listed in the table below. Here, min is short for scan time.active.min and max is short for scan_time.active.max. + + - min=0, max=0: scan dwells on each channel for 120 ms. + - min>0, max=0: scan dwells on each channel for 120 ms. + - min=0, max>0: scan dwells on each channel for ``max`` ms. + - min>0, max>0: the minimum time the scan dwells on each channel is ``min`` ms. If no AP is found during this time frame, the scan switches to the next channel. Otherwise, the scan dwells on the channel for ``max`` ms. + + If you want to improve the performance of the scan, you can try to modify these two parameters. There are also some global scan attributes which are configured by API :cpp:func:`esp_wifi_set_config`, refer to `Station Basic Configuration`_ @@ -774,252 +743,258 @@ Wi-Fi Reason Code The table below shows the reason-code defined in {IDF_TARGET_NAME}. The first column is the macro name defined in esp_wifi_types.h. The common prefix *WIFI_REASON* is removed, which means that *UNSPECIFIED* actually stands for *WIFI_REASON_UNSPECIFIED* and so on. The second column is the value of the reason. The third column is the standard value to which this reason is mapped in section 8.4.1.7 of IEEE 802.11-2012. (For more information, refer to the standard mentioned above.) The last column is a description of the reason. -+---------------------------+-------+---------+-------------------------------------------------------------+ -| Reason code | Value |Mapped To| Description | -+===========================+=======+=========+=============================================================+ -| UNSPECIFIED | 1 | 1 | Generally, it means an internal failure, e.g., the memory | -| | | | runs out, the internal TX fails, or the reason is received | -| | | | from the remote side, etc. | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| AUTH_EXPIRE | 2 | 2 | The previous authentication is no longer valid. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - auth is timed out. | -| | | | - the reason is received from the AP. | -| | | | | -| | | | For the ESP AP, this reason is reported when: | -| | | | | -| | | | - the AP has not received any packets from the station | -| | | | in the past five minutes. | -| | | | - the AP is stopped by calling :cpp:func:`esp_wifi_stop()`.| -| | | | - the station is de-authed by calling | -| | | | :cpp:func:`esp_wifi_deauth_sta()`. | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| AUTH_LEAVE | 3 | 3 | De-authenticated, because the sending STA is | -| | | | leaving (or has left). | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| ASSOC_EXPIRE | 4 | 4 | Disassociated due to inactivity. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -| | | | For the ESP AP, this reason is reported when: | -| | | | | -| | | | - the AP has not received any packets from the | -| | | | station in the past five minutes. | -| | | | - the AP is stopped by calling :cpp:func:`esp_wifi_stop()` | -| | | | - the station is de-authed by calling | -| | | | :cpp:func:`esp_wifi_deauth_sta()` | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| ASSOC_TOOMANY | 5 | 5 | Disassociated, because the AP is unable to handle | -| | | | all currently associated STAs at the same time. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -| | | | For the ESP AP, this reason is reported when: | -| | | | | -| | | | - the stations associated with the AP reach the | -| | | | maximum number that the AP can support. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| NOT_AUTHED | 6 | 6 | Class-2 frame received from a non-authenticated STA. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -| | | | For the ESP AP, this reason is reported when: | -| | | | | -| | | | - the AP receives a packet with data from a | -| | | | non-authenticated station. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| NOT_ASSOCED | 7 | 7 | Class-3 frame received from a non-associated STA. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -| | | | For the ESP AP, this reason is reported when: | -| | | | | -| | | | - the AP receives a packet with data from a | -| | | | non-associated station. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| ASSOC_LEAVE | 8 | 8 | Disassociated, because the sending STA is leaving (or has | -| | | | left) BSS. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | - the station is disconnected by | -| | | | :cpp:func:`esp_wifi_disconnect()` and other APIs. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| ASSOC_NOT_AUTHED | 9 | 9 | STA requesting (re)association is not authenticated by the | -| | | | responding STA. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -| | | | For the ESP AP, this reason is reported when: | -| | | | | -| | | | - the AP receives packets with data from an | -| | | | associated, yet not authenticated, station. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| DISASSOC_PWRCAP_BAD | 10 | 10 | Disassociated, because the information in the Power | -| | | | Capability element is unacceptable. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| DISASSOC_SUPCHAN_BAD | 11 | 11 | Disassociated, because the information in the Supported | -| | | | Channels element is unacceptable. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| IE_INVALID | 13 | 13 | Invalid element, i.e. an element whose content does not meet| -| | | | the specifications of the Standard in frame formats clause. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -| | | | For the ESP AP, this reason is reported when: | -| | | | | -| | | | - the AP parses a wrong WPA or RSN IE. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| MIC_FAILURE | 14 | 14 | Message integrity code (MIC) failure. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| 4WAY_HANDSHAKE_TIMEOUT | 15 | 15 | Four-way handshake times out. For legacy reasons, in ESP | -| | | | this reason-code is replaced with | -| | | | WIFI_REASON_HANDSHAKE_TIMEOUT. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - the handshake times out. | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| GROUP_KEY_UPDATE_TIMEOUT | 16 | 16 | Group-Key Handshake times out. | -| | | | | -| | | | For the ESP station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| IE_IN_4WAY_DIFFERS | 17 | 17 | The element in the four-way handshake is different from the | -| | | | (Re-)Association Request/Probe and Response/Beacon frame. | -| | | | | -| | | | For the ESP station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | - the station finds that the four-way handshake IE differs | -| | | | from the IE in the (Re-)Association Request/Probe and | -| | | | Response/Beacon frame. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| GROUP_CIPHER_INVALID | 18 | 18 | Invalid group cipher. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| PAIRWISE_CIPHER_INVALID | 19 | 19 | Invalid pairwise cipher. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| AKMP_INVALID | 20 | 20 | Invalid AKMP. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| UNSUPP_RSN_IE_VERSION | 21 | 21 | Unsupported RSNE version. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| INVALID_RSN_IE_CAP | 22 | 22 | Invalid RSNE capabilities. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| 802_1X_AUTH_FAILED | 23 | 23 | IEEE 802.1X. authentication failed. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -| | | | For the ESP AP, this reason is reported when: | -| | | | | -| | | | - 802.1 x authentication fails. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| CIPHER_SUITE_REJECTED | 24 | 24 | Cipher suite rejected due to security policies. | -| | | | | -| | | | For the ESP Station, this reason is reported when: | -| | | | | -| | | | - it is received from the AP. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| BEACON_TIMEOUT | 200 |reserved | Espressif-specific Wi-Fi reason-code: when the station | -| | | | loses N beacons continuously, it will disrupt the connection| -| | | | and report this reason. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| NO_AP_FOUND | 201 |reserved | Espressif-specific Wi-Fi reason-code: when the station | -| | | | fails to scan the target AP, this reason code will be | -| | | | reported. | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| AUTH_FAIL | 202 |reserved | Espressif-specific Wi-Fi reason-code: the | -| | | | authentication fails, but not because of a timeout. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| ASSOC_FAIL | 203 |reserved | Espressif-specific Wi-Fi reason-code: the association | -| | | | fails, but not because of ASSOC_EXPIRE or ASSOC_TOOMANY. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| HANDSHAKE_TIMEOUT | 204 |reserved | Espressif-specific Wi-Fi reason-code: the | -| | | | handshake fails for the same reason as that in | -| | | | WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ -| CONNECTION_FAIL | 205 |reserved | Espressif-specific Wi-Fi reason-code: the | -| | | | connection to the AP has failed. | -| | | | | -+---------------------------+-------+---------+-------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 5 10 12 40 + + * - Reason code + - Value + - Mapped To + - Description + * - UNSPECIFIED + - 1 + - 1 + - Generally, it means an internal failure, e.g., the memory runs out, the internal TX fails, or the reason is received from the remote side, etc. + * - AUTH_EXPIRE + - 2 + - 2 + - The previous authentication is no longer valid. + + For the ESP station, this reason is reported when: + + - auth is timed out. + - the reason is received from the AP. + + For the ESP AP, this reason is reported when: + + - the AP has not received any packets from the station in the past five minutes. + - the AP is stopped by calling :cpp:func:`esp_wifi_stop()`. + - the station is de-authed by calling :cpp:func:`esp_wifi_deauth_sta()`. + * - AUTH_LEAVE + - 3 + - 3 + - De-authenticated, because the sending station is leaving (or has left). + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - ASSOC_EXPIRE + - 4 + - 4 + - Disassociated due to inactivity. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + + For the ESP AP, this reason is reported when: + + - the AP has not received any packets from the station in the past five minutes. + - the AP is stopped by calling :cpp:func:`esp_wifi_stop()`. + - the station is de-authed by calling :cpp:func:`esp_wifi_deauth_sta()`. + * - ASSOC_TOOMANY + - 5 + - 5 + - Disassociated, because the AP is unable to handle all currently associated STAs at the same time. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + + For the ESP AP, this reason is reported when: + + - the stations associated with the AP reach the maximum number that the AP can support. + * - NOT_AUTHED + - 6 + - 6 + - Class-2 frame received from a non-authenticated STA. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + + For the ESP AP, this reason is reported when: + + - the AP receives a packet with data from a non-authenticated station. + * - NOT_ASSOCED + - 7 + - 7 + - Class-3 frame received from a non-associated STA. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + + For the ESP AP, this reason is reported when: + + - the AP receives a packet with data from a non-associated station. + * - ASSOC_LEAVE + - 8 + - 8 + - Disassociated, because the sending station is leaving (or has left) BSS. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + - the station is disconnected by :cpp:func:`esp_wifi_disconnect()` and other APIs. + * - ASSOC_NOT_AUTHED + - 9 + - 9 + - station requesting (re)association is not authenticated by the responding STA. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + + For the ESP AP, this reason is reported when: + + - the AP receives packets with data from an associated, yet not authenticated, station. + * - DISASSOC_PWRCAP_BAD + - 10 + - 10 + - Disassociated, because the information in the Power Capability element is unacceptable. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - DISASSOC_SUPCHAN_BAD + - 11 + - 11 + - Disassociated, because the information in the Supported Channels element is unacceptable. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - IE_INVALID + - 13 + - 13 + - Invalid element, i.e. an element whose content does not meet the specifications of the Standard in frame formats clause. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + + For the ESP AP, this reason is reported when: + + - the AP parses a wrong WPA or RSN IE. + * - MIC_FAILURE + - 14 + - 14 + - Message integrity code (MIC) failure. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - 4WAY_HANDSHAKE_TIMEOUT + - 15 + - 15 + - Four-way handshake times out. For legacy reasons, in ESP this reason-code is replaced with WIFI_REASON_HANDSHAKE_TIMEOUT. + + For the ESP station, this reason is reported when: + + - the handshake times out. + - it is received from the AP. + * - GROUP_KEY_UPDATE_TIMEOUT + - 16 + - 16 + - Group-Key Handshake times out. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - IE_IN_4WAY_DIFFERS + - 17 + - 17 + - The element in the four-way handshake is different from the (Re-)Association Request/Probe and Response/Beacon frame. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + - the station finds that the four-way handshake IE differs from the IE in the (Re-)Association Request/Probe and Response/Beacon frame. + * - GROUP_CIPHER_INVALID + - 18 + - 18 + - Invalid group cipher. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - PAIRWISE_CIPHER_INVALID + - 19 + - 19 + - Invalid pairwise cipher. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - AKMP_INVALID + - 20 + - 20 + - Invalid AKMP. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - UNSUPP_RSN_IE_VERSION + - 21 + - 21 + - Unsupported RSNE version. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - INVALID_RSN_IE_CAP + - 22 + - 22 + - Invalid RSNE capabilities. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - 802_1X_AUTH_FAILED + - 23 + - 23 + - IEEE 802.1X. authentication failed. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + + For the ESP AP, this reason is reported when: + + - IEEE 802.1X. authentication fails. + * - CIPHER_SUITE_REJECTED + - 24 + - 24 + - Cipher suite rejected due to security policies. + + For the ESP station, this reason is reported when: + + - it is received from the AP. + * - BEACON_TIMEOUT + - 200 + - reserved + - Espressif-specific Wi-Fi reason-code: when the station loses N beacons continuously, it will disrupt the connection and report this reason. + * - NO_AP_FOUND + - 201 + - reserved + - Espressif-specific Wi-Fi reason-code: when the station fails to scan the target AP, this reason code will be reported. + * - AUTH_FAIL + - 202 + - reserved + - Espressif-specific Wi-Fi reason-code: the authentication fails, but not because of a timeout. + * - ASSOC_FAIL + - 203 + - reserved + - Espressif-specific Wi-Fi reason-code: the association fails, but not because of ASSOC_EXPIRE or ASSOC_TOOMANY. + * - HANDSHAKE_TIMEOUT + - 204 + - reserved + - Espressif-specific Wi-Fi reason-code: the handshake fails for the same reason as that in WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT. + * - CONNECTION_FAIL + - 205 + - reserved + - Espressif-specific Wi-Fi reason-code: the connection to the AP has failed. {IDF_TARGET_NAME} Wi-Fi Station Connecting When Multiple APs Are Found ---------------------------------------------------------------------- @@ -1055,101 +1030,54 @@ Wi-Fi Mode +++++++++++++++++++++++++ Call :cpp:func:`esp_wifi_set_mode()` to set the Wi-Fi mode. -+------------------+--------------------------------------------------------------+ -| Mode | Description | -+==================+==============================================================+ -| WIFI_MODE_NULL | NULL mode: in this mode, the internal data struct is not | -| | allocated to the station and the AP, while both the | -| | station and AP interfaces are not initialized for | -| | RX/TX Wi-Fi data. Generally, this mode is used for Sniffer, | -| | or when you only want to stop both the STA and the AP | -| | without calling :cpp:func:`esp_wifi_deinit()` to unload the | -| | whole Wi-Fi driver. | -+------------------+--------------------------------------------------------------+ -| WIFI_MODE_STA | Station mode: in this mode, :cpp:func:`esp_wifi_start()` will| -| | init the internal station data, while the station's interface| -| | is ready for the RX and TX Wi-Fi data. After | -| | :cpp:func:`esp_wifi_connect()` is called, the STA will | -| | connect to the target target AP. | -+------------------+--------------------------------------------------------------+ -| WIFI_MODE_AP | AP mode: in this mode, :cpp:func:`esp_wifi_start()` will init| -| | the internal AP data, while the AP's interface is ready | -| | for RX/TX Wi-Fi data. Then, the Wi-Fi driver starts broad- | -| | casting beacons, and the AP is ready to get connected | -| | to other stations. | -+------------------+--------------------------------------------------------------+ -| WIFI_MODE_APSTA | Station-AP coexistence mode: in this mode, | -| | :cpp:func:`esp_wifi_start()` will simultaneously init both | -| | the station and the AP.This is done in station mode and AP | -| | mode. Please note that the channel of the external AP, which | -| | the ESP Station is connected to, has higher priority over the| -| | ESP AP channel. | -+------------------+--------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 50 + + * - Mode + - Description + * - WIFI_MODE_NULL + - NULL mode: in this mode, the internal data struct is not allocated to the station and the AP, while both the station and AP interfaces are not initialized for RX/TX Wi-Fi data. Generally, this mode is used for Sniffer, or when you only want to stop both the station and the AP without calling :cpp:func:`esp_wifi_deinit()` to unload the whole Wi-Fi driver. + * - WIFI_MODE_STA + - Station mode: in this mode, :cpp:func:`esp_wifi_start()` will init the internal station data, while the station’s interface is ready for the RX and TX Wi-Fi data. After :cpp:func:`esp_wifi_connect()`, the station will connect to the target AP. + * - WIFI_MODE_AP + - AP mode: in this mode, :cpp:func:`esp_wifi_start()` will init the internal AP data, while the AP’s interface is ready for RX/TX Wi-Fi data. Then, the Wi-Fi driver starts broad-casting beacons, and the AP is ready to get connected to other stations. + * - WIFI_MODE_APSTA + - Station/AP coexistence mode: in this mode, :cpp:func:`esp_wifi_start()` will simultaneously init both the station and the AP. This is done in station mode and AP mode. Please note that the channel of the external AP, which the ESP station is connected to, has higher priority over the ESP AP channel. Station Basic Configuration +++++++++++++++++++++++++++++++++++++ API esp_wifi_set_config() can be used to configure the station. The table below describes the fields in detail. -+------------------+--------------------------------------------------------------+ -| Field | Description | -+==================+==============================================================+ -| ssid | This is the SSID of the target AP, to which the station wants| -| | to connect to. | -| | | -+------------------+--------------------------------------------------------------+ -| password | Password of the target AP. | -| | | -+------------------+--------------------------------------------------------------+ -| scan_method | For WIFI_FAST_SCAN scan, the scan ends when the first matched| -| | AP is found, for WIFI_ALL_CHANNEL_SCAN, the scan finds all | -| | matched APs on all channels. | -| | The default scan is WIFI_FAST_SCAN. | -+------------------+--------------------------------------------------------------+ -| bssid_set | If bssid_set is 0, the station connects to the AP whose SSID | -| | is the same as the field "ssid", while the field "bssid" | -| | is ignored. In all other cases, the station connects to | -| | the AP whose SSID is the same as the "ssid" field, while its | -| | BSSID is the same the "bssid" field . | -+------------------+--------------------------------------------------------------+ -| bssid | This is valid only when bssid_set is 1; see field | -| | "bssid_set". | -+------------------+--------------------------------------------------------------+ -| channel | If the channel is 0, the station scans the channel 1 ~ N to | -| | search for the target AP; otherwise, the station starts by | -| | scanning the channel whose value is the same as that of the | -| | "channel" field, and then scans others to find the target AP.| -| | If you do not know which channel the target AP is running on,| -| | set it to 0. | -+------------------+--------------------------------------------------------------+ -| sort_method | This field is only for WIFI_ALL_CHANNEL_SCAN | -| | | -| | If the sort_method is WIFI_CONNECT_AP_BY_SIGNAL, all matched | -| | APs are sorted by signal, for AP with best signal will be | -| | connected firstly. E.g. if the station want to connect AP | -| | whose ssid is "apxx", the scan finds two AP whose ssid equals| -| | to "apxx", the first AP's signal is -90 dBm, the second AP's | -| | signal is -30 dBm, the station connects the second AP | -| | firstly, it doesn't connect the first one unless it fails to | -| | connect the second one. | -| | | -| | If the sort_method is WIFI_CONNECT_AP_BY_SECURITY, all | -| | matched APs are sorted by security. E.g. if the station wants| -| | to connect AP whose ssid is "apxx", the scan finds two AP | -| | whose ssid is "apxx", the security of the first found AP is | -| | open while the second one is WPA2, the stations connects to | -| | the second AP firstly, it doesn't connect the second one | -| | unless it fails to connect the first one. | -+------------------+--------------------------------------------------------------+ -| threshold | The threshold is used to filter the found AP, if the RSSI or | -| | security mode is less than the configured threshold, the AP | -| | will be discard. | -| | | -| | If the RSSI set to 0, it means default threshold, the default| -| | RSSI threshold is -127 dBm. If the authmode threshold is set | -| | to 0, it means default threshold, the default authmode | -| | threshold is open. | -+------------------+--------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 50 + + * - Field + - Description + * - ssid + - This is the SSID of the target AP, to which the station wants to connect to. + * - password + - Password of the target AP. + * - scan_method + - For WIFI_FAST_SCAN scan, the scan ends when the first matched AP is found. For WIFI_ALL_CHANNEL_SCAN, the scan finds all matched APs on all channels. The default scan is WIFI_FAST_SCAN. + * - bssid_set + - If bssid_set is 0, the station connects to the AP whose SSID is the same as the field “ssid”, while the field “bssid” is ignored. In all other cases, the station connects to the AP whose SSID is the same as the “ssid” field, while its BSSID is the same the “bssid” field . + * - bssid + - This is valid only when bssid_set is 1; see field “bssid_set”. + * - channel + - If the channel is 0, the station scans the channel 1 ~ N to search for the target AP; otherwise, the station starts by scanning the channel whose value is the same as that of the “channel” field, and then scans others to find the target AP. If you do not know which channel the target AP is running on, set it to 0. + * - sort_method + - This field is only for WIFI_ALL_CHANNEL_SCAN. + + If the sort_method is WIFI_CONNECT_AP_BY_SIGNAL, all matched APs are sorted by signal, for AP with best signal will be connected firstly. E.g. if the station want to connect AP whose ssid is “apxx”, the scan finds two AP whose ssid equals to “apxx”, the first AP’s signal is -90 dBm, the second AP’s signal is -30 dBm, the station connects the second AP firstly, it doesn’t connect the first one unless it fails to connect the second one. + + If the sort_method is WIFI_CONNECT_AP_BY_SECURITY, all matched APs are sorted by security. E.g. if the station wants to connect AP whose ssid is “apxx”, the scan finds two AP whose ssid is “apxx”, the security of the first found AP is open while the second one is WPA2, the stations connects to the second AP firstly, it doesn’t connect the second one unless it fails to connect the first one. + * - threshold + - The threshold is used to filter the found AP, if the RSSI or security mode is less than the configured threshold, the AP will be discard. + + If the RSSI set to 0, it means default threshold, the default RSSI threshold is -127 dBm. If the authmode threshold is set to 0, it means default threshold, the default authmode threshold is open. .. attention:: WEP/WPA security modes are deprecated in IEEE 802.11-2016 specifications and are recommended not to be used. These modes can be rejected using authmode threshold by setting threshold as WPA2 by threshold.authmode as WIFI_AUTH_WPA2_PSK. @@ -1159,80 +1087,52 @@ AP Basic Configuration API esp_wifi_set_config() can be used to configure the AP. The table below describes the fields in detail. -+------------------+--------------------------------------------------------------+ -| Field | Description | -+==================+==============================================================+ -| ssid | SSID of AP; if the ssid[0] is 0xFF and ssid[1] is 0xFF, | -| | the AP defaults the SSID to ESP_aabbcc, where "aabbcc" | -| | is the last three bytes of the AP MAC. | -| | | -+------------------+--------------------------------------------------------------+ -| password | Password of AP; if the auth mode is WIFI_AUTH_OPEN, | -| | this field will be ignored. | -| | | -+------------------+--------------------------------------------------------------+ -| ssid_len | Length of SSID; if ssid_len is 0, check the SSID until there | -| | is a termination character. If ssid_len > 32, change it to | -| | 32; otherwise, set the SSID length according to ssid_len. | -| | | -+------------------+--------------------------------------------------------------+ -| channel | Channel of AP; if the channel is out of range, the Wi-Fi | -| | driver defaults the channel to channel 1. So, please make | -| | sure the channel is within the required range. | -| | For more details, refer to `Wi-Fi Country Code`_. | -+------------------+--------------------------------------------------------------+ -| authmode | Auth mode of ESP AP; currently, ESP Wi-Fi does not | -| | support AUTH_WEP. If the authmode is an invalid value, | -| | AP defaults the value to WIFI_AUTH_OPEN. | -| | | -+------------------+--------------------------------------------------------------+ -| ssid_hidden | If ssid_hidden is 1, AP does not broadcast the SSID; | -| | otherwise, it does broadcast the SSID. | -| | | -+------------------+--------------------------------------------------------------+ -| max_connection | Currently, ESP Wi-Fi supports up to 10 Wi-Fi connections. | -| | If max_connection > 10, AP defaults the value to 10. | -| | | -+------------------+--------------------------------------------------------------+ -| beacon_interval | Beacon interval; the value is 100 ~ 60000 ms, with default | -| | value being 100 ms. If the value is out of range, | -| | AP defaults it to 100 ms. | -+------------------+--------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 55 + + * - Field + - Description + * - ssid + - SSID of AP; if the ssid[0] is 0xFF and ssid[1] is 0xFF, the AP defaults the SSID to ESP_aabbcc, where “aabbcc” is the last three bytes of the AP MAC. + * - password + - Password of AP; if the auth mode is WIFI_AUTH_OPEN, this field will be ignored. + * - ssid_len + - Length of SSID; if ssid_len is 0, check the SSID until there is a termination character. If ssid_len > 32, change it to 32; otherwise, set the SSID length according to ssid_len. + * - channel + - Channel of AP; if the channel is out of range, the Wi-Fi driver defaults the channel to channel 1. So, please make sure the channel is within the required range. For more details, refer to `Wi-Fi Country Code`_. + * - authmode + - Auth mode of ESP AP; currently, ESP Wi-Fi does not support AUTH_WEP. If the authmode is an invalid value, AP defaults the value to WIFI_AUTH_OPEN. + * - ssid_hidden + - If ssid_hidden is 1, AP does not broadcast the SSID; otherwise, it does broadcast the SSID. + * - max_connection + - Currently, ESP Wi-Fi supports up to 10 Wi-Fi connections. If max_connection > 10, AP defaults the value to 10. + * - beacon_interval + - Beacon interval; the value is 100 ~ 60000 ms, with default value being 100 ms. If the value is out of range, AP defaults it to 100 ms. Wi-Fi Protocol Mode +++++++++++++++++++++++++ Currently, the IDF supports the following protocol modes: -+--------------------+------------------------------------------------------------+ -| Protocol Mode | Description | -+====================+============================================================+ -| 802.11 B | Call esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B) to set | -| | the station/AP to 802.11B-only mode. | -| | | -+--------------------+------------------------------------------------------------+ -| 802.11 BG | Call esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B|WIFI_ | -| | PROTOCOL_11G) to set the station/AP to 802.11BG mode. | -| | | -+--------------------+------------------------------------------------------------+ -| 802.11 BGN | Call esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B| | -| | WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N) to set the station/ | -| | AP to BGN mode. | -| | | -+--------------------+------------------------------------------------------------+ -| 802.11 BGNLR | Call esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B| | -| | WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N|WIFI_PROTOCOL_LR) | -| | to set the station/AP to BGN and the | -| | Espressif-specific mode. | -+--------------------+------------------------------------------------------------+ -| 802.11 LR | Call esp_wifi_set_protocol (ifx, WIFI_PROTOCOL_LR) to set | -| | the station/AP only to the Espressif-specific mode. | -| | | -| | **This mode is an Espressif-patented mode which can achieve| -| | a one-kilometer line of sight range. Please, make sure both| -| | the station and the AP are connected to an | -| | ESP device** | -+--------------------+------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 55 + + * - Protocol Mode + - Description + * - 802.11b + - Call esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B) to set the station/AP to 802.11b-only mode. + * - 802.11bg + - Call esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G) to set the station/AP to 802.11bg mode. + * - 802.11bgn + - Call esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B| WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N) to set the station/ AP to BGN mode. + * - 802.11 BGNLR + - Call esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B| WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N|WIFI_PROTOCOL_LR) to set the station/AP to BGN and the Espressif-specific mode. + * - 802.11 LR + - Call esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_LR) to set the station/AP only to the Espressif-specific mode. + + **This mode is an Espressif-patented mode which can achieve a one-kilometer line of sight range. Please, make sure both the station and the AP are connected to an ESP device.** Long Range (LR) +++++++++++++++++++++++++ @@ -1306,91 +1206,71 @@ The general conditions for using LR are: Wi-Fi Country Code +++++++++++++++++++++++++ -Call :cpp:func:`esp_wifi_set_country()` to set the country info. -The table below describes the fields in detail, please consult local 2.4 GHz RF operating regulations before configuring these fields. +Call :cpp:func:`esp_wifi_set_country()` to set the country info. The table below describes the fields in detail, please consult local 2.4 GHz RF operating regulations before configuring these fields. -+------------------+-----------------------------------------------------------------------------------+ -| Field | Description | -+==================+===================================================================================+ -| cc[3] | Country code string, this attributes identify the country or noncountry entity | -| | in which the station/AP is operating. If it's a country, the first two | -| | octets of this string is the two character country info as described in document | -| | ISO/IEC3166-1. The third octect is one of the following: | -| | | -| | - an ASCII space character, if the regulations under which the station/AP is | -| | operating encompass all environments for the current frequency band in the | -| | country. | -| | - an ASCII 'O' character if the regulations under which the station/AP is | -| | operating are for an outdoor environment only. | -| | - an ASCII 'I' character if the regulations under which the station/AP is | -| | operating are for an indoor environment only. | -| | - an ASCII 'X' character if the station/AP is operating under a noncountry | -| | entity. The first two octets of the noncountry entity is two ASCII 'XX' | -| | characters. | -| | - the binary representation of the Operating Class table number currently in use.| -| | Refer to Annex E, IEEE Std 802.11-2012. | -| | | -+------------------+-----------------------------------------------------------------------------------+ -| schan | Start channel, it's the minimum channel number of the regulations under which the | -| | station/AP can operate. | -| | | -+------------------+-----------------------------------------------------------------------------------+ -| nchan | Total number of channels as per the regulations, e.g. if the schan=1, nchan=13, | -| | it means the station/AP can send data from channel 1 to 13. | -| | | -+------------------+-----------------------------------------------------------------------------------+ -| policy | Country policy, this field control which country info will be used if the | -| | configured country info is conflict with the connected AP's. More description | -| | about policy is provided in following section. | -| | | -+------------------+-----------------------------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 55 + + * - Field + - Description + * - cc[3] + - Country code string, this attributes identify the country or noncountry entity in which the station/AP is operating. If it’s a country, the first two octets of this string is the two character country info as described in document ISO/IEC3166-1. The third octect is one of the following: + + - an ASCII space character, if the regulations under which the station/AP is operating encompass all environments for the current frequency band in the country. + - an ASCII ‘O’ character if the regulations under which the station/AP is operating are for an outdoor environment only. + - an ASCII ‘I’ character if the regulations under which the station/AP is operating are for an indoor environment only. + - an ASCII ‘X’ character if the station/AP is operating under a noncountry entity. The first two octets of the noncountry entity is two ASCII ‘XX’ characters. + - the binary representation of the Operating Class table number currently in use. Refer to Annex E, IEEE Std 802.11-2012. + + * - schan + - Start channel, it’s the minimum channel number of the regulations under which the station/AP can operate. + * - nchan + - Total number of channels as per the regulations, e.g. if the schan=1, nchan=13, it means the station/AP can send data from channel 1 to 13. + * - policy + - Country policy, this field control which country info will be used if the configured country info is conflict with the connected AP’s. More description about policy is provided in following section. The default country info is {.cc="CN", .schan=1, .nchan=13, policy=WIFI_COUNTRY_POLICY_AUTO}, if the Wi-Fi Mode is station/AP coexist mode, they share the same configured country info. Sometimes, the country info of AP, to which the station is connected, is different from the country info of configured. For example, the configured station has country info {.cc="JP", .schan=1, .nchan=14, policy=WIFI_COUNTRY_POLICY_AUTO}, but the connected AP has country info {.cc="CN", .schan=1, .nchan=13}, then country info of connected AP's is used. + Following table depicts which country info is used in different Wi-Fi Mode and different country policy, also describe the impact to active scan. -+-----------+----------------------------+----------------------------------------------------------------+ -| WiFi Mode | Policy | Description | -+===========+============================+================================================================+ -| Station | WIFI_COUNTRY_POLICY_AUTO | If the connected AP has country IE in its beacon, the country | -| | | info equals to the country info in beacon, otherwise, use | -| | | default country info. | -| | | | -| | | For scan: | -| | | | -| | | -If schan+nchan-1 >11 : | -| | | Use active scan from schan to 11 and use passive scan | -| | | from 12 to schan+nchan-1. | -| | | | -| | | -If schan+nchan-1 <= 11 : | -| | | Use active scan from schan to schan+nchan-1. | -| | | | -| | | Always keep in mind that if an AP with hidden SSID | -| | | is set to a passive scan channel, the passive scan will not | -| | | find it. In other words, if the application hopes to find the | -| | | AP with hidden SSID in every channel, the policy of | -| | | country info should be configured to | -| | | WIFI_COUNTRY_POLICY_MANUAL. | -| | | | -+-----------+----------------------------+----------------------------------------------------------------+ -| Station | WIFI_COUNTRY_POLICY_MANUAL | Always use the configured country info. | -| | | | -| | | For scan, scans channel "schan" to "schan+nchan-1" with active | -| | | scan. | -| | | | -+-----------+----------------------------+----------------------------------------------------------------+ -| AP | WIFI_COUNTRY_POLICY_AUTO | Always use the configured country info. | -| | | | -+-----------+----------------------------+----------------------------------------------------------------+ -| AP | WIFI_COUNTRY_POLICY_MANUAL | Always use the configured country info. | -| | | | -+-----------+----------------------------+----------------------------------------------------------------+ -|Station/AP-| WIFI_COUNTRY_POLICY_AUTO | If the station doesn't connects to any AP, the AP use the | -| | | configured country info. | -|coexistence| | If the station connects to an AP, the AP has the same | -| | | country info as the station. | -| | | | -| | | Same as station mode with policy WIFI_COUNTRY_POLICY_AUTO. | -+-----------+----------------------------+----------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 15 35 + + * - Wi-Fi Mode + - Policy + - Description + * - Station + - WIFI_COUNTRY_POLICY_AUTO + - If the connected AP has country IE in its beacon, the country info equals to the country info in beacon, otherwise, use default country info. + + For scan: + + - If schan+nchan-1 >11 : + + Use active scan from schan to 11 and use passive scan from 12 to schan+nchan-1. + + - If schan+nchan-1 <= 11 : + + Use active scan from schan to schan+nchan-1. + + Always keep in mind that if an AP with hidden SSID and station is set to a passive scan channel, the passive scan will not find it. In other words, if the application hopes to find the AP with hidden SSID in every channel, the policy of country info should be configured to WIFI_COUNTRY_POLICY_MANUAL. + + * - Station + - WIFI_COUNTRY_POLICY_MANUAL + - Always use the configured country info. For scan, scans channel “schan” to “schan+nchan-1” with active scan. + * - AP + - WIFI_COUNTRY_POLICY_AUTO + - Always use the configured country info. + * - AP + - WIFI_COUNTRY_POLICY_MANUAL + - Always use the configured country info. + * - Station/AP-coexistence + - WIFI_COUNTRY_POLICY_AUTO + - If the station doesn’t connects to any external AP, the AP use the configured country info. If the station connects to an external AP, the AP has the same country info as the station. + + Same as station mode with policy WIFI_COUNTRY_POLICY_AUTO. Home Channel ************************* @@ -1407,18 +1287,15 @@ By default, all Wi-Fi management frames are processed by the Wi-Fi driver, and t Wi-Fi Easy Connect™ (DPP) -------------------------- -Wi-Fi Easy Connect\ :sup:`TM` (or Device Provisioning Protocol) is a secure and standardized provisioning protocol for configuration of Wi-Fi Devices. -More information can be found on the API reference page :doc:`esp_dpp <../api-reference/network/esp_dpp>`. +Wi-Fi Easy Connect\ :sup:`TM` (or Device Provisioning Protocol) is a secure and standardized provisioning protocol for configuration of Wi-Fi Devices. More information can be found on the API reference page :doc:`esp_dpp <../api-reference/network/esp_dpp>`. WPA2-Enterprise +++++++++++++++++++++++++++++++++ WPA2-Enterprise is the secure authentication mechanism for enterprise wireless networks. It uses RADIUS server for authentication of network users before connecting to the Access Point. The authentication process is based on 802.1X policy and comes with different Extended Authentication Protocol (EAP) methods like TLS, TTLS, PEAP etc. RADIUS server authenticates the users based on their credentials (username and password), digital certificates or both. When {IDF_TARGET_NAME} in Station mode tries to connect to an AP in enterprise mode, it sends authentication request to AP which is sent to RADIUS server by AP for authenticating the Station. Based on different EAP methods, the parameters can be set in configuration which can be opened using ``idf.py menuconfig``. WPA2_Enterprise is supported by {IDF_TARGET_NAME} only in Station mode. - For establishing a secure connection, AP and Station negotiate and agree on the best possible cipher suite to be used. {IDF_TARGET_NAME} supports 802.1X/EAP (WPA) method of AKM and Advanced encryption standard with Counter Mode Cipher Block Chaining Message Authentication protocol (AES-CCM) cipher suite. It also supports the cipher suites supported by mbedtls if `USE_MBEDTLS_CRYPTO` flag is set. - {IDF_TARGET_NAME} currently supports the following EAP methods: - EAP-TLS: This is certificate based method and only requires SSID and EAP-IDF. - PEAP: This is Protected EAP method. Username and Password are mandatory. @@ -1426,10 +1303,28 @@ For establishing a secure connection, AP and Station negotiate and agree on the - PAP: Password Authentication Protocol. - CHAP: Challenge Handshake Authentication Protocol. - MSCHAP and MSCHAP-V2. - + - EAP-FAST: This is a Protected Access Credentials (PAC) based authentication method which also uses identity and password. Currently, USE_MBEDTLS_CRYPTO flag should be disabled to use this feature. Detailed information on creating certificates and how to run wpa2_enterprise example on {IDF_TARGET_NAME} can be found in :example:`wifi/wpa2_enterprise`. +Wireless Network Management +---------------------------- + +Wireless Network Management allows client devices to exchange information about the network topology, including information related to RF environment. This makes each client network-aware, facilitating overall improvement in the performace of the wireless network. It is part of 802.11v specification. It also enables client to support Network assisted Roaming. + +Network assisted Roaming: Enables WLAN to send messages to associated clients, resulting clients to associate with APs with better link metrics. This is useful for both load balancing and in directing poorly connected clients. + +Current implementation of 802.11v includes support for BSS transition management frames. + +Radio Resource Measurement +--------------------------- + +Radio Resource Measurement (802.11k) is intended to improve the way traffic is distributed within a network. In a wireless LAN, each device normally connects to the access point (AP) that provides the strongest signal. Depending on the number and geographic locations of the subscribers, this arrangement can sometimes lead to excessive demand on one AP and underutilization of others, resulting in degradation of overall network performance. In a network conforming to 802.11k, if the AP having the strongest signal is loaded to its full capacity, a wireless device can be moved to one of the underutilized APs. Even though the signal may be weaker, the overall throughput is greater because more efficient use is made of the network resources. + +Current implementation of 802.11k includes support for beacon measurement report, link measurement report and neighbor request. + +Refer IDF example :idf_file:`examples/wifi/roaming/README.md` to set up and use these APIs. Example code only demonstrates how these APIs can be used, the application should define its own algorithm and cases as required. + .. only:: esp32s2 or esp32c3 Wi-Fi Location @@ -1441,13 +1336,16 @@ Detailed information on creating certificates and how to run wpa2_enterprise exa +++++++++++++++++++++++++++++ FTM is used to measure Wi-Fi Round Trip Time (Wi-Fi RTT) which is the time a Wi-Fi signal takes to travel from a device to another device and back again. Using Wi-Fi RTT the distance between the devices can be calculated with a simple formula of `RTT * c / 2`, where c is the speed of light. + FTM uses timestamps given by Wi-Fi interface hardware at the time of arrival or departure of frames exchanged between a pair of devices. One entity called FTM Initiator (mostly a Station device) discovers the FTM Responder (can be a Station or an Access Point) and negotiates to start an FTM procedure. The procedure uses multiple Action frames sent in bursts and its ACK's to gather the timestamps data. FTM Initiator gathers the data in the end to calculate an average Round-Trip-Time. + {IDF_TARGET_NAME} supports FTM in below configuration: - {IDF_TARGET_NAME} as FTM Initiator in Station mode. - {IDF_TARGET_NAME} as FTM Responder in SoftAP mode. Distance measurement using RTT is not accurate, factors such as RF interference, multi-path travel, antenna orientation and lack of calibration increase these inaccuracies. For better results it is suggested to perform FTM between two {IDF_TARGET_NAME} devices as Station and SoftAP. + Refer to IDF example :idf_file:`examples/wifi/ftm/README.md` for steps on how to setup and perform FTM. {IDF_TARGET_NAME} Wi-Fi Power-saving Mode @@ -1482,64 +1380,133 @@ The table below shows the best throughput results we got in Espressif's lab and .. only:: esp32 - +----------------------+-----------------+-----------------+---------------+--------------+ - | Type/Throughput | Air In Lab | Shield-box | Test Tool | IDF Version | - | | | | | (commit ID) | - +======================+=================+=================+===============+==============+ - | Raw 802.11 Packet RX | N/A | **130 MBit/s** | Internal tool | NA | - +----------------------+-----------------+-----------------+---------------+--------------+ - | Raw 802.11 Packet TX | N/A | **130 MBit/s** | Internal tool | NA | - +----------------------+-----------------+-----------------+---------------+--------------+ - | UDP RX | 30 MBit/s | 85 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ - | UDP TX | 30 MBit/s | 75 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ - | TCP RX | 20 MBit/s | 65 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ - | TCP TX | 20 MBit/s | 75 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 10 25 + + * - Type/Throughput + - Air In Lab + - Shield-box + - Test Tool + - IDF Version (commit ID) + * - Raw 802.11 Packet RX + - N/A + - **130 MBit/s** + - Internal tool + - NA + * - Raw 802.11 Packet TX + - N/A + - **130 MBit/s** + - Internal tool + - NA + * - UDP RX + - 30 MBit/s + - 85 MBit/s + - iperf example + - 15575346 + * - UDP TX + - 30 MBit/s + - 75 MBit/s + - iperf example + - 15575346 + * - TCP RX + - 20 MBit/s + - 65 MBit/s + - iperf example + - 15575346 + * - TCP TX + - 20 MBit/s + - 75 MBit/s + - iperf example + - 15575346 When the throughput is tested by iperf example, the sdkconfig is :idf_file:`examples/wifi/iperf/sdkconfig.defaults.esp32`. .. only:: esp32s2 - +----------------------+-----------------+-----------------+---------------+--------------+ - | Type/Throughput | Air In Lab | Shield-box | Test Tool | IDF Version | - | | | | | (commit ID) | - +======================+=================+=================+===============+==============+ - | Raw 802.11 Packet RX | N/A | **130 MBit/s** | Internal tool | NA | - +----------------------+-----------------+-----------------+---------------+--------------+ - | Raw 802.11 Packet TX | N/A | **130 MBit/s** | Internal tool | NA | - +----------------------+-----------------+-----------------+---------------+--------------+ - | UDP RX | 30 MBit/s | 70 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ - | UDP TX | 30 MBit/s | 50 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ - | TCP RX | 20 MBit/s | 32 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ - | TCP TX | 20 MBit/s | 37 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 10 25 + + * - Type/Throughput + - Air In Lab + - Shield-box + - Test Tool + - IDF Version (commit ID) + * - Raw 802.11 Packet RX + - N/A + - **130 MBit/s** + - Internal tool + - NA + * - Raw 802.11 Packet TX + - N/A + - **130 MBit/s** + - Internal tool + - NA + * - UDP RX + - 30 MBit/s + - 70 MBit/s + - iperf example + - 15575346 + * - UDP TX + - 30 MBit/s + - 50 MBit/s + - iperf example + - 15575346 + * - TCP RX + - 20 MBit/s + - 32 MBit/s + - iperf example + - 15575346 + * - TCP TX + - 20 MBit/s + - 37 MBit/s + - iperf example + - 15575346 When the throughput is tested by iperf example, the sdkconfig is :idf_file:`examples/wifi/iperf/sdkconfig.defaults.esp32s2`. .. only:: esp32c3 - +----------------------+-----------------+-----------------+---------------+--------------+ - | Type/Throughput | Air In Lab | Shield-box | Test Tool | IDF Version | - | | | | | (commit ID) | - +======================+=================+=================+===============+==============+ - | Raw 802.11 Packet RX | N/A | **130 MBit/s** | Internal tool | NA | - +----------------------+-----------------+-----------------+---------------+--------------+ - | Raw 802.11 Packet TX | N/A | **130 MBit/s** | Internal tool | NA | - +----------------------+-----------------+-----------------+---------------+--------------+ - | UDP RX | 30 MBit/s | 50 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ - | UDP TX | 30 MBit/s | 40 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ - | TCP RX | 20 MBit/s | 35 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ - | TCP TX | 20 MBit/s | 37 MBit/s | iperf example | 15575346 | - +----------------------+-----------------+-----------------+---------------+--------------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 15 20 + + * - 类型/吞吐量 + - 实验室空气状况 + - 屏蔽箱 + - 测试工具 + - IDF 版本 (commit ID) + * - 原始 802.11 数据包接收数据 + - N/A + - **130 MBit/s** + - 内部工具 + - N/A + * - 原始 802.11 数据包发送数据 + - N/A + - **130 MBit/s** + - 内部工具 + - N/A + * - UDP 接收数据 + - 30 MBit/s + - 50 MBit/s + - iperf example + - 15575346 + * - UDP 发送数据 + - 30 MBit/s + - 40 MBit/s + - iperf example + - 15575346 + * - TCP 接收数据 + - 20 MBit/s + - 35 MBit/s + - iperf example + - 15575346 + * - TCP 发送数据 + - 20 MBit/s + - 37 MBit/s + - iperf example + - 15575346 When the throughput is tested by iperf example, the sdkconfig is :idf_file:`examples/wifi/iperf/sdkconfig.defaults.esp32c3`. @@ -1571,88 +1538,41 @@ Side-Effects to Avoid in Different Scenarios Theoretically, if we do not consider the side-effects the API imposes on the Wi-Fi driver or other stations/APs, we can send a raw 802.11 packet over the air, with any destination MAC, any source MAC, any BSSID, or any other type of packet. However,robust/useful applications should avoid such side-effects. The table below provides some tips/recommendations on how to avoid the side-effects of :cpp:func:`esp_wifi_80211_tx` in different scenarios. -+-----------------------------+---------------------------------------------------+ -| Scenario | Description | -+=============================+===================================================+ -| No WiFi connection | In this scenario, no Wi-Fi connection is set up, | -| | so there are no side-effects on the Wi-Fi driver. | -| | If en_sys_seq==true, the Wi-Fi driver is | -| | responsible for the sequence control. If | -| | en_sys_seq==false, the application needs to ensure| -| | that the buffer has the correct sequence. | -| | | -| | Theoretically, the MAC address can be any address.| -| | However, this may impact other stations/APs | -| | with the same MAC/BSSID. | -| | | -| | Side-effect example#1 | -| | The application calls esp_wifi_80211_tx to send | -| | a beacon with BSSID == mac_x in AP mode, but | -| | the mac_x is not the MAC of the AP interface. | -| | Moreover, there is another AP, say | -| | "other-AP", whose bssid is mac_x. If this | -| | happens, an "unexpected behavior" may occur, | -| | because the stations which connect to the | -| | "other-AP" cannot figure out whether the beacon is| -| | from the "other-AP" or the esp_wifi_80211_tx. | -| | | -| | To avoid the above-mentioned side-effects, we | -| | recommend that: | -| | | -| | - If esp_wifi_80211_tx is called in Station mode,| -| | the first MAC should be a multicast MAC or the | -| | exact target-device's MAC, while the second MAC| -| | should be that of the station interface. | -| | - If esp_wifi_80211_tx is called in AP mode, | -| | the first MAC should be a multicast MAC or the | -| | exact target-device's MAC, while the second MAC| -| | should be that of the AP interface. | -| | | -| | The recommendations above are only for avoiding | -| | side-effects and can be ignored when there are | -| | good reasons for doing this. | -+-----------------------------+---------------------------------------------------+ -| Have WiFi connection | When the Wi-Fi connection is already set up, and | -| | the sequence is controlled by the application, the| -| | latter may impact the sequence control of the | -| | Wi-Fi connection, as a whole. So, the | -| | en_sys_seq need to be true, otherwise | -| | ESP_ERR_WIFI_ARG is returned. | -| | | -| | The MAC-address recommendations in the | -| | "No WiFi connection" scenario also apply to this | -| | scenario. | -| | | -| | If the WiFi mode is station mode and the MAC | -| | address1 is the MAC of AP to which the station is | -| | connected, the MAC address2 is the MAC of station | -| | interface, we say the packets is from the station | -| | to AP. On the other hand, if the WiFi mode is | -| | AP mode and the MAC address1 is the MAC of | -| | the station who connects to this AP, the MAC | -| | address2 is the MAC of AP interface, we say | -| | the packet is from the AP to station. | -| | To avoid conflicting with WiFi connections, the | -| | following checks are applied: | -| | | -| | - If the packet type is data and is from the | -| | station to AP, the ToDS bit in IEEE 80211 | -| | frame control should be 1, the FromDS bit | -| | should be 0, otherwise the packet will be | -| | discarded by WiFi driver. | -| | - If the packet type is data and is from the | -| | AP to station, the ToDS bit in IEEE 80211 | -| | frame control should be 0, the FromDS bit | -| | should be 1, otherwise the packet will be | -| | discarded by WiFi driver. | -| | - If the packet is from station to AP or | -| | from AP to station, the Power Management, | -| | More Data, Re-Transmission bits should be 0, | -| | otherwise the packet will be discarded by WiFi | -| | driver. | -| | | -| | ESP_ERR_WIFI_ARG is returned if any check fails. | -+-----------------------------+---------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 10 50 + + * - Scenario + - Description + * - No Wi-Fi connection + - In this scenario, no Wi-Fi connection is set up, so there are no side-effects on the Wi-Fi driver. If en_sys_seq==true, the Wi-Fi driver is responsible for the sequence control. If en_sys_seq==false, the application needs to ensure that the buffer has the correct sequence. + + Theoretically, the MAC address can be any address. However, this may impact other stations/APs with the same MAC/BSSID. + + Side-effect example#1 The application calls esp_wifi_80211_tx to send a beacon with BSSID == mac_x in AP mode, but the mac_x is not the MAC of the AP interface. Moreover, there is another AP, say “other-AP”, whose bssid is mac_x. If this happens, an “unexpected behavior” may occur, because the stations which connect to the “other-AP” cannot figure out whether the beacon is from the “other-AP” or the esp_wifi_80211_tx. + + To avoid the above-mentioned side-effects, we recommend that: + + - If esp_wifi_80211_tx is called in station mode, the first MAC should be a multicast MAC or the exact target-device’s MAC, while the second MAC should be that of the station interface. + + - If esp_wifi_80211_tx is called in AP mode, the first MAC should be a multicast MAC or the exact target-device’s MAC, while the second MAC should be that of the AP interface. + + The recommendations above are only for avoiding side-effects and can be ignored when there are good reasons for doing this. + + * - Have Wi-Fi connection + - When the Wi-Fi connection is already set up, and the sequence is controlled by the application, the latter may impact the sequence control of the Wi-Fi connection, as a whole. So, the en_sys_seq need to be true, otherwise ESP_ERR_WIFI_ARG is returned. + + The MAC-address recommendations in the “No Wi-Fi connection” scenario also apply to this scenario. + + If the Wi-Fi mode is station mode and the MAC address1 is the MAC of AP to which the station is connected, the MAC address2 is the MAC of station interface, we say the packets is from the station to AP. On the other hand, if the Wi-Fi mode is AP mode and the MAC address1 is the MAC of the station who connects to this AP, the MAC address2 is the MAC of AP interface, we say the packet is from the AP to station. To avoid conflicting with Wi-Fi connections, the following checks are applied: + + - If the packet type is data and is from the station to AP, the ToDS bit in IEEE 80211 frame control should be 1, the FromDS bit should be 0, otherwise the packet will be discarded by Wi-Fi driver. + + - If the packet type is data and is from the AP to station, the ToDS bit in IEEE 80211 frame control should be 0, the FromDS bit should be 1, otherwise the packet will be discarded by Wi-Fi driver. + + - If the packet is from station to AP or from AP to station, the Power Management, More Data, Re-Transmission bits should be 0, otherwise the packet will be discarded by Wi-Fi driver. + + ESP_ERR_WIFI_ARG is returned if any check fails. Wi-Fi Sniffer Mode --------------------------- @@ -1986,115 +1906,304 @@ The parameters not mentioned in the following table should be set to the default .. only:: esp32 - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | Rank | Iperf | TX prior | High-performance | RX prior | Default | Memory saving | Minimum | - +============================+=======+==========+==================+==========+=========+===============+=========+ - | Available memory(KB) | 37.1 | 113.8 | 123.3 | 145.5 | 144.5 | 170.2 | 185.2 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | WIFI_STATIC_RX_BUFFER_NUM | 16 | 6 | 6 | 6 | 6 | 6 | 4 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | WIFI_DYNAMIC_RX_BUFFER_NUM | 64 | 16 | 24 | 34 | 20 | 12 | 8 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | WIFI_DYNAMIC_TX_BUFFER_NUM | 64 | 28 | 24 | 18 | 20 | 12 | 8 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | WIFI_RX_BA_WIN | 32 | 8 | 12 | 12 | 10 | 6 | Disable | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | TCP_SND_BUF_DEFAULT(KB) | 65 | 28 | 24 | 18 | 20 | 12 | 8 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | TCP_WND_DEFAULT(KB) | 65 | 16 | 24 | 34 | 20 | 12 | 8 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | WIFI_IRAM_OPT | 15 | 15 | 15 | 15 | 15 | 15 | 15 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | WIFI_RX_IRAM_OPT | 16 | 16 | 16 | 16 | 16 | 16 | 16 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | LWIP_IRAM_OPTIMIZATION | 13 | 13 | 13 | 13 | 13 | 13 | 13 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | TCP TX throughput (Mbit/s) | 74.6 | 50.8 | 46.5 | 39.9 | 44.2 | 33.8 | 25.6 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | TCP RX throughput (Mbit/s) | 63.6 | 35.5 | 42.3 | 48.5 | 40.5 | 30.1 | 27.8 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | UDP TX throughput (Mbit/s) | 76.2 | 75.1 | 74.1 | 72.4 | 69.6 | 64.1 | 36.5 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ - | UDP RX throughput (Mbit/s) | 83.1 | 66.3 | 75.1 | 75.6 | 73.1 | 65.3 | 54.7 | - +----------------------------+-------+----------+------------------+----------+---------+---------------+---------+ + .. list-table:: + :header-rows: 1 + :widths: 10 5 5 10 5 5 10 5 + + * - Rank + - Iperf + - TX prior + - High-performance + - RX prior + - Default + - Memory saving + - Minimum + * - Available memory (KB) + - 37.1 + - 113.8 + - 123.3 + - 145.5 + - 144.5 + - 170.2 + - 185.2 + * - WIFI_STATIC_RX_BUFFER_NUM + - 16 + - 6 + - 6 + - 6 + - 6 + - 6 + - 4 + * - WIFI_DYNAMIC_RX_BUFFER_NUM + - 64 + - 16 + - 24 + - 34 + - 20 + - 12 + - 8 + * - WIFI_DYNAMIC_TX_BUFFER_NUM + - 64 + - 28 + - 24 + - 18 + - 20 + - 12 + - 8 + * - WIFI_RX_BA_WIN + - 32 + - 8 + - 12 + - 12 + - 10 + - 6 + - Disable + * - TCP_SND_BUF_DEFAULT (KB) + - 65 + - 28 + - 24 + - 18 + - 20 + - 12 + - 8 + * - TCP_WND_DEFAULT (KB) + - 65 + - 16 + - 24 + - 34 + - 20 + - 12 + - 8 + * - WIFI_IRAM_OPT + - 15 + - 15 + - 15 + - 15 + - 15 + - 15 + - 15 + * - WIFI_RX_IRAM_OPT + - 16 + - 16 + - 16 + - 16 + - 16 + - 16 + - 16 + * - LWIP_IRAM_OPTIMIZATION + - 13 + - 13 + - 13 + - 13 + - 13 + - 13 + - 13 + * - TCP TX throughput (Mbit/s) + - 74.6 + - 50.8 + - 46.5 + - 39.9 + - 44.2 + - 33.8 + - 25.6 + * - TCP RX throughput (Mbit/s) + - 63.6 + - 35.5 + - 42.3 + - 48.5 + - 40.5 + - 30.1 + - 27.8 + * - UDP TX throughput (Mbit/s) + - 76.2 + - 75.1 + - 74.1 + - 72.4 + - 69.6 + - 64.1 + - 36.5 + * - UDP RX throughput (Mbit/s) + - 83.1 + - 66.3 + - 75.1 + - 75.6 + - 73.1 + - 65.3 + - 54.7 + .. only:: esp32s2 - +----------------------------+-------+------------------+---------+---------------+---------+ - | Rank | Iperf | High-performance | Default | Memory saving | Minimum | - +============================+=======+==================+=========+===============+=========+ - | Available memory (KB) | 4.1 | 24.2 | 78.4 | 86.5 | 116.4 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | WIFI_STATIC_RX_BUFFER_NUM | 8 |6 | 6 | 4 | 3 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | WIFI_DYNAMIC_RX_BUFFER_NUM | 24 | 18 | 12 | 8 | 6 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | WIFI_DYNAMIC_TX_BUFFER_NUM | 24 | 18 | 12 | 8 | 6 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | WIFI_RX_BA_WIN | 12 | 9 | 6 | 4 | 3 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | TCP_SND_BUF_DEFAULT (KB) | 24 | 18 | 12 | 8 | 6 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | TCP_WND_DEFAULT(KB) | 24 | 18 | 12 | 8 | 6 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | WIFI_IRAM_OPT | 15 | 15 | 15 | 15 | 0 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | WIFI_RX_IRAM_OPT | 16 | 16 | 16 | 0 | 0 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | LWIP_IRAM_OPTIMIZATION | 13 | 13 | 0 | 0 | 0 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | INSTRUCTION_CACHE | 16 | 16 | 16 | 16 | 8 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | INSTRUCTION_CACHE_LINE | 16 | 16 | 16 | 16 | 16 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | TCP TX throughput (Mbit/s) | 37.6 | 33.1 | 22.5 | 12.2 | 5.5 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | TCP RX throughput (Mbit/s) | 31.5 | 28.1 | 20.1 | 13.1 | 7.2 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | UDP TX throughput (Mbit/s) | 58.1 | 57.3 | 28.1 | 22.6 | 8.7 | - +----------------------------+-------+------------------+---------+---------------+---------+ - | UDP RX throughput (Mbit/s) | 78.1 | 66.7 | 65.3 | 53.8 | 28.5 | - +----------------------------+-------+------------------+---------+---------------+---------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 10 10 10 + + * - Rank + - Iperf + - High-performance + - Default + - Memory saving + - Minimum + * - Available memory (KB) + - 4.1 + - 24.2 + - 78.4 + - 86.5 + - 116.4 + * - WIFI_STATIC_RX_BUFFER_NUM + - 8 + - 6 + - 6 + - 4 + - 3 + * - WIFI_DYNAMIC_RX_BUFFER_NUM + - 24 + - 18 + - 12 + - 8 + - 6 + * - WIFI_DYNAMIC_TX_BUFFER_NUM + - 24 + - 18 + - 12 + - 8 + - 6 + * - WIFI_RX_BA_WIN + - 12 + - 9 + - 6 + - 4 + - 3 + * - TCP_SND_BUF_DEFAULT (KB) + - 24 + - 18 + - 12 + - 8 + - 6 + * - TCP_WND_DEFAULT (KB) + - 24 + - 18 + - 12 + - 8 + - 6 + * - WIFI_IRAM_OPT + - 15 + - 15 + - 15 + - 15 + - 0 + * - WIFI_RX_IRAM_OPT + - 16 + - 16 + - 16 + - 0 + - 0 + * - LWIP_IRAM_OPTIMIZATION + - 13 + - 13 + - 0 + - 0 + - 0 + * - INSTRUCTION_CACHE + - 16 + - 16 + - 16 + - 16 + - 8 + * - INSTRUCTION_CACHE_LINE + - 16 + - 16 + - 16 + - 16 + - 16 + * - TCP TX throughput (Mbit/s) + - 37.6 + - 33.1 + - 22.5 + - 12.2 + - 5.5 + * - TCP RX throughput (Mbit/s) + - 31.5 + - 28.1 + - 20.1 + - 13.1 + - 7.2 + * - UDP TX throughput (Mbit/s) + - 58.1 + - 57.3 + - 28.1 + - 22.6 + - 8.7 + * - UDP RX throughput (Mbit/s) + - 78.1 + - 66.7 + - 65.3 + - 53.8 + - 28.5 .. only:: esp32c3 - +----------------------------+-------+---------+---------+ - | Rank | Iperf | Default | Minimum | - +============================+=======+=========+=========+ - | Available memory(KB) | 59 | 160 | 180 | - +----------------------------+-------+---------+---------+ - | WIFI_STATIC_RX_BUFFER_NUM | 20 | 8 | 3 | - +----------------------------+-------+---------+---------+ - | WIFI_DYNAMIC_RX_BUFFER_NUM | 40 | 16 | 6 | - +----------------------------+-------+---------+---------+ - | WIFI_DYNAMIC_TX_BUFFER_NUM | 40 | 16 | 6 | - +----------------------------+-------+---------+---------+ - | WIFI_RX_BA_WIN | 32 | 16 | 6 | - +----------------------------+-------+---------+---------+ - | TCP_SND_BUF_DEFAULT(KB) | 40 | 16 | 6 | - +----------------------------+-------+---------+---------+ - | TCP_WND_DEFAULT(KB) | 40 | 16 | 6 | - +----------------------------+-------+---------+---------+ - | WIFI_IRAM_OPT | - | - | - | - +----------------------------+-------+---------+---------+ - | WIFI_RX_IRAM_OPT | - | - | - | - +----------------------------+-------+---------+---------+ - | LWIP_IRAM_OPTIMIZATION | 13 | 13 | 0 | - +----------------------------+-------+---------+---------+ - | TCP TX throughput (Mbit/s) | 38.1 | 27.2 | 20.4 | - +----------------------------+-------+---------+---------+ - | TCP RX throughput (Mbit/s) | 35.3 | 24.2 | 17.4 | - +----------------------------+-------+---------+---------+ - | UDP TX throughput (Mbit/s) | 40.6 | 38.9 | 34.1 | - +----------------------------+-------+---------+---------+ - | UDP RX throughput (Mbit/s) | 52.4 | 44.5 | 44.2 | - +----------------------------+-------+---------+---------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 15 + + * - Rank + - Iperf + - Default + - Minimum + * - Available memory (KB) + - 59 + - 160 + - 180 + * - WIFI_STATIC_RX_BUFFER_NUM + - 20 + - 8 + - 3 + * - WIFI_DYNAMIC_RX_BUFFER_NUM + - 40 + - 16 + - 6 + * - WIFI_DYNAMIC_TX_BUFFER_NUM + - 40 + - 16 + - 6 + * - WIFI_RX_BA_WIN + - 32 + - 16 + - 6 + * - TCP_SND_BUF_DEFAULT (KB) + - 40 + - 16 + - 6 + * - TCP_WND_DEFAULT (KB) + - 40 + - 16 + - 6 + * - LWIP_IRAM_OPTIMIZATION + - 13 + - 13 + - 0 + * - TCP TX throughput (Mbit/s) + - 38.1 + - 27.2 + - 20.4 + * - TCP RX throughput (Mbit/s) + - 35.3 + - 24.2 + - 17.4 + * - UDP TX throughput (Mbit/s) + - 40.6 + - 38.9 + - 34.1 + * - UDP RX throughput (Mbit/s) + - 52.4 + - 44.5 + - 44.2 .. only:: esp32 or esp32s2 .. note:: - The result is tested with a single stream in a shielded box using an ASUS RT-N66U router. - {IDF_TARGET_NAME}'s CPU is dual core with 240 MHz, {IDF_TARGET_NAME}'s flash is in QIO mode with 80 MHz. + The result is tested with a single stream in a shielded box using an ASUS RT-N66U router. {IDF_TARGET_NAME}'s CPU is dual core with 240 MHz, {IDF_TARGET_NAME}'s flash is in QIO mode with 80 MHz. .. only:: esp32 @@ -2157,79 +2266,187 @@ The parameters not mentioned in the following table should be set to the default .. only:: esp32 - +----------------------------+-------+---------+---------------+---------+ - | Rank | Iperf | Default | Memory saving | Minimum | - +============================+=======+=========+===============+=========+ - | Available memory(KB) | 113.8 | 152.4 | 181.2 | 202.6 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_STATIC_RX_BUFFER_NUM | 16 | 8 | 4 | 2 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_DYNAMIC_RX_BUFFER_NUM | 128 | 128 | 128 | 128 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_STATIC_TX_BUFFER_NUM | 16 | 8 | 4 | 2 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_RX_BA_WIN | 16 | 16 | 8 | Disable | - +----------------------------+-------+---------+---------------+---------+ - | TCP_SND_BUF_DEFAULT(KB) | 65 | 65 | 65 | 65 | - +----------------------------+-------+---------+---------------+---------+ - | TCP_WND_DEFAULT(KB) | 65 | 65 | 65 | 65 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_IRAM_OPT | 15 | 15 | 15 | 0 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_RX_IRAM_OPT | 16 | 16 | 0 | 0 | - +----------------------------+-------+---------+---------------+---------+ - | LWIP_IRAM_OPTIMIZATION | 13 | 0 | 0 | 0 | - +----------------------------+-------+---------+---------------+---------+ - | TCP TX throughput (Mbit/s) | 37.5 | 31.7 | 21.7 | 14.6 | - +----------------------------+-------+---------+---------------+---------+ - | TCP RX throughput (Mbit/s) | 31.5 | 29.8 | 26.5 | 21.1 | - +----------------------------+-------+---------+---------------+---------+ - | UDP TX throughput (Mbit/s) | 69.1 | 31.5 | 27.1 | 24.1 | - +----------------------------+-------+---------+---------------+---------+ - | UDP RX throughput (Mbit/s) | 40.1 | 38.5 | 37.5 | 36.9 | - +----------------------------+-------+---------+---------------+---------+ + .. list-table:: + :header-rows: 1 + :widths: 15 10 10 15 10 + + * - Rank + - Iperf + - Default + - Memory saving + - Minimum + * - Available memory (KB) + - 113.8 + - 152.4 + - 181.2 + - 202.6 + * - WIFI_STATIC_RX_BUFFER_NUM + - 16 + - 8 + - 4 + - 2 + * - WIFI_DYNAMIC_RX_BUFFER_NUM + - 128 + - 128 + - 128 + - 128 + * - WIFI_STATIC_TX_BUFFER_NUM + - 16 + - 8 + - 4 + - 2 + * - WIFI_RX_BA_WIN + - 16 + - 16 + - 8 + - Disable + * - TCP_SND_BUF_DEFAULT (KB) + - 65 + - 65 + - 65 + - 65 + * - TCP_WND_DEFAULT (KB) + - 65 + - 65 + - 65 + - 65 + * - WIFI_IRAM_OPT + - 15 + - 15 + - 15 + - 0 + * - WIFI_RX_IRAM_OPT + - 16 + - 16 + - 0 + - 0 + * - LWIP_IRAM_OPTIMIZATION + - 13 + - 0 + - 0 + - 0 + * - TCP TX throughput (Mbit/s) + - 37.5 + - 31.7 + - 21.7 + - 14.6 + * - TCP RX throughput (Mbit/s) + - 31.5 + - 29.8 + - 26.5 + - 21.1 + * - UDP TX throughput (Mbit/s) + - 69.1 + - 31.5 + - 27.1 + - 24.1 + * - UDP RX throughput (Mbit/s) + - 40.1 + - 38.5 + - 37.5 + - 36.9 .. only:: esp32s2 - +----------------------------+-------+---------+---------------+---------+ - | Rank | Iperf | Default | Memory saving | Minimum | - +============================+=======+=========+===============+=========+ - | Available memory(KB) | 70.6 | 96.4 | 118.8 | 148.2 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_STATIC_RX_BUFFER_NUM | 8 | 8 | 6 | 4 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_DYNAMIC_RX_BUFFER_NUM | 64 | 64 | 64 | 64 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_STATIC_TX_BUFFER_NUM | 16 | 8 | 6 | 4 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_RX_BA_WIN | 16 | 6 | 6 | Disable | - +----------------------------+-------+---------+---------------+---------+ - | TCP_SND_BUF_DEFAULT(KB) | 32 | 32 | 32 | 32 | - +----------------------------+-------+---------+---------------+---------+ - | TCP_WND_DEFAULT(KB) | 32 | 32 | 32 | 32 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_IRAM_OPT | 15 | 15 | 15 | 0 | - +----------------------------+-------+---------+---------------+---------+ - | WIFI_RX_IRAM_OPT | 16 | 16 | 0 | 0 | - +----------------------------+-------+---------+---------------+---------+ - | LWIP_IRAM_OPTIMIZATION | 13 | 0 | 0 | 0 | - +----------------------------+-------+---------+---------------+---------+ - | INSTRUCTION_CACHE | 16 | 16 | 16 | 8 | - +----------------------------+-------+---------+---------------+---------+ - | INSTRUCTION_CACHE_LINE | 16 | 16 | 16 | 16 | - +----------------------------+-------+---------+---------------+---------+ - | DATA_CACHE | 8 | 8 | 8 | 8 | - +----------------------------+-------+---------+---------------+---------+ - | DATA_CACHE_LINE | 32 | 32 | 32 | 32 | - +----------------------------+-------+---------+---------------+---------+ - | TCP TX throughput (Mbit/s) | 40.1 | 29.2 | 20.1 | 8.9 | - +----------------------------+-------+---------+---------------+---------+ - | TCP RX throughput (Mbit/s) | 21.9 | 16.8 | 14.8 | 9.6 | - +----------------------------+-------+---------+---------------+---------+ - | UDP TX throughput (Mbit/s) | 50.1 | 25.7 | 22.4 | 10.2 | - +----------------------------+-------+---------+---------------+---------+ - | UDP RX throughput (Mbit/s) | 45.3 | 43.1 | 28.5 | 15.1 | - +----------------------------+-------+---------+---------------+---------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 10 15 + + * - Rank + - Iperf + - Default + - Memory saving + - Minimum + * - Available memory (KB) + - 70.6 + - 96.4 + - 118.8 + - 148.2 + * - WIFI_STATIC_RX_BUFFER_NUM + - 8 + - 8 + - 6 + - 4 + * - WIFI_DYNAMIC_RX_BUFFER_NUM + - 64 + - 64 + - 64 + - 64 + * - WIFI_STATIC_TX_BUFFER_NUM + - 16 + - 8 + - 6 + - 4 + * - WIFI_RX_BA_WIN + - 16 + - 6 + - 6 + - Disable + * - TCP_SND_BUF_DEFAULT (KB) + - 32 + - 32 + - 32 + - 32 + * - TCP_WND_DEFAULT (KB) + - 32 + - 32 + - 32 + - 32 + * - WIFI_IRAM_OPT + - 15 + - 15 + - 15 + - 0 + * - WIFI_RX_IRAM_OPT + - 16 + - 16 + - 0 + - 0 + * - LWIP_IRAM_OPTIMIZATION + - 13 + - 0 + - 0 + - 0 + * - INSTRUCTION_CACHE + - 16 + - 16 + - 16 + - 8 + * - INSTRUCTION_CACHE_LINE + - 16 + - 16 + - 16 + - 16 + * - DATA_CACHE + - 8 + - 8 + - 8 + - 8 + * - DATA_CACHE_LINE + - 32 + - 32 + - 32 + - 32 + * - TCP TX throughput (Mbit/s) + - 40.1 + - 29.2 + - 20.1 + - 8.9 + * - TCP RX throughput (Mbit/s) + - 21.9 + - 16.8 + - 14.8 + - 9.6 + * - UDP TX throughput (Mbit/s) + - 50.1 + - 25.7 + - 22.4 + - 10.2 + * - UDP RX throughput (Mbit/s) + - 45.3 + - 43.1 + - 28.5 + - 15.1 .. note:: Reaching peak performance may cause task watchdog. It is a normal phenomenon considering the CPU may have no time for lower priority tasks. @@ -2318,80 +2535,58 @@ Description: The diagram shows the configuration of the Wi-Fi internal buffer. -+------------------+------------+------------+--------------+---------------------------------------+ -| Buffer Type | Alloc Type | Default | Configurable | Description | -+==================+============+============+==============+=======================================+ -| Static RX Buffer | Static | 10 * | Yes | This is a kind of DMA memory. It is | -| (Hardware RX | | 1600 Bytes | | initialized in | -| Buffer) | | | | :cpp:func:`esp_wifi_init()` and freed | -| | | | | in :cpp:func:`esp_wifi_deinit()`. The | -| | | | | 'Static Rx Buffer' forms the hardware | -| | | | | receiving list. Upon receiving a frame| -| | | | | over the air, hardware writes the | -| | | | | frame into the buffer and raises an | -| | | | | interrupt to the CPU. Then, the Wi-Fi | -| | | | | driver reads the content from the | -| | | | | buffer and returns the buffer back to | -| | | | | the list. | -| | | | | | -| | | | | If the application want to reduce the | -| | | | | the memory statically allocated by | -| | | | | Wi-Fi, they can reduce this value from| -| | | | | 10 to 6 to save 6400 Bytes memory. | -| | | | | It's not recommended to reduce the | -| | | | | configuration to a value less than 6 | -| | | | | unless the AMPDU feature is disabled. | -| | | | | | -+------------------+------------+------------+--------------+---------------------------------------+ -| Dynamic RX Buffer| Dynamic | 32 | Yes | The buffer length is variable and it | -| | | | | depends on the received frames' | -| | | | | length. When the Wi-Fi driver receives| -| | | | | a frame from the 'Hardware Rx Buffer',| -| | | | | the 'Dynamic Rx Buffer' needs to be | -| | | | | allocated from the heap. The number of| -| | | | | the Dynamic Rx Buffer, configured in | -| | | | | the menuconfig, is used to limit the | -| | | | | total un-freed Dynamic Rx Buffer | -| | | | | number. | -+------------------+------------+------------+--------------+---------------------------------------+ -| Dynamic TX Buffer| Dynamic | 32 | Yes | This is a kind of DMA memory. It is | -| | | | | allocated to the heap. When the upper-| -| | | | | layer (LwIP) sends packets to the | -| | | | | Wi-Fi driver, it firstly allocates a | -| | | | | 'Dynamic TX Buffer' and makes a copy | -| | | | | of the upper-layer buffer. | -| | | | | | -| | | | | The Dynamic and Static TX Buffers are | -| | | | | mutually exclusive. | -+------------------+------------+------------+--------------+---------------------------------------+ -| Static TX Buffer | Static | 16 * | Yes | This is a kind of DMA memory. It is | -| | | 1600Bytes | | initialized in | -| | | | | :cpp:func:`esp_wifi_init()` and freed | -| | | | | in :cpp:func:`esp_wifi_deinit()`. When| -| | | | | the upper-layer (LwIP) sends packets | -| | | | | to the Wi-Fi driver, it firstly | -| | | | | allocates a 'Static TX Buffer' and | -| | | | | makes a copy of the upper-layer | -| | | | | buffer. | -| | | | | | -| | | | | The Dynamic and Static TX Buffer are | -| | | | | mutually exclusive. | -| | | | | | -| | | | | Since the TX buffer must be DMA | -| | | | | buffer, so when PSRAM is enabled, the | -| | | | | TX buffer must be static. | -+------------------+------------+------------+--------------+---------------------------------------+ -| Management Short | Dynamic | 8 | NO | Wi-Fi driver's internal buffer. | -| Buffer | | | | | -+------------------+------------+------------+--------------+---------------------------------------+ -| Management Long | Dynamic | 32 | NO | Wi-Fi driver's internal buffer. | -| Buffer | | | | | -+------------------+------------+------------+--------------+---------------------------------------+ -| Management Long | Dynamic | 32 | NO | Wi-Fi driver's internal buffer. | -| Long Buffer | | | | | -+------------------+------------+------------+--------------+---------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 10 10 10 10 25 + * - Buffer Type + - Alloc Type + - Default + - Configurable + - Description + * - Static RX Buffer (Hardware RX Buffer) + - Static + - 10 * 1600 Bytes + - Yes + - This is a kind of DMA memory. It is initialized in :cpp:func:`esp_wifi_init()` and freed in :cpp:func:`esp_wifi_deinit()`. The ‘Static Rx Buffer’ forms the hardware receiving list. Upon receiving a frame over the air, hardware writes the frame into the buffer and raises an interrupt to the CPU. Then, the Wi-Fi driver reads the content from the buffer and returns the buffer back to the list. + If the application want to reduce the the memory statically allocated by Wi-Fi, they can reduce this value from 10 to 6 to save 6400 Bytes memory. It’s not recommended to reduce the configuration to a value less than 6 unless the AMPDU feature is disabled. + * - Dynamic RX Buffer + - Dynamic + - 32 + - Yes + - The buffer length is variable and it depends on the received frames’ length. When the Wi-Fi driver receives a frame from the ‘Hardware Rx Buffer’, the ‘Dynamic Rx Buffer’ needs to be allocated from the heap. The number of the Dynamic Rx Buffer, configured in the menuconfig, is used to limit the total un-freed Dynamic Rx Buffer number. + * - Dynamic TX Buffer + - Dynamic + - 32 + - Yes + - This is a kind of DMA memory. It is allocated to the heap. When the upper- layer (LwIP) sends packets to the Wi-Fi driver, it firstly allocates a ‘Dynamic TX Buffer’ and makes a copy of the upper-layer buffer. + + The Dynamic and Static TX Buffers are mutually exclusive. + * - Static TX Buffer + - Static + - 16 * 1600Bytes + - Yes + - This is a kind of DMA memory. It is initialized in :cpp:func:`esp_wifi_init()` and freed in :cpp:func:`esp_wifi_deinit()`. When the upper-layer (LwIP) sends packets to the Wi-Fi driver, it firstly allocates a ‘Static TX Buffer’ and makes a copy of the upper-layer buffer. + + The Dynamic and Static TX Buffer are mutually exclusive. + + Since the TX buffer must be DMA buffer, so when PSRAM is enabled, the TX buffer must be static. + * - Management Short Buffer + - Dynamic + - 8 + - NO + - Wi-Fi driver’s internal buffer. + * - Management Long Buffer + - Dynamic + - 32 + - NO + - Wi-Fi driver’s internal buffer. + * - Management Long Long Buffer + - Dynamic + - 32 + - NO + - Wi-Fi driver’s internal buffer. Wi-Fi NVS Flash +++++++++++++++++++++ @@ -2412,4 +2607,4 @@ Please refer to a separate document with :doc:`wireshark-user-guide`. .. toctree:: :hidden: - wireshark-user-guide + wireshark-user-guide \ No newline at end of file diff --git a/docs/en/api-reference/storage/nvs_flash.rst b/docs/en/api-reference/storage/nvs_flash.rst index 31ae316d8a..244064bf08 100644 --- a/docs/en/api-reference/storage/nvs_flash.rst +++ b/docs/en/api-reference/storage/nvs_flash.rst @@ -8,7 +8,6 @@ Introduction Non-volatile storage (NVS) library is designed to store key-value pairs in flash. This section introduces some concepts used by NVS. - Underlying storage ^^^^^^^^^^^^^^^^^^ @@ -378,5 +377,3 @@ API Reference .. include-build-file:: inc/nvs_flash.inc .. include-build-file:: inc/nvs.inc - - diff --git a/docs/zh_CN/api-guides/wifi.rst b/docs/zh_CN/api-guides/wifi.rst index fe4d238c4a..1509a13417 100644 --- a/docs/zh_CN/api-guides/wifi.rst +++ b/docs/zh_CN/api-guides/wifi.rst @@ -2,17 +2,17 @@ ================== :link_to_translation:`en:[English]` + {IDF_TARGET_NAME} Wi-Fi 功能列表 ------------------------------------ - 支持仅 station 模式、仅 AP 模式、station/AP 共存模式 - 支持使用 IEEE 802.11B、IEEE 802.11G、IEEE 802.11N 和 API 配置协议模式 -- 支持 WPA/WPA2/WPA2-企业版和 WPS +- 支持 WPA/WPA2/WPA3/WPA2-企业版和 WPS - 支持 AMPDU、HT40、QoS 以及其它主要功能 - 支持 Modem-sleep - 支持乐鑫专属协议,可实现 **1 km** 数据通信量 - 空中数据传输最高可达 20 MBit/s TCP 吞吐量和 30 MBit/s UDP 吞吐量 - 支持 Sniffer -- 支持用于 Wi-Fi 连接的 fast_crypto 算法与普通算法的切换 - 支持快速扫描和全信道扫描 - 支持多个天线 - 支持获取信道状态信息 @@ -299,7 +299,7 @@ WIFI_EVENT_AP_PROBEREQRECVED } -1.Wi-Fi/LwIP 初始化阶段 +1. Wi-Fi/LwIP 初始化阶段 ++++++++++++++++++++++++++++++ - s1.1:主任务通过调用函数 :cpp:func:`esp_netif_init()` 创建一个 LwIP 核心任务,并初始化 LwIP 相关工作。 @@ -313,7 +313,7 @@ WIFI_EVENT_AP_PROBEREQRECVED 推荐按照 s1.1 ~ s1.5 的步骤顺序针对基于 Wi-Fi/LwIP 的应用程序进行初始化。但这一顺序 **并非** 强制,您可以在第 s1.1 步创建应用程序任务,然后在该应用程序任务中进行所有其它初始化操作。不过,如果您的应用程序任务依赖套接字,那么在初始化阶段创建应用程序任务可能并不适用。此时,您可以在接收到 IP 后再进行任务创建。 -2.Wi-Fi 配置阶段 +2. Wi-Fi 配置阶段 +++++++++++++++++++++++++++++++ Wi-Fi 驱动程序初始化成功后,可以进入到配置阶段。该场景下,Wi-Fi 驱动程序处于 station 模式。因此,首先您需调用函数 :cpp:func:`esp_wifi_set_mode` (WIFI_MODE_STA) 将 Wi-Fi 模式配置为 station 模式。可通过调用其它 esp_wifi_set_xxx API 进行更多设置,例如:协议模式、国家代码、带宽等。请参阅 `{IDF_TARGET_NAME} Wi-Fi 配置`_。 @@ -321,13 +321,13 @@ Wi-Fi 驱动程序初始化成功后,可以进入到配置阶段。该场景 如果 menuconfig 已使能 Wi-Fi NVS flash,则不论当前阶段还是后续的 Wi-Fi 配置信息都将被存储至该 flash 中。那么,当主板上电/重新启动时,就不需从头开始配置 Wi-Fi 驱动程序。您只需调用函数 esp_wifi_get_xxx API 获取之前存储的配置信息。当然,如果不想使用之前的配置,您依然可以重新配置 Wi-Fi 驱动程序。 -3.Wi-Fi 启动阶段 +3. Wi-Fi 启动阶段 ++++++++++++++++++++++++++++++++ - s3.1:调用函数 :cpp:func:`esp_wifi_start()` 启动 Wi-Fi 驱动程序。 - s3.2:Wi-Fi 驱动程序将事件 `WIFI_EVENT_STA_START`_ 发布到事件任务中,然后,事件任务将执行一些正常操作并调用应用程序的事件回调函数。 - s3.3:应用程序的事件回调函数将事件 `WIFI_EVENT_STA_START`_ 中继到应用程序任务中。推荐您此时调用函数 :cpp:func:`esp_wifi_connect()` 进行 Wi-Fi 连接。当然,您也可以等待在 `WIFI_EVENT_STA_START`_ 事件发生后的其它阶段再调用此函数。 -4.Wi-Fi 连接阶段 +4. Wi-Fi 连接阶段 +++++++++++++++++++++++++++++++++ - s4.1:调用函数 :cpp:func:`esp_wifi_connect()` 后,Wi-Fi 驱动程序将启动内部扫描/连接过程。 @@ -337,26 +337,26 @@ Wi-Fi 驱动程序初始化成功后,可以进入到配置阶段。该场景 步骤 s4.2 中 Wi-Fi 连接可能会由于某些原因而失败,例如:密码错误、未找到 AP 等。这种情况下,将引发 `WIFI_EVENT_STA_DISCONNECTED`_ 事件并提示连接错误原因。有关如何处理中断 Wi-Fi 连接的事件,请参阅下文阶段 6 的描述。 -5.Wi-Fi 获取 IP 阶段 +5. Wi-Fi 获取 IP 阶段 +++++++++++++++++++++++++++++++++ - s5.1:一旦步骤 4.2 中的 DHCP 客户端初始化完成,Wi-Fi 驱动程序将进入 *获取 IP* 阶段。 - s5.2:如果 Wi-Fi 成功从 DHCP 服务器接收到 IP 地址,则将引发 `IP_EVENT_STA_GOT_IP`_ 事件,事件任务将执行正常处理。 - s5.3:应用程序的事件回调函数将事件 `IP_EVENT_STA_GOT_IP`_ 中继到应用程序任务中。对于那些基于 LwIP 构建的应用程序,此事件较为特殊,因为它意味着应用程序已准备就绪,可以开始任务,例如:创建 TCP/UDP 套接字等。此时较为容易犯的一个错误就是在接收到 `IP_EVENT_STA_GOT_IP`_ 事件之前就初始化套接字。**切忌在接收到 IP 之前启动任何套接字相关操作。** -6.Wi-Fi 断开阶段 +6. Wi-Fi 断开阶段 +++++++++++++++++++++++++++++++++ - s6.1:当 Wi-Fi 因为某些原因(例如:AP 掉电、RSSI 较弱等)连接中断时,将产生 `WIFI_EVENT_STA_DISCONNECTED`_ 事件。此事件也可能在上文阶段 3 中发生。在这里,事件任务将通知 LwIP 任务清除/移除所有 UDP/TCP 连接。然后,所有应用程序套接字都将处于错误状态。也就是说,`WIFI_EVENT_STA_DISCONNECTED`_ 事件发生时,任何套接字都无法正常工作。 - s6.2:上述情况下,应用程序的事件回调函数会将 `WIFI_EVENT_STA_DISCONNECTED`_ 事件中继到应用程序任务中。推荐您调用函数 :cpp:func:`esp_wifi_connect()` 重新连接 Wi-Fi,关闭所有套接字,并在必要时重新创建套接字。请参阅 `WIFI_EVENT_STA_DISCONNECTED`_。 -7.Wi-Fi IP 更改阶段 +7. Wi-Fi IP 更改阶段 ++++++++++++++++++++++++++++++++++ - s7.1:如果 IP 地址发生更改,将引发 `IP_EVENT_STA_GOT_IP`_ 事件,其中 "ip_change" 被置为 "true"。 - s7.2:**此事件对应用程序至关重要。这一事件发生时,适合关闭所有已创建的套接字并进行重新创建。** -8.Wi-Fi 清理阶段 +8. Wi-Fi 清理阶段 ++++++++++++++++++++++++++++ - s8.1:调用函数 :cpp:func:`esp_wifi_disconnect()` 断开 Wi-Fi 连接。 @@ -420,25 +420,24 @@ Wi-Fi 驱动程序初始化成功后,可以进入到配置阶段。该场景 扫描类型 +++++++++++++++++++++++++ -+--------------+---------------------------------------------------------------------------------------------------+ -| 模式 | 描述 | -+==============+===================================================================================================+ -| 主动扫描 | 通过发送 probe request 进行扫描。该模式为默认的扫描模式。 | -+--------------+---------------------------------------------------------------------------------------------------+ -| 被动扫描 | 跳至某一特定信道并等待 beacon。应用程序可通过wifi_scan_config_t 中的 scan_type 字段使能被动扫描。 | -+--------------+---------------------------------------------------------------------------------------------------+ -| 前端扫描 | 不发出 probe request。在 station 模式下 Wi-Fi 未连接时,可进行前端扫描。 | -| | Wi-Fi 驱动程序决定进行前端扫描还是后端扫描,应用程序无法配置这两种模式。 | -+--------------+---------------------------------------------------------------------------------------------------+ -| 后端扫描 | 在 station 模式或 station/AP 共存模式下 Wi-Fi 已连接时,可进行后端扫描。 | -| | Wi-Fi 驱动程序决定进行前端扫描还是后端扫描,应用程序无法配置这两种模式。 | -+--------------+---------------------------------------------------------------------------------------------------+ -| 全信道扫描 | 扫描所有信道。wifi_scan_config_t 中的 channel 字段为 0 时, | -| | 当前模式为全信道扫描。 | -+--------------+---------------------------------------------------------------------------------------------------+ -| 特定信道扫描 | 仅扫描特定的信道。wifi_scan_config_t 中的 channel 字段为 1 | -| | 时,当前模式为特定信道扫描。 | -+--------------+---------------------------------------------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 50 + + * - 模式 + - 描述 + * - 主动扫描 + - 通过发送 probe request 进行扫描。该模式为默认的扫描模式。 + * - 被动扫描 + - 不发送 probe request。跳至某一特定信道并等待 beacon。应用程序可通过 wifi_scan_config_t 中的 scan_type 字段使能被动扫描。 + * - 前端扫描 + - 在 station 模式下 Wi-Fi 未连接时,可进行前端扫描。Wi-Fi 驱动程序决定进行前端扫描还是后端扫描,应用程序无法配置这两种模式。 + * - 后端扫描 + - 在 station 模式或 station/AP 共存模式下 Wi-Fi 已连接时,可进行后端扫描。Wi-Fi 驱动程序决定进行前端扫描还是后端扫描,应用程序无法配置这两种模式。 + * - 全信道扫描 + - 扫描所有信道。wifi_scan_config_t 中的 channel 字段为 0 时,当前模式为全信道扫描。 + * - 特定信道扫描 + - 仅扫描特定的信道。wifi_scan_config_t 中的 channel 字段为 1-14 时,当前模式为特定信道扫描。 上表中的扫描模式可以任意组合,因此共有 8 种不同扫描方式: @@ -451,42 +450,40 @@ Wi-Fi 驱动程序初始化成功后,可以进入到配置阶段。该场景 - 特定信道前端主动扫描 - 特定信道前端被动扫描 - 扫描配置 +++++++++++++++++ 扫描类型与其他扫描属性通过函数 :cpp:func:`esp_wifi_scan_start` 进行配置。下表详细描述了函数 wifi_scan_config_t 各字段信息。 -+-------------+----------------------------------------------------------------------------------------------------------------------+ -| 字段 | 描述 | -+=============+======================================================================================================================+ -| ssid | 如果该字段的值不为 NULL,则仅可扫描到具有相同 SSID 值的 AP。 | -+-------------+----------------------------------------------------------------------------------------------------------------------+ -| bssid | 如果该字段的值不为 NULL,则仅可扫描到具有相同 BSSID 值的 AP。 | -+-------------+----------------------------------------------------------------------------------------------------------------------+ -| channel | 如果该字段值为 0,将进行全信道扫描;反之,将针对特定信道进行扫描。 | -+-------------+----------------------------------------------------------------------------------------------------------------------+ -| show_hidden | 如果该字段值为 0,本次扫描将忽略具有隐藏 SSID 的 AP; | -| | 反之,这些 AP 也会在扫描时被视为正常 AP。 | -+-------------+----------------------------------------------------------------------------------------------------------------------+ -| scan_type | 如果该字段值为为 WIFI_SCAN_TYPE_ACTIVE,则本次扫描为主动扫描; | -| | 反之,将被视为被动扫描。 | -+-------------+----------------------------------------------------------------------------------------------------------------------+ -| scan_time | 该字段用于控制每个信道的扫描时间。 | -| | | -| | 被动扫描时,scan_time.passive 字段负责为每个信道指定扫描时间。 | -| | | -| | 主动扫描时,每个信道的扫描时间如下列表所示。其中,min 代表 | -| | scan_time_active_min,max 代表 scan_time_active_max。 | -| | | -| | - min=0, max=0:每个信道的扫描时间为 120 ms。 | -| | - min>0, max=0:每个信道的扫描时间为 120 ms。 | -| | - min=0, max>0:每个信道的扫描时间为 ``max`` ms。 | -| | - min>0, max>0:每个信道扫描的最短时间为 ``min`` ms。 如果在这段时间内未找到 AP,将跳转至下一个信道。如这段时间内 | -| | 找到 AP,则该信道的扫描时间为 ``max`` ms。 | -| | | -| | 如希望提升 Wi-Fi 扫描性能,则可修改上述两个参数。 | -+-------------+----------------------------------------------------------------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 50 + + * - 字段 + - 描述 + * - ssid + - 如果该字段的值不为 NULL,则仅可扫描到具有相同 SSID 值的 AP。 + * - bssid + - 如果该字段的值不为 NULL,则仅可扫描到具有相同 BSSID 值的 AP。 + * - channel + - 如果该字段值为 0,将进行全信道扫描;反之,将针对特定信道进行扫描。 + * - show_hidden + - 如果该字段值为 0,本次扫描将忽略具有隐藏 SSID 的 AP;反之,这些 AP 也会在扫描时被视为正常 AP。 + * - scan_type + - 如果该字段值为为 WIFI_SCAN_TYPE_ACTIVE,则本次扫描为主动扫描;反之,将被视为被动扫描。 + * - scan_time + - 该字段用于控制每个信道的扫描时间。 + + 被动扫描时,scan_time.passive 字段负责为每个信道指定扫描时间。 + + 主动扫描时,每个信道的扫描时间如下列表所示。其中,min 代表 scan_time_active_min,max 代表 scan_time_active_max。 + + - min=0, max=0:每个信道的扫描时间为 120 ms。 + - min>0, max=0:每个信道的扫描时间为 120 ms。 + - min=0, max>0:每个信道的扫描时间为 ``max`` ms。 + - min>0, max>0:每个信道扫描的最短时间为 ``min`` ms。 如果在这段时间内未找到 AP,将跳转至下一个信道。如这段时间内找到 AP,则该信道的扫描时间为 ``max`` ms。 + + 如希望提升 Wi-Fi 扫描性能,则可修改上述两个参数。 调用 API :cpp:func:`esp_wifi_set_config` 可全局配置一些扫描属性,请参阅 `station 基本配置`_。 @@ -746,212 +743,258 @@ Wi-Fi 原因代码 下表罗列了 {IDF_TARGET_NAME} 中定义的原因代码。其中,第一列为 esp_wifi_types.h 中定义的宏名称。名称中省去了前缀 *WIFI_REASON*,也就是说,名称 *UNSPECIFIED* 实际应为 *WIFI_REASON_UNSPECIFIED*,以此类推。第二列为原因代码的相应数值。第三列为该原因映射到 IEEE 802.11-2012 中 8.4.1.7 段的标准值。(更多详细信息,请参阅前文描述。)最后一列为这一原因的描述。 +.. list-table:: + :header-rows: 1 + :widths: 5 10 12 40 -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| 原因代码 | 数值 | 映射值 | 描述 | -+==========================+======+==========+=========================================================================+ -| UNSPECIFIED | 1 | 1 | 出现内部错误,例如:存储器已满,内部发送失败,或该原因已 被远端接收等。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| AUTH_EXPIRE | 2 | 2 | 先前的 authentication 已失效。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时将报告该代码: | -| | | | | -| | | | - authentication 超时; | -| | | | - 从 AP 接收到该代码。 | -| | | | | -| | | | 对于 ESP AP,出现以下情况时将报告该代码: | -| | | | | -| | | | - 在过去五分钟之内,AP 未从 station 接收到任何数据包; | -| | | | - 由于调用了函数 :cpp:func:`esp_wifi_stop()` 导致 AP 终止; | -| | | | - 由于调用了函数 :cpp:func:`esp_wifi_deauth_sta()` 导致 station 的 auth | -| | | | 取消。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| AUTH_LEAVE | 3 | 3 | authentication 取消,因为发送 STA 正在离开(或已经离开)。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| ASSOC_EXPIRE | 4 | 4 | association 取消,因为 AP 不活跃。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -| | | | | -| | | | 对于 ESP AP,出现以下情况时报告该代码: | -| | | | | -| | | | - 在过去五分钟之内, AP 未从 station 接收到任何数据包; | -| | | | - 由于调用了函数 :cpp:func:`esp_wifi_stop()` 导致 AP 终止; | -| | | | - 由于调用了函数 :cpp:func:`esp_wifi_deauth_sta()` 导致 station 的 auth | -| | | | 取消。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| ASSOC_TOOMANY | 5 | 5 | association 取消,因为 AP 无法同时处理所有当前已关联的 STA。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -| | | | | -| | | | 对于 ESP AP,出现以下情况时报告该代码: | -| | | | | -| | | | - 与 AP 相关联的 station 数量已到达 AP 可支持的最大值。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| NOT_AUTHED | 6 | 6 | 从一个未认证 STA 接收到 class-2 frame。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -| | | | | -| | | | 对于 ESP AP,出现以下情况时报告该代码: | -| | | | | -| | | | - AP 从一个未认证 station 接收到数据包。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| NOT_ASSOCED | 7 | 7 | 从一个未关联 STA 接收到的 class-3 frame。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -| | | | | -| | | | 对于 ESP AP,出现以下情况时报告该代码: | -| | | | | -| | | | - AP 从未关联 station 接收到数据包。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| ASSOC_LEAVE | 8 | 8 | association 取消,因为发送 STA 正在离开(或已经离开)BSS。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码; | -| | | | - 由于调用 :cpp:func:`esp_wifi_disconnect()` 其它 API, | -| | | | station 断开连接。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| ASSOC_NOT_AUTHED | 9 | 9 | STA 的 re(association) 请求未被响应 STA 认证。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -| | | | | -| | | | 对于 ESP AP,出现以下情况时报告该代码: | -| | | | | -| | | | - AP 从一个已关联,但未认证的 station 接收到数据包。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| DISASSOC_PWRCAP_BAD | 10 | 10 | association 取消,因为无法接收功率能力 (Power Capability) | -| | | | 元素中的信息。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| DISASSOC_SUPCHAN_BAD | 11 | 11 | association 取消,因为无法接收支持的信道 (Supported Channels) | -| | | | 元素中的信息。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| IE_INVALID | 13 | 13 | 无效元素,即内容不符合 Wi-Fi 协议中帧格式 (Frame formats) | -| | | | 章节所描述标准的元素。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -| | | | | -| | | | 对于 ESP AP,出现以下情况时报告该代码: | -| | | | | -| | | | - AP 解析了一个错误的 WPA 或 RSN IE。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| MIC_FAILURE | 14 | 14 | 消息完整性代码 (MIC) 出错。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| 4WAY_HANDSHAKE_TIMEOUT | 15 | 15 | 四次握手超时。由于某些历史原因,在 ESP 中该原因代码实为 | -| | | | WIFI_REASON_HANDSHAKE_TIMEOUT。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 握手超时; | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| GROUP_KEY_UPDATE_TIMEOUT | 16 | 16 | 组密钥 (Group-Key) 握手超时。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| IE_IN_4WAY_DIFFERS | 17 | 17 | 四次握手中产生的元素与 (re-)association 后的 request/probe 以及 | -| | | | response/beacon frame 中的信息不同。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码; | -| | | | - station 发现四次握手的 IE 与 (re-)association 后的 request/probe | -| | | | 以及 response/beacon frame 中的 IE 不同。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| GROUP_CIPHER_INVALID | 18 | 18 | 无效组密文。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| PAIRWISE_CIPHER_INVALID | 19 | 19 | 无效成对密文。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| AKMP_INVALID | 20 | 20 | 无效 AKMP。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| UNSUPP_RSN_IE_VERSION | 21 | 21 | RSNE 版本不支持。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| INVALID_RSN_IE_CAP | 22 | 22 | 无效的 RSNE 性能。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| 802_1X_AUTH_FAILED | 23 | 23 | IEEE 802.1X. authentication 失败。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -| | | | | -| | | | 对于 ESP AP,出现以下情况时报告该代码: | -| | | | | -| | | | - IEEE 802.1X. authentication 失败。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| CIPHER_SUITE_REJECTED | 24 | 24 | 因安全策略,安全密钥算法套件 (cipher suite) 被拒。 | -| | | | | -| | | | 对于 ESP station,出现以下情况时报告该代码: | -| | | | | -| | | | - 从 AP 接收到该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| BEACON_TIMEOUT | 200 | reserved | 乐鑫特有的 Wi-Fi 原因代码: 当 station 连续失去 N 个 beacon, | -| | | | 将中断连接并报告该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| NO_AP_FOUND | 201 | reserved | 乐鑫特有的 Wi-Fi 原因代码: 当 station 未扫描到目标 AP 时, | -| | | | 将报告该代码。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| AUTH_FAIL | 202 | reserved | 乐鑫特有的 Wi-Fi 原因代码: authentication 失败, | -| | | | 但并非由超时而引发。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| ASSOC_FAIL | 203 | reserved | 乐鑫特有的 Wi-Fi 原因代码: association 失败,但并非由 | -| | | | ASSOC_EXPIRE 或 ASSOC_TOOMANY 引发。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| HANDSHAKE_TIMEOUT | 204 | reserved | 乐鑫特有的 Wi-Fi 原因代码: 握手失败,与 | -| | | | WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT 中失败原因相同。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ -| CONNECTION_FAIL | 205 | reserved | 乐鑫特有的 Wi-Fi 原因代码: AP 连接失败。 | -+--------------------------+------+----------+-------------------------------------------------------------------------+ + * - 原因代码 + - 数值 + - 映射值 + - 描述 + * - UNSPECIFIED + - 1 + - 1 + - 出现内部错误,例如:内存已满,内部发送失败,或该原因已被远端接收等。 + * - AUTH_EXPIRE + - 2 + - 2 + - 先前的 authentication 已失效。 + 对于 ESP station,出现以下情况时将报告该代码: + - authentication 超时; + - 从 AP 接收到该代码。 + + 对于 ESP AP,出现以下情况时将报告该代码: + + - 在过去五分钟之内,AP 未从 station 接收到任何数据包; + - 由于调用了函数 :cpp:func:`esp_wifi_stop()` 导致 AP 终止; + - 由于调用了函数 :cpp:func:`esp_wifi_deauth_sta()` 导致 station 的 authentication 取消。 + * - AUTH_LEAVE + - 3 + - 3 + - authentication 取消,因为发送 station 正在离开(或已经离开)。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - ASSOC_EXPIRE + - 4 + - 4 + - 因为 AP 不活跃,association 取消。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + + 对于 ESP AP,出现以下情况时将报告该代码: + + - 在过去五分钟之内, AP 未从 station 接收到任何数据包; + - 由于调用了函数 :cpp:func:`esp_wifi_stop()` 导致 AP 终止; + - 由于调用了函数 :cpp:func:`esp_wifi_deauth_sta()` 导致 station 的 authentication 取消。 + * - ASSOC_TOOMANY + - 5 + - 5 + - association 取消,因为 AP 无法同时处理所有当前已关联的 STA。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + + 对于 ESP AP,出现以下情况时将报告该代码: + + - 与 AP 相关联的 station 数量已到达 AP 可支持的最大值。 + * - NOT_AUTHED + - 6 + - 6 + - 从一个未认证 station 接收到 class-2 frame。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + + 对于 ESP AP,出现以下情况时将报告该代码: + + - AP 从一个未认证 station 接收到数据包。 + * - NOT_ASSOCED + - 7 + - 7 + - 从一个未关联 station 接收到的 class-3 frame。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + + 对于 ESP AP,出现以下情况时将报告该代码: + + - AP 从未关联 station 接收到数据包。 + * - ASSOC_LEAVE + - 8 + - 8 + - association 取消,因为发送 station 正在离开(或已经离开)BSS。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + - 由于调用 :cpp:func:`esp_wifi_disconnect()` 和其它 API,station 断开连接。 + * - ASSOC_NOT_AUTHED + - 9 + - 9 + - station 的 re(association) 请求未被响应 station 认证。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + + 对于 ESP AP,出现以下情况时将报告该代码: + + - AP 从一个已关联,但未认证的 station 接收到数据包。 + * - DISASSOC_PWRCAP_BAD + - 10 + - 10 + - association 取消,因为无法接收功率能力 (Power Capability) 元素中的信息。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - DISASSOC_SUPCHAN_BAD + - 11 + - 11 + - association 取消,因为无法接收支持的信道 (Supported Channels) 元素中的信息。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - IE_INVALID + - 13 + - 13 + - 无效元素,即内容不符合 Wi-Fi 协议中帧格式 (Frame formats) 章节所描述标准的元素。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + + 对于 ESP AP,出现以下情况时将报告该代码: + + - AP 解析了一个错误的 WPA 或 RSN IE。 + * - MIC_FAILURE + - 14 + - 14 + - 消息完整性代码 (MIC) 出错。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - 4WAY_HANDSHAKE_TIMEOUT + - 15 + - 15 + - 四次握手超时。由于某些历史原因,在 ESP 中该原因代码实为 WIFI_REASON_HANDSHAKE_TIMEOUT。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 握手超时。 + - 从 AP 接收到该代码。 + * - GROUP_KEY_UPDATE_TIMEOUT + - 16 + - 16 + - 组密钥 (Group-Key) 握手超时。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - IE_IN_4WAY_DIFFERS + - 17 + - 17 + - 四次握手中产生的元素与 (re-)association 后的 request/probe 以及 response/beacon frame 中的信息不同。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + - station 发现四次握手的 IE 与 (re-)association 后的 request/probe 以及 response/beacon frame 中的 IE 不同。 + * - GROUP_CIPHER_INVALID + - 18 + - 18 + - 无效组密文。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - PAIRWISE_CIPHER_INVALID + - 19 + - 19 + - 无效成对密文。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - AKMP_INVALID + - 20 + - 20 + - 无效 AKMP。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - UNSUPP_RSN_IE_VERSION + - 21 + - 21 + - 不支持的 RSNE 版本。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - INVALID_RSN_IE_CAP + - 22 + - 22 + - 无效的 RSNE 性能。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - 802_1X_AUTH_FAILED + - 23 + - 23 + - IEEE 802.1X. authentication 失败。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + + 对于 ESP AP,出现以下情况时将报告该代码: + + - IEEE 802.1X. authentication 失败。 + * - CIPHER_SUITE_REJECTED + - 24 + - 24 + - 因安全策略,安全密钥算法套件 (cipher suite) 被拒。 + + 对于 ESP station,出现以下情况时报告该代码: + + - 从 AP 接收到该代码。 + * - BEACON_TIMEOUT + - 200 + - 保留 + - 乐鑫特有的 Wi-Fi 原因代码: 当 station 连续失去 N 个 beacon,将中断连接并报告该代码。 + * - NO_AP_FOUND + - 201 + - 保留 + - 乐鑫特有的 Wi-Fi 原因代码: 当 station 未扫描到目标 AP 时,将报告该代码。 + * - AUTH_FAIL + - 202 + - 保留 + - 乐鑫特有的 Wi-Fi 原因代码: authentication 失败,但并非由超时而引发。 + * - ASSOC_FAIL + - 203 + - 保留 + - 乐鑫特有的 Wi-Fi 原因代码: association 失败,但并非由 ASSOC_EXPIRE 或 ASSOC_TOOMANY 引发。 + * - HANDSHAKE_TIMEOUT + - 204 + - 保留 + - 乐鑫特有的 Wi-Fi 原因代码: 握手失败,与 WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT 中失败原因相同。 + * - CONNECTION_FAIL + - 205 + - 保留 + - 乐鑫特有的 Wi-Fi 原因代码: AP 连接失败。 找到多个 AP 时的 {IDF_TARGET_NAME} Wi-Fi station 连接 ---------------------------------------------------------------------- @@ -978,7 +1021,6 @@ Wi-Fi beacon 超时 beacon 超时发生后,station 将向 AP 发送 5 个 probe request,如果仍未从 AP 接收到 probe response 或 beacon,station 将与 AP 断开连接并产生 `WIFI_EVENT_STA_DISCONNECTED`_ 事件。 - {IDF_TARGET_NAME} Wi-Fi 配置 ------------------------------------- @@ -988,72 +1030,56 @@ Wi-Fi 模式 +++++++++++++++++++++++++ 调用函数 :cpp:func:`esp_wifi_set_mode()` 设置 Wi-Fi 模式。 -+-----------------+------------------------------------------------------------------------------+ -| 模式 | 描述 | -+-----------------+------------------------------------------------------------------------------+ -| WIFI_MODE_NULL | NULL 模式:此模式下,内部数据结构不分配给 station 和 AP,同时,station 和 AP | -| | 接口不会为发送/接收 Wi-Fi 数据进行初始化。通常,此模式用于 | -| | Sniffer,或者您不想通过调用函数 :cpp:func:`esp_wifi_deinit()` 卸载整个 | -| | Wi-Fi 驱动程序来同时停止 station 和 AP。 | -+-----------------+------------------------------------------------------------------------------+ -| WIFI_MODE_STA | Station 模式:此模式下,:cpp:func:`esp_wifi_start()` 将初始化内部 | -| | station 数据,同时 station 接口准备发送/接收 Wi-Fi 数据。调用函数 | -| | :cpp:func:`esp_wifi_connect()` 后,station 将连接到目标 AP。 | -+-----------------+------------------------------------------------------------------------------+ -| WIFI_MODE_AP | AP 模式:在此模式下,:cpp:func:`esp_wifi_start()` 将初始化内部 AP | -| | 数据,同时 AP 接口准备发送/接收 Wi-Fi 数据。随后,Wi-Fi | -| | 驱动程序开始广播 beacon,AP 即可与其它 station 连接。 | -+-----------------+------------------------------------------------------------------------------+ -| WIFI_MODE_APSTA | Station/AP 共存模式:在此模式下,函数 :cpp:func:`esp_wifi_start()` | -| | 将同时初始化 station 和 AP。该步骤在 Station 模式和 AP | -| | 模式下完成。请注意 ESP Station 所连外部 AP 的信道优先于 ESP AP 信道。 | -+-----------------+------------------------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 50 + + * - 模式 + - 描述 + * - WIFI_MODE_NULL + - NULL 模式:此模式下,内部数据结构不分配给 station 和 AP,同时,station 和 AP 接口不会为发送/接收 Wi-Fi 数据进行初始化。通常,此模式用于 Sniffer,或者您不想通过调用函数 :cpp:func:`esp_wifi_deinit()` 卸载整个 Wi-Fi 驱动程序来同时停止 station 和 AP。 + * - WIFI_MODE_STA + - station 模式:此模式下,:cpp:func:`esp_wifi_start()` 将初始化内部 station 数据,同时 station 接口准备发送/接收 Wi-Fi 数据。调用函数 :cpp:func:`esp_wifi_connect()` 后,station 将连接到目标 AP。 + * - WIFI_MODE_AP + - AP 模式:在此模式下,:cpp:func:`esp_wifi_start()` 将初始化内部 AP 数据,同时 AP 接口准备发送/接收 Wi-Fi 数据。随后,Wi-Fi 驱动程序开始广播 beacon,AP 即可与其它 station 连接。 + * - WIFI_MODE_APSTA + - station/AP 共存模式:在此模式下,函数 :cpp:func:`esp_wifi_start()` 将同时初始化 station 和 AP。该步骤在 station 模式和 AP 模式下完成。请注意 ESP station 所连外部 AP 的信道优先于 ESP AP 信道。 Station 基本配置 +++++++++++++++++++++++++++++++++++++ API esp_wifi_set_config() 可用于配置 station。下表详细介绍了各个字段。 +.. list-table:: + :header-rows: 1 + :widths: 15 45 -+-------------+---------------------------------------------------------------------------+ -| 字段 | 描述 | -+=============+===========================================================================+ -| ssid | station 想要连接的目标 AP 的 SSID。 | -+-------------+---------------------------------------------------------------------------+ -| password | 目标 AP 的密码。 | -+-------------+---------------------------------------------------------------------------+ -| scan_method | WIFI_FAST_SCAN 模式下,扫描到一个匹配的 AP 时即结束。WIFI_ALL_CHANNEL_SCA | -| | 模式下,在所有信道扫描所有匹配的 AP。默认扫描模式是 WIFI_FAST_SCAN。 | -+-------------+---------------------------------------------------------------------------+ -| bssid_set | 如果 bssid_set 为 0,station 连接 SSID 与 "ssid" 字段相同的 | -| | AP,同时忽略字段 "bssid"。其他情况下,station 连接 SSID | -| | 与 "ssid" 字段相同、BSSID 与 "bssid" 字段也相同的 AP。 | -+-------------+---------------------------------------------------------------------------+ -| bssid | 只有当 bssid_set 为 1 时有效。见字段 "bssid_set"。 | -+-------------+---------------------------------------------------------------------------+ -| channel | 该字段为 0 时,station 扫描信道 1~N 寻找目标 AP;否则,station | -| | 首先扫描值与 "channel" 字段相同的信道,再扫描其他信道。如果您不知道目标 | -| | AP 在哪个信道,请将该字段设置为 0。 | -+-------------+---------------------------------------------------------------------------+ -| sort_method | 该字段仅用于 WIFI_ALL_CHANNEL_SCAN 模式。如果设置为 | -| | WIFI_CONNECT_AP_BY_SIGNAL,所有匹配的 AP | -| | 将会按照信号强度排序,信号最好的 AP 会被首先连接。比如,如果 | -| | station 想要连接 ssid 为 "apxx" 的 AP,且扫描到两个这样的 | -| | AP。第一个 AP 的信号为 -90 dBm,第二个 AP 的信号为 -30 dBm,station | -| | 首先连接第二个 AP。除非失败,才会连接第一个。如果设置为 | -| | WIFI_CONNECT_AP_BY_SECURITY,所有匹配的 AP 将会按照安全性排序。比如,如果 | -| | station 想要连接 ssid 为 "apxx"的 AP,并且扫描到两个这样的 AP。第一个 | -| | AP 为开放式,第二个 AP 为 WPA2 加密,station 首先连接第二个 | -| | AP。除非失败,才会连接第一个。 | -+-------------+---------------------------------------------------------------------------+ -| threshold | 该字段用来筛选找到的 AP,如果 AP 的 RSSI | -| | 或安全模式小于配置的阈值,则不会被连接。如果 RSSI | -| | 设置为 0,则取 RSSI 的默认阈值 -127 dBm。如果 | -| | authmode 设置为 0,则取 authmode 默认阈值无授权。 | -+-------------+---------------------------------------------------------------------------+ + * - 字段 + - 描述 + * - ssid + - station 想要连接的目标 AP 的 SSID。 + * - password + - 目标 AP 的密码。 + * - scan_method + - WIFI_FAST_SCAN 模式下,扫描到一个匹配的 AP 时即结束。WIFI_ALL_CHANNEL_SCAN 模式下,在所有信道扫描所有匹配的 AP。默认扫描模式是 WIFI_FAST_SCAN。 + * - bssid_set + - 如果 bssid_set 为 0,station 连接 SSID 与 “ssid” 字段相同的 AP,同时忽略字段 “bssid”。其他情况下,station 连接 SSID 与 “ssid” 字段相同、BSSID 与 “bssid” 字段也相同的 AP。 + * - bssid + - 只有当 bssid_set 为 1 时有效。见字段 “bssid_set”。 + * - channel + - 该字段为 0 时,station 扫描信道 1 ~ N 寻找目标 AP;否则,station 首先扫描值与 “channel” 字段相同的信道,再扫描其他信道。如果您不知道目标 AP 在哪个信道,请将该字段设置为 0。 + * - sort_method + - 该字段仅用于 WIFI_ALL_CHANNEL_SCAN 模式。 + + 如果设置为 WIFI_CONNECT_AP_BY_SIGNAL,所有匹配的 AP 将会按照信号强度排序,信号最好的 AP 会被首先连接。比如,如果 station 想要连接 ssid 为 “apxx” 的 AP,且扫描到两个这样的 AP。第一个 AP 的信号为 -90 dBm,第二个 AP 的信号为 -30 dBm,station 首先连接第二个 AP。除非失败,才会连接第一个。 + + 如果设置为 WIFI_CONNECT_AP_BY_SECURITY,所有匹配的 AP 将会按照安全性排序。比如,如果 station 想要连接 ssid 为 “apxx” 的 AP,并且扫描到两个这样的 AP。第一个 AP 为开放式,第二个 AP 为 WPA2 加密,station 首先连接第二个 AP。除非失败,才会连接第一个。 + * - threshold + - 该字段用来筛选找到的 AP,如果 AP 的 RSSI 或安全模式小于配置的阈值,则不会被连接。 + + 如果 RSSI 设置为 0,则表示默认阈值、默认 RSSI 阈值为 -127 dBm。如果 authmode 阈值设置为 0,则表示默认阈值,默认 authmode 阈值无授权。 .. attention:: - WEP/WPA 安全模式在 IEEE802.11-2016 协议中已弃用,建议不要使用。可使用 authmode 阈值代替,通过将 threshold.authmode 设置为 WIFI_AUTH_WPA2_PSK 使用 WPA2 模式 AP 基本配置 @@ -1061,60 +1087,52 @@ AP 基本配置 API esp_wifi_set_config() 可用于配置 AP。下表详细介绍了各个字段。 -+-----------------+----------------------------------------------------------------------------------+ -| 字段 | 描述 | -+-----------------+----------------------------------------------------------------------------------+ -| ssid | 指 AP的 SSID。如果 ssid[0] 和 ssid[1] 均为 0xFF,AP | -| | 默认 SSID 为 ESP_aabbcc,"aabbcc" 是 AP MAC 的最后三个字节。 | -+-----------------+----------------------------------------------------------------------------------+ -| password | AP 的密码。如果身份验证模式为 WIFI_AUTH_OPEN,此字段将被忽略。 | -+-----------------+----------------------------------------------------------------------------------+ -| ssid_len | SSID 的长度。如果 ssid_len 为 0,则检查 SSID 直至出现终止字符。如果 | -| | ssid_len 大于 32,请更改为 32,或者根据 ssid_len 设置 SSID 长度。 | -+-----------------+----------------------------------------------------------------------------------+ -| channel | AP 的信道。如果信道超出范围,Wi-Fi 驱动程序将默认该信道为信道 | -| | 1。所以,请确保信道在要求的范围内。有关详细信息,请参阅 `Wi-Fi 国家/地区代码`_。 | -+-----------------+----------------------------------------------------------------------------------+ -| authmode | ESP AP 的身份验证模式。目前,ESP Wi-Fi 不支持 | -| | AUTH_WEP。如果 authmode 是一个无效值,AP | -| | 默认该值为 WIFI_AUTH_OPEN。 | -+-----------------+----------------------------------------------------------------------------------+ -| ssid_hidden | 如果 ssid_hidden 为 1,AP 不广播 SSID。若为其他值,则广播。 | -+-----------------+----------------------------------------------------------------------------------+ -| max_connection | 目前,ESP Wi-Fi 支持 10 个 Wi-Fi 连接。如果 | -| | max_connection 大于 10,AP 默认该值为 10。 | -+-----------------+----------------------------------------------------------------------------------+ -| beacon_interval | beacon 间隔。值为 100 ~ 60000 ms,默认值为 100 | -| | ms。如果该值不在上述范围,AP 默认取 100 ms。 | -+-----------------+----------------------------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 55 + + * - 字段 + - 描述 + * - ssid + - 指 AP 的 SSID。如果 ssid[0] 和 ssid[1] 均为 0xFF,AP 默认 SSID 为 ESP_aabbcc,”aabbcc” 是 AP MAC 的最后三个字节。 + * - password + - AP 的密码。如果身份验证模式为 WIFI_AUTH_OPEN,此字段将被忽略。 + * - ssid_len + - SSID 的长度。如果 ssid_len 为 0,则检查 SSID 直至出现终止字符。如果 ssid_len 大于 32,请更改为 32,或者根据 ssid_len 设置 SSID 长度。 + * - channel + - AP 的信道。如果信道超出范围,Wi-Fi 驱动程序将默认该信道为信道 1。所以,请确保信道在要求的范围内。有关详细信息,请参阅 `Wi-Fi 国家/地区代码`_。 + * - authmode + - ESP AP 的身份验证模式。目前,ESP Wi-Fi 不支持 AUTH_WEP。如果 authmode 是一个无效值,AP 默认该值为 WIFI_AUTH_OPEN。 + * - ssid_hidden + - 如果 ssid_hidden 为 1,AP 不广播 SSID。若为其他值,则广播。 + * - max_connection + - 目前,ESP Wi-Fi 支持 10 个 Wi-Fi 连接。如果 max_connection 大于 10,AP 默认该值为 10。 + * - beacon_interval + - beacon 间隔。值为 100 ~ 60000 ms,默认值为 100 ms。如果该值不在上述范围,AP 默认取 100 ms。 Wi-Fi 协议模式 +++++++++++++++++++++++++ 目前,IDF 支持以下协议模式: -+--------------+------------------------------------------------------------------------------------------------------------------+ -| 协议模式 | 描述 | -+--------------+------------------------------------------------------------------------------------------------------------------+ -| 802.11b | 调用函数 :cpp:func:`esp_wifi_set_protocol` (ifx, WIFI_PROTOCOL_11B),将 | -| | station/AP 设置为仅 802.11b 模式。 | -+--------------+------------------------------------------------------------------------------------------------------------------+ -| 802.11bg | 调用函数 :cpp:func:`esp_wifi_set_protocol` (ifx, WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G),将 station/AP 设置为 | -| | 802.11bg 模式。 | -+--------------+------------------------------------------------------------------------------------------------------------------+ -| 802.11bgn | 调用函数 :cpp:func:`esp_wifi_set_protocol` (ifx, WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N),将 | -| | station/AP 设置为 802.11bgn 模式。 | -+--------------+------------------------------------------------------------------------------------------------------------------+ -| 802.11 BGNLR | 调用函数 :cpp:func:`esp_wifi_set_protocol` | -| | (ifx, WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N|WIFI_PROTOCOL_LR),将 station/AP 设置为 802.11bgn | -| | 和乐鑫专属模式。 | -+--------------+------------------------------------------------------------------------------------------------------------------+ -| 802.11 LR | 调用函数 :cpp:func:`esp_wifi_set_protocol` (ifx, WIFI_PROTOCOL_LR),将 | -| | station/AP 设置为仅乐鑫专属模式。 | -| | | -| | **此模式是乐鑫的专利模式,可以达到 1 公里视线范围。请确保 | -| | station 和 AP 同时连接至 ESP 设备。** | -+--------------+------------------------------------------------------------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 55 + + * - 协议模式 + - 描述 + * - 802.11b + - 调用函数 esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B),将 station/AP 设置为仅 802.11b 模式。 + * - 802.11bg + - 调用函数 esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G),将 station/AP 设置为 802.11bg 模式。 + * - 802.11bgn + - 调用函数 esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N),将 station/AP 设置为 802.11bgn 模式。 + * - 802.11 BGNLR + - 调用函数 esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N|WIFI_PROTOCOL_LR),将 station/AP 设置为 802.11bgn 和乐鑫专属模式。 + * - 802.11 LR + - 调用函数 esp_wifi_set_protocol(ifx, WIFI_PROTOCOL_LR),将 station/AP 设置为仅乐鑫专属模式。 + + **此模式是乐鑫的专利模式,可以达到 1 公里视线范围。请确保 station 和 AP 同时连接至 ESP 设备。** 远程 (LR) +++++++++++++++++++++++++ @@ -1190,66 +1208,69 @@ Wi-Fi 国家/地区代码 调用 :cpp:func:`esp_wifi_set_country()`,设置国家/地区信息。下表详细介绍了各个字段,请在配置这些字段之前参考当地的 2.4GHz RF 操作规定。 -+--------+----------------------------------------------------------------------------------------------------------------+ -| 字段 | 描述 | -+--------+----------------------------------------------------------------------------------------------------------------+ -| cc[3] | 国家/地区代码字符串,此属性标识 station/AP | -| | 位于的国家/地区或非国家/地区实体。如果是一个国家/地区,该字符串的前两个八位字节是 | -| | ISO/IEC3166-1 中规定的国家/地区两位字母代码。第三个八位字节应是下述之一: | -| | | -| | -ASCII 码空格字符,代表 station/AP 所处国家/地区的规定允许当前频段所需的所有环境。 | -| | | -| | -ASCII 码 'O' 字符,代表 station/AP 所处国家/地区的规定仅允许室外环境。 | -| | | -| | -ASCII 码 'I' 字符,代表 station/AP 所处国家/地区的规定仅允许室内环境。 | -| | | -| | -ASCII 码 'X' 字符,代表 station/AP 位于非国家/地区实体。非国家实体的前两个八位字节是两个ASCII 码 'XX' 字符。 | -| | | -| | -当前使用的操作类表编号的二进制形式。见 IEEE Std 802.11-2012 附件 E。 | -+--------+----------------------------------------------------------------------------------------------------------------+ -| schan | 起始信道,station/AP 所处国家/地区规定的最小信道数。 | -+--------+----------------------------------------------------------------------------------------------------------------+ -| nchan | 规定的总信道数,比如,如果 schan=1,nchan=13,那么 station/AP 可以从信道 1 至 13 发送数据。 | -+--------+----------------------------------------------------------------------------------------------------------------+ -| policy | 国家/地区政策,当配置的国家/地区信息与所连 AP | -| | 的国家/地区信息冲突时,该字段决定使用哪一信息。更多政策相关信息,可参见下文。 | -+--------+----------------------------------------------------------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 55 + + * - 字段 + - 描述 + * - cc[3] + - 国家/地区代码字符串,此属性标识 station/AP 位于的国家/地区或非国家/地区实体。如果是一个国家/地区,该字符串的前两个八位字节是 ISO/IEC3166-1 中规定的国家/地区两位字母代码。第三个八位字节应是下述之一: + + - ASCII 码空格字符,代表 station/AP 所处国家/地区的规定允许当前频段所需的所有环境。 + - ASCII 码 ‘O’ 字符,代表 station/AP 所处国家/地区的规定仅允许室外环境。 + - ASCII 码 ‘I’ 字符,代表 station/AP 所处国家/地区的规定仅允许室内环境。 + - ASCII 码 ‘X’ 字符,代表 station/AP 位于非国家/地区实体。非国家实体的前两个八位字节是两个 ASCII 码 ‘XX’ 字符。 + - 当前使用的操作类表编号的二进制形式。见 IEEE Std 802.11-2012 附件 E。 + + * - schan + - 起始信道,station/AP 所处国家/地区规定的最小信道数。 + * - nchan + - 规定的总信道数,比如,如果 schan=1,nchan=13,那么 station/AP 可以从信道 1 至 13 发送数据。 + * - policy + - 国家/地区政策,当配置的国家/地区信息与所连 AP 的国家/地区信息冲突时,该字段决定使用哪一信息。更多政策相关信息,可参见下文。 默认国家/地区信息为 {.cc="CN", .schan=1, .nchan=13, policy=WIFI_COUNTRY_POLICY_AUTO},如果 Wi-Fi 模式为 AP-STA 共存模式,则它们配置的国家/地区信息相同。有时,station 所连 AP 的国家/地区信息与配置的不同。例如,配置的 station 国家/地区信息为 {.cc="JP", .schan=1, .nchan=14, policy=WIFI_COUNTRY_POLICY_AUTO},但所连 AP 的国家/地区信息为 {.cc="CN", .schan=1, .nchan=13},此时,使用 AP 的国家/地区信息。 + 下表描述了在不同 Wi-Fi 模式和不同国家/地区政策下使用的国家/地区信息,并描述了对主动扫描的影响。 -+---------------------+----------------------------+------------------------------------------------------------------------------+ -| Wi-Fi 模式 | 政策 | 描述 | -+---------------------+----------------------------+------------------------------------------------------------------------------+ -| Station 模式 | WIFI_COUNTRY_POLICY_AUTO | 如果所连 AP 的 beacon 中有国家/地区的 IE,使用的国家/地区信息为 beacon | -| | | 中的信息,否则,使用默认信息。 | -| | | | -| | | 扫描时: | -| | | | -| | | -如果 schan+nchan-1>11, | -| | | 主动扫描起始信道至信道 11,被动扫描信道 12 至 信道 | -| | | schan+nchan-1。 | -| | | | -| | | -如果 schan+nchan-1<=11, | -| | | 主动扫描起始信道至信道 schan+nchan-1。 | -| | | | -| | | 请记住,如果 AP 带有隐藏 SSID | -| | | 且被设置为被动扫描信道,被动扫描将无法找到该 | -| | | AP。也就是说,如果应用程序希望在每个信道中找到带有隐藏 | -| | | SSID 的 AP,国家/地区信息应该配置为 | -| | | WIFI_COUNTRY_POLICY_MANUAL。 | -+---------------------+----------------------------+------------------------------------------------------------------------------+ -| Station 模式 | WIFI_COUNTRY_POLICY_MANUAL | 总是使用配置的国家/地区信息。 扫描时,主动扫描起始信道至信道 schan+nchan-1。 | -+---------------------+----------------------------+------------------------------------------------------------------------------+ -| AP 模式 | WIFI_COUNTRY_POLICY_AUTO | 总是使用配置的国家/地区信息。 | -+---------------------+----------------------------+------------------------------------------------------------------------------+ -| AP 模式 | WIFI_COUNTRY_POLICY_MANUAL | 总是使用配置的国家/地区信息。 | -+---------------------+----------------------------+------------------------------------------------------------------------------+ -| Station/AP 共存模式 | WIFI_COUNTRY_POLICY_AUTO | 如果 station 不连接任何 AP,AP 使用配置的国家/地区信息。如果 station | -| | | 连接一个 AP,该 AP 的国家/地区信息与该 station 相同。与 | -| | | Station 模式、WIFI_COUNTRY_POLICY_AUTO 政策下使用的国家/地区信息相同。 | -+---------------------+----------------------------+------------------------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 15 15 35 + * - Wi-Fi 模式 + - 政策 + - 描述 + * - station 模式 + - WIFI_COUNTRY_POLICY_AUTO + - 如果所连 AP 的 beacon 中有国家/地区的 IE,使用的国家/地区信息为 beacon 中的信息,否则,使用默认信息。 + + 扫描时: + + - 如果 schan+nchan-1>11: + + 主动扫描起始信道至信道 11,被动扫描信道 12 至 信道 schan+nchan-1。 + + - 如果 schan+nchan-1<=11: + + 主动扫描起始信道至信道 schan+nchan-1。 + + 请记住,如果 AP 带有隐藏 SSID 且 station 被设置为被动扫描信道,被动扫描将无法找到该 AP。也就是说,如果应用程序希望在每个信道中找到带有隐藏 SSID 的 AP,国家/地区信息应该配置为 WIFI_COUNTRY_POLICY_MANUAL。 + + * - station 模式 + - WIFI_COUNTRY_POLICY_MANUAL + - 总是使用配置的国家/地区信息。 扫描时,主动扫描起始信道至信道 schan+nchan-1。 + * - AP 模式 + - WIFI_COUNTRY_POLICY_AUTO + - 总是使用配置的国家/地区信息。 + * - AP 模式 + - WIFI_COUNTRY_POLICY_MANUAL + - 总是使用配置的国家/地区信息。 + * - station/AP 共存模式 + - WIFI_COUNTRY_POLICY_AUTO + - 如果 station 不连接任何外部 AP,AP 使用配置的国家/地区信息。如果 station 连接一个外部 AP,该 AP 的国家/地区信息与该 station 相同。 + + 与 station 模式、WIFI_COUNTRY_POLICY_AUTO 政策下使用的国家/地区信息相同。 主信道 ************************* @@ -1262,40 +1283,70 @@ Wi-Fi 供应商 IE 配置 默认情况下,所有 Wi-Fi 管理帧都由 Wi-Fi 驱动程序处理,应用程序不需要任何操作。但是,某些应用程序可能需要处理 beacon、probe request、probe response 和其他管理帧。例如,如果在管理帧中插入一些只针对供应商的 IE,则只有包含此 IE 的管理帧才能得到处理。{IDF_TARGET_NAME} 中,:cpp:func:`esp_wifi_set_vendor_ie()` 和 :cpp:func:`esp_wifi_set_vendor_ie_cb()` 负责此类任务。 -Wi-Fi 安全性 -------------------------------- -除了传统的安全保障方法 (WEP/WPA-TKIP/WPA2-CCMP),{IDF_TARGET_NAME} Wi-Fi 如今还支持最先进的安全协议,即基于 802.11w 标准的“受保护的管理帧” (PMF) 和 Wi-Fi Protected Access 3 (WPA3-Personal) 技术。PMF 与 WPA3 一道,提供更好的隐私性,也能更强地抵御传统模式下的已知攻击。 +Wi-Fi Easy Connect™ (DPP) +-------------------------- -受保护的管理帧 (PMF) -++++++++++++++++++++++++++++++++++ +Wi-Fi Easy Connect\ :sup:`TM`(也称为设备配置协议)是一个安全且标准化的配置协议,用于配置 Wi-Fi 设备。更多信息请参考 :doc:`esp_dpp <../api-reference/network/esp_dpp>`。 -在 Wi-Fi 中,非 AP station 使用 beacon、探测器、(de)authentication、(dis)association 等管理帧来扫描和连接 AP。与数据帧不同,这些帧发送时未加密。 -攻击者可以使用窃听和数据包注入等方式在恰当的时间发送虚假的 (de)authentication 和 (dis)association 帧,如果未受保护的管理帧发生改变,将出现以下攻击。 - - - 在攻击者范围内对一个或所有 client 进行 DOS 攻击。 - - 通过发送关联请求取消 AP 端的现有关联。 - - 如果 PSK 遭到破坏,强制 client 再次执行 4 次握手,以获得 PTK。 - - 从关联请求获取隐藏网络的 SSID。 - - 强制 client 从合法 AP 中 (de)authentication,并关联到流氓 AP,发起中间人攻击。 - -PMF 通过对单播管理帧进行加密,并检查广播管理帧的完整性,阻止上述攻击。其中包括 (de)authentication、(dis)association 和强奸的管理帧。PMF 同样提供“安全关联” (SA) 拆解机制,阻止欺骗 association/authentication frame 断开已连接的 client。 - -关于PMF,{IDF_TARGET_NAME} 支持以下三种操作模式。 - - - 不支持 PMF:此模式下,{IDF_TARGET_NAME} 向 AP 表示在关联过程中不能支持管理保护。实际上,此模式下的安全性与传统模式相同。 - - 支持但未要求使用 PMF:此模式下,{IDF_TARGET_NAME} 向AP表示能够支持 PMF。如果 AP 授权 PMF 或至少能支持 PMF,将使用管理保护。 - - 支持且需要 PMF:此模式下,如果 AP 支持 PMF,{IDF_TARGET_NAME} 将仅连接该 AP。如果不支持,{IDF_TARGET_NAME} 将拒绝连接该 AP。 - -通过在 `pmf_cfg` 参数中设置适当标志,:cpp:func:`esp_wifi_set_config` 可以用来配置 PMF 模式。目前,仅 station 模式支持 PMF。 - - -WPA3-Personal +WPA2-Enterprise +++++++++++++++++++++++++++++++++ -Wi-Fi Protected Access-3 (WPA3) 是一套增强 Wi-Fi 接入安全性的措施,旨在取代目前的 WPA2 标准。为了提供更强健的认证方式,WPA3 采用了等值同时认证 (SAE) 算法,即基于 Diffie-Hellman 密钥交换的密码认证密钥协议方法。与 WPA2 不同,该技术可以抵御离线字典攻击,即攻击者试图在没有任何进一步网络交互的情况下,根据捕获的 4 次握手来确定共享密码。WPA3 还提供前向保密功能,即数据传输后,即使密码泄露,也无法对捕获的数据进行解密。更多详细信息,请见 Wi-Fi 联盟官方网站 `Security `_ 一章。 +WPA2-Enterprise 是企业无线网络的安全认证机制。在连接到接入点 (AP) 之前,它使用 RADIUS 服务器对网络用户进行身份验证。身份验证过程基于 802.1X 标准,并有不同的扩展身份验证协议 (EAP) 方法,如 TLS、TTLS、PEAP 等。RADIUS 服务器根据用户的凭据(用户名和密码)、数字证书或两者对用户进行身份验证。当处于 station 模式的 {IDF_TARGET_NAME} 尝试连接到企业模式的 AP 时,它会向 AP 发送身份验证请求,AP 会将该请求发送到 RADIUS 服务器以对 station 进行身份验证。根据不同的 EAP 方式,可以通过 ``idf.py menuconfig`` 打开配置,并在配置中设置参数。{IDF_TARGET_NAME} 仅在 station 模式下支持 WPA2_Enterprise。 -要使能 WPA3-Personal,请在 menuconfig 中选择 "Enable WPA3-Personal"。使能后,如果 AP 支持,{IDF_TARGET_NAME} 会使用 SAE 进行身份认证。由于 WPA3 强制要求 PMF,{IDF_TARGET_NAME} 要使用 WPA3 模式,至少应该将 PMF 模式设置为 "PMF capable, but not required"(支持但未要求使用 PMF)。应用程序的安全模式已经选用最高级别,因此开发者无需担心。请注意,使用 WPA3 时,Wi-Fi 协议栈大小要求将增加约 3 k。目前,仅 Station 模式支持 WPA3。 +为了建立安全连接,AP 和 station 协商并就要使用的最佳密码套件达成一致。{IDF_TARGET_NAME} 支持 AKM 的 802.1X/EAP (WPA) 方法和 AES-CCM(高级加密标准-带密码块链消息验证码协议的计数器模式)支持的密码套件。如果设置了 `USE_MBEDTLS_CRYPTO` 标志,{IDF_TARGET_NAME} 也支持 mbedtls 支持的密码套件。 + +目前,{IDF_TARGET_NAME} 支持以下 EAP 方法: + - EAP-TLS: 这是基于证书的方法,只需要 SSID 和 EAP-IDF。 + - PEAP: - PEAP:这是受保护的 EAP 方法。用户名和密码是必填项。 + - EAP-TTLS: 这是基于凭据的方法。只有服务器身份验证是强制性的,而用户身份验证是可选的。用户名和密码是必填项。 它支持不同的 Phase2 方法,例如: + - PAP: 密码认证协议 + - CHAP: 询问握手身份验证协议 + - MSCHAP 和 MSCHAP-V2 + - EAP-FAST: 这是一种基于受保护的访问凭据 (PAC) 的认证方法,使用身份验证和密码。目前使用此功能时需要禁用 USE_MBEDTLS_CRYPTO 标志。 + +请查看 :example:`wifi/wpa2_enterprise` 获取关于证书创建以及如何在 {IDF_TARGET_NAME} 上运行 wpa2_enterprise 示例的详细信息。 + +无线网络管理 +---------------------------- + +无线网络管理让客户端设备能够交换有关网络拓扑结构的信息,包括与射频环境相关的信息。这使每个客户端都能感知网络状况,从而促进无线网络性能的整体改进。这是 802.11v 规范的一部分。它还使客户端能够支持网络辅助漫游。 + +网络辅助漫游让 WLAN 能够向关联的客户端发送消息,从而使客户端与具有更好链路指标的 AP 关联。这对于促进负载平衡以及引导连接不良的客户端都很有用。 + +目前 802.11v 的实现支持 BSS 过渡管理帧。 + +无线资源管理 +--------------------------- + +无线电资源测量(802.11k)旨在改善网络内流量的分配方式。在无线局域网中,一般情况下,无线设备会连接发射信号最强的 AP。根据用户的数量和地理位置,这种分配方式有时会导致某个 AP 超负荷而其它 AP 利用不足,从而导致整体网络性能下降。在符合 802.11k 规范的网络中,如果信号最强的 AP 已满负荷加载,无线设备则转移到其它未充分利用的 AP。尽管信号可能较弱,但由于更有效地利用了网络资源,总体吞吐量会更大。 + +目前 802.11k 的实现支持信标测量报告、链路测量报告和邻居请求。 + +请参考 IDF 示例程序 :idf_file:`examples/wifi/roaming/README.md` 来设置和使用这些 API。示例代码只演示了如何使用这些 API,应用程序应根据需要定义自己的算法和案例。 + +.. only:: esp32s2 or esp32c3 + + Wi-Fi Location + ------------------------------- + + Wi-Fi Location 将提高 AP 以外设备位置数据的准确性,这有助于创建新的、功能丰富的应用程序和服务,例如地理围栏、网络管理、导航等。用于确定设备相对于 AP 的位置的协议之一是精细定时测量 (FTM),它会计算 Wi-Fi 帧的飞行时间。 + + 精细定时测量 (FTM) + +++++++++++++++++++++++++++++ + + FTM 用于测量 Wi-Fi 往返时间(Wi-Fi RTT),即 Wi-Fi 信号从一个设备到另一个设备并返回所需的时间。使用 Wi-Fi RTT,设备之间的距离可以用一个简单的公式 `RTT * c / 2` 来计算,其中 c 是光速。 + + 对于设备之间交换的帧,FTM 在帧到达或离开时使用时间戳,这个时间戳由 Wi-Fi 接口硬件提供。FTM 发起方(主要是 station 设备)发现 FTM 响应方(可以是 station 或 AP),并协商启动 FTM 程序。该程序以突发形式发送的多个动作帧及其 ACK 来收集时间戳数据。FTM 发起方最后收集数据以计算平均往返时间。 + + {IDF_TARGET_NAME} 在以下配置中支持 FTM: + + - {IDF_TARGET_NAME} 在 station 模式下为 FTM 发起方。 + - {IDF_TARGET_NAME} 在 AP 模式下为 FTM 响应方。 + + 使用 RTT 的距离测量并不准确,RF 干扰、多径传播、天线方向和缺乏校准等因素会增加这些不准确度。为了获得更好的结果,建议在两个 {IDF_TARGET_NAME} 设备之间执行 FTM,这两个设备可分别设置为 station 和 AP 模式。 + + 请参考 IDF 示例 :idf_file:`examples/wifi/ftm/README.md` 了解设置和执行 FTM 的详细步骤。 {IDF_TARGET_NAME} Wi-Fi 节能模式 ----------------------------------------- @@ -1329,69 +1380,139 @@ AP 睡眠 .. only:: esp32 - +----------------------------+----------------+------------+---------------+----------------------+ - | 类型/吞吐量 | 实验室空气状况 | 屏蔽箱 | 测试工具 | IDF 版本 (commit ID) | - +----------------------------+----------------+------------+---------------+----------------------+ - | 原始 802.11 数据包接收数据 | N/A | 130 MBit/s | 内部工具 | N/A | - +----------------------------+----------------+------------+---------------+----------------------+ - | 原始 802.11 数据包发送数据 | N/A | 130 MBit/s | 内部工具 | N/A | - +----------------------------+----------------+------------+---------------+----------------------+ - | UDP 接收数据 | 30 MBit/s | 85 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ - | UDP 发送数据 | 30 MBit/s | 75 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ - | TCP 接收数据 | 20 MBit/s | 65 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ - | TCP 发送数据 | 20 MBit/s | 75 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 15 20 - 使用 iperf example 测试吞吐量时,sdkconfig 是 :idf_file:` 示例/wifi/iperf/sdkconfig.defaults.esp32`。 + * - 类型/吞吐量 + - 实验室空气状况 + - 屏蔽箱 + - 测试工具 + - IDF 版本 (commit ID) + * - 原始 802.11 数据包接收数据 + - N/A + - **130 MBit/s** + - 内部工具 + - N/A + * - 原始 802.11 数据包发送数据 + - N/A + - **130 MBit/s** + - 内部工具 + - N/A + * - UDP 接收数据 + - 30 MBit/s + - 85 MBit/s + - iperf example + - 15575346 + * - UDP 发送数据 + - 30 MBit/s + - 75 MBit/s + - iperf example + - 15575346 + * - TCP 接收数据 + - 20 MBit/s + - 65 MBit/s + - iperf example + - 15575346 + * - TCP 发送数据 + - 20 MBit/s + - 75 MBit/s + - iperf example + - 15575346 + + 使用 iperf example 测试吞吐量时,sdkconfig 是 :idf_file:` 示例/wifi/iperf/sdkconfig.defaults.esp32s2`。 .. only:: esp32s2 - +----------------------------+----------------+------------+---------------+----------------------+ - | 类型/吞吐量 | 实验室空气状况 | 屏蔽箱 | 测试工具 | IDF 版本 (commit ID) | - +----------------------------+----------------+------------+---------------+----------------------+ - | 原始 802.11 数据包接收数据 | N/A | 130 MBit/s | 内部工具 | N/A | - +----------------------------+----------------+------------+---------------+----------------------+ - | 原始 802.11 数据包发送数据 | N/A | 130 MBit/s | 内部工具 | N/A | - +----------------------------+----------------+------------+---------------+----------------------+ - | UDP 接收数据 | 30 MBit/s | 70 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ - | UDP 发送数据 | 30 MBit/s | 50 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ - | TCP 接收数据 | 20 MBit/s | 32 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ - | TCP 发送数据 | 20 MBit/s | 37 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 15 20 + + * - 类型/吞吐量 + - 实验室空气状况 + - 屏蔽箱 + - 测试工具 + - IDF 版本 (commit ID) + * - 原始 802.11 数据包接收数据 + - N/A + - **130 MBit/s** + - 内部工具 + - N/A + * - 原始 802.11 数据包发送数据 + - N/A + - **130 MBit/s** + - 内部工具 + - N/A + * - UDP 接收数据 + - 30 MBit/s + - 70 MBit/s + - iperf example + - 15575346 + * - UDP 发送数据 + - 30 MBit/s + - 50 MBit/s + - iperf example + - 15575346 + * - TCP 接收数据 + - 20 MBit/s + - 32 MBit/s + - iperf example + - 15575346 + * - TCP 发送数据 + - 20 MBit/s + - 37 MBit/s + - iperf example + - 15575346 使用 iperf example 测试吞吐量时,sdkconfig 是 :idf_file:` 示例/wifi/iperf/sdkconfig.defaults.esp32s2`。 .. only:: esp32c3 - +----------------------------+----------------+------------+---------------+----------------------+ - | 类型/吞吐量 | 实验室空气状况 | 屏蔽箱 | 测试工具 | IDF 版本 (commit ID) | - +----------------------------+----------------+------------+---------------+----------------------+ - | 原始 802.11 数据包接收数据 | N/A | 130 MBit/s | 内部工具 | N/A | - +----------------------------+----------------+------------+---------------+----------------------+ - | 原始 802.11 数据包发送数据 | N/A | 130 MBit/s | 内部工具 | N/A | - +----------------------------+----------------+------------+---------------+----------------------+ - | UDP 接收数据 | 30 MBit/s | 50 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ - | UDP 发送数据 | 30 MBit/s | 40 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ - | TCP 接收数据 | 20 MBit/s | 35 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ - | TCP 发送数据 | 20 MBit/s | 37 MBit/s | iperf example | 15575346 | - +----------------------------+----------------+------------+---------------+----------------------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 15 20 + + * - 类型/吞吐量 + - 实验室空气状况 + - 屏蔽箱 + - 测试工具 + - IDF 版本 (commit ID) + * - 原始 802.11 数据包接收数据 + - N/A + - **130 MBit/s** + - 内部工具 + - N/A + * - 原始 802.11 数据包发送数据 + - N/A + - **130 MBit/s** + - 内部工具 + - N/A + * - UDP 接收数据 + - 30 MBit/s + - 50 MBit/s + - iperf example + - 15575346 + * - UDP 发送数据 + - 30 MBit/s + - 40 MBit/s + - iperf example + - 15575346 + * - TCP 接收数据 + - 20 MBit/s + - 35 MBit/s + - iperf example + - 15575346 + * - TCP 发送数据 + - 20 MBit/s + - 37 MBit/s + - iperf example + - 15575346 使用 iperf example 测试吞吐量时,sdkconfig 是 :idf_file:` 示例/wifi/iperf/sdkconfig.defaults.esp32c3`。 Wi-Fi 80211 数据包发送 --------------------------- -**重要说明:API esp_wifi_80211_tx 在 IDF 2.1 中不可用,即将发布的版本将可以使用。** - :cpp:func:`esp_wifi_80211_tx` API 可用于: - 发送 beacon、probe request、probe response 和 action 帧。 @@ -1417,67 +1538,46 @@ Wi-Fi 80211 数据包发送 理论上,如果不考虑 API 对 Wi-Fi 驱动程序或其他 station 或 AP 的副作用,可以通过空中发送一个原始的 802.11 数据包,包括任何目的地址的 MAC、任何源地址的 MAC、任何 BSSID、或任何其他类型的数据包。但是,一个具有强健、有用的应用程序应该避免这种副作用。下表针对如何避免 :cpp:func:`esp_wifi_80211_tx` 的副作用提供了一些提示或建议。 -+---------------+--------------------------------------------------------------------------------------------+ -| 场景 | 描述 | -+---------------+--------------------------------------------------------------------------------------------+ -| 无 Wi-Fi 连接 | 在这种情况下,因为没有 Wi-Fi 连接,Wi-Fi 驱动程序不会受到副作用影响。如果 | -| | en_sys_seq==true,则 Wi-Fi 驱动程序负责序列控制。如果 | -| | en_sys_seq==false,应用程序需要确保缓冲区的序列正确。 | -| | | -| | 理论上,MAC 地址可以是任何地址。但是,这样可能会影响其他使用相同 MAC/BSSID 的 station/AP。 | -| | | -| | 例如,AP 模式下,应用程序调用函数 | -| | :cpp:func:`esp_wifi_80211_tx` 发送带有 BSSID == mac_x 的 beacon,但是 mac_x | -| | 并非 AP 接口的 MAC。而且,还有 另一个 AP(我们称之为 "other-AP")的 bssid 是 | -| | mac_x。因此,连接到 "other-AP" 的 station 无法分辨 beacon 来自 "other-AP" 还是 | -| | :cpp:func:`esp_wifi_80211_tx`,就会出现 “意外行为”。 | -| | | -| | 为了避免上述副作用,我们建议: | -| | | -| | -如果在 Station 模式下调用函数 :cpp:func:`esp_wifi_80211_tx`,第一个 MAC 应该是组播 | -| | | -| | MAC 或是目标设备的 MAC,第二个 MAC 应该是 station 接口的 MAC。 | -| | | -| | -如果在 AP 模式下调用函数 esp_wifi_80211_tx,第一个 MAC 应该是组播 MAC 或是目标设备的 | -| | | -| | MAC, 第二个 MAC 应该是 AP 接口的 MAC。 | -| | | -| | 上述建议仅供避免副作用,在有充分理由的情况下可以忽略。 | -+---------------+--------------------------------------------------------------------------------------------+ -| 有 Wi-Fi 连接 | 当 Wi-Fi 已连接,且序列由应用程序控制,应用程序可能会影响整个 Wi-Fi | -| | 连接的序列控制。 因此,en_sys_seq 要为 true,否则将返回 ESP_ERR_WIFI_ARG。 | -| | | -| | “无 Wi-Fi 连接” 情况下的 MAC 地址建议也适用于此情况。如果 Wi-Fi | -| | 模式是 Station 模式,MAC 的地址 1 是 station 所连 AP 的 MAC,地址 | -| | 2 是 station 接口的 MAC,那么就称数据包是从 station 发送到 AP。另一方面,如果 Wi-Fi | -| | 模式是 AP 模式,且 MAC 地址 1 是该 AP 所连 station 的 MAC,地址 2 是 | -| | AP 接口的 MAC,那么就称数据包是从 AP 发送到 station。为避免与 | -| | Wi-Fi 连接冲突,可采用以下检查方法: | -| | | -| | -如果数据包类型是数据,且是从 station 发送到 AP,IEEE 802.11 | -| | | -| | Frame control 字段中的 ToDS 位应该为 1,FromDS 位为 0,否则,Wi-Fi | -| | | -| | 驱动程序不接受该数据包。 | -| | | -| | -如果数据包类型是数据,且是从 AP 发送到 station,IEEE 802.11 | -| | | -| | Frame control 字段中的 ToDS 位应该为 0,FromDS 位为 1,否则,Wi-Fi | -| | | -| | 驱动程序不接受该数据包。 | -| | | -| | -如果数据包是从 station 发送到 AP,或从 AP 到 station,Power Management、More | -| | | -| | Data 和 Re-Transmission 位应该为 0,否则,Wi-Fi 驱动程序不接受该数据包。 | -| | | -| | 如果任何检查失败,将返回 ESP_ERR_WIFI_ARG。 | -+---------------+--------------------------------------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 10 55 + + * - 场景 + - 描述 + * - 无 Wi-Fi 连接 + - 在这种情况下,因为没有 Wi-Fi 连接,Wi-Fi 驱动程序不会受到副作用影响。如果 en_sys_seq==true,则 Wi-Fi 驱动程序负责序列控制。如果 en_sys_seq==false,应用程序需要确保缓冲区的序列正确。 + + 理论上,MAC 地址可以是任何地址。但是,这样可能会影响其他使用相同 MAC/BSSID 的 station/AP。 + + 例如,AP 模式下,应用程序调用函数 esp_wifi_80211_tx() 发送带有 BSSID == mac_x 的 beacon,但是 mac_x 并非 AP 接口的 MAC。而且,还有另一个 AP(我们称之为 “other-AP”)的 bssid 是 mac_x。因此,连接到 “other-AP” 的 station 无法分辨 beacon 来自 “other-AP” 还是 esp_wifi_80211_tx(),就会出现 “意外行为”。 + + 为了避免上述副作用,我们建议: + + - 如果在 station 模式下调用函数 esp_wifi_80211_tx(),第一个 MAC 应该是组播 MAC 或是目标设备的 MAC,第二个 MAC 应该是 station 接口的 MAC。 + + - 如果在 AP 模式下调用函数 esp_wifi_80211_tx,第一个 MAC 应该是组播 MAC 或是目标设备的 MAC,第二个 MAC 应该是 AP 接口的 MAC。 + + 上述建议仅供避免副作用,在有充分理由的情况下可以忽略。 + + * - 有 Wi-Fi 连接 + - 当 Wi-Fi 已连接,且序列由应用程序控制,应用程序可能会影响整个 Wi-Fi 连接的序列控制。 因此,en_sys_seq 要为 true,否则将返回 ESP_ERR_WIFI_ARG。 + + “无 Wi-Fi 连接”情况下的 MAC 地址建议也适用于此情况。 + + 如果 Wi-Fi 模式是 station 模式,MAC 的地址 1 是 station 所连 AP 的 MAC,地址 2 是 station 接口的 MAC,那么就称数据包是从 station 发送到 AP。另一方面,如果 Wi-Fi 模式是 AP 模式,且 MAC 地址 1 是该 AP 所连 station 的 MAC,地址 2 是 AP 接口的 MAC,那么就称数据包是从 AP 发送到 station。为避免与 Wi-Fi 连接冲突,可采用以下检查方法: + + - 如果数据包类型是数据,且是从 station 发送到 AP,IEEE 802.11 Frame control 字段中的 ToDS 位应该为 1,FromDS 位为 0,否则,Wi-Fi 驱动程序不接受该数据包。 + + - 如果数据包类型是数据,且是从 AP 发送到 station,IEEE 802.11 Frame control 字段中的 ToDS 位应该为 0,FromDS 位为 1,否则,Wi-Fi 驱动程序不接受该数据包。 + + - 如果数据包是从 station 发送到 AP,或从 AP 到 station,Power Management、More Data 和 Re-Transmission 位应该为 0,否则,Wi-Fi 驱动程序不接受该数据包。 + + 如果任何检查失败,将返回 ESP_ERR_WIFI_ARG。 Wi-Fi Sniffer 模式 --------------------------- -Wi-Fi Sniffer 模式可以通过 :cpp:func:`esp_wifi_set_promiscuous()` 使能。如果使能 Sniffer 模式, **可以** -向应用程序转储以下数据包。 +Wi-Fi Sniffer 模式可以通过 :cpp:func:`esp_wifi_set_promiscuous()` 使能。如果使能 Sniffer 模式, **可以** 向应用程序转储以下数据包。 - 802.11 管理帧 - 802.11 数据帧,包括 MPDU、AMPDU、AMSDU 等 @@ -1523,7 +1623,6 @@ Wi-Fi 多根天线 - 因为发送数据天线基于 WIFI_ANT_MODE_AUTO 类型的接收数据天线选择算法,只有接收数据的天线模式为 WIFI_ANT_MODE_AUTO 时,发送数据天线才能设置为 WIFI_ANT_MODE_AUTO。 - 目前,Bluetooth® 不支持多根天线功能,请不要使用与多根天线有关的 API。 - - 目前不支持 Bluetooth/Bluetooth LE SoftAP 共存模式。 推荐在以下场景中使用多根天线: @@ -1587,10 +1686,9 @@ Wi-Fi 信道状态信息 - 如果 wifi_csi_info_t 的 first_word_invalid 字段为 true,表示由于 {IDF_TARGET_NAME} 的硬件限制,CSI 数据的前四个字节无效。 - 更多信息,如RSSI,射频的噪声底,接收时间和天线 rx_ctrl 领域。 -.. note :: +.. note:: - 对于 STBC 数据包,每个空时流都提供了 CSI,不会出现 CSD(循环移位延迟)。由于附加链上的每一次循环移位为 -200 ns,因为子载波 0 中没有信道频率响应,在 HT-LTF 和 STBC-HT-LTF 中只记录第一空时流的 CSD 角度。CSD[10:0] 是 11 位,范围从 -pi 到 pi。 - - 如果调用 API :cpp:func:`esp_wifi_set_csi_config` 没有使能 LLTF、HT-LTF 或 STBC-HT-LTF,则 CSI 数据的总字节数会比表中的少。例如,如果没有使能 LLTF 和 HT-LTF,而使能 STBC-HT-LTF,当接收到上述条件、HT、40 MHz 或 STBC的数据包时,CSI 数据的总字节数为 244((61+60)*2+2=244,结果对齐为四个字节,最后两个字节无效)。 Wi-Fi 信道状态信息配置 @@ -1808,111 +1906,305 @@ Wi-Fi 使用的堆内存峰值是 Wi-Fi 驱动程序 **理论上消耗的最大 .. only:: esp32 - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | 等级 | Iperf | 发送数据优先 | 高性能 | 接收数据优先 | 默认值 | 节省内存 | 最小 | - +============================+=======+==============+========+==============+========+==========+=======+ - | 可用内存 (KB) | 37.1 | 113.8 | 123.3 | 145.5 | 144.5 | 170.2 | 185.2 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | WIFI_STATIC_RX_BUFFER_NUM | 16 | 6 | 6 | 6 | 6 | 6 | 4 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | WIFI_DYNAMIC_RX_BUFFER_NUM | 64 | 16 | 24 | 34 | 20 | 12 | 8 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | WIFI_DYNAMIC_TX_BUFFER_NUM | 64 | 28 | 24 | 18 | 20 | 12 | 8 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | WIFI_RX_BA_WIN | 32 | 8 | 12 | 12 | 10 | 6 | 禁用 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | TCP_SND_BUF_DEFAULT (KB) | 65 | 28 | 24 | 18 | 20 | 12 | 8 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | TCP_WND_DEFAULT (KB) | 65 | 16 | 24 | 34 | 20 | 12 | 8 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | WIFI_IRAM_OPT | 15 | 15 | 15 | 15 | 15 | 15 | 15 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | WIFI_RX_IRAM_OPT | 16 | 16 | 16 | 16 | 16 | 16 | 16 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | LWIP_IRAM_OPTIMIZATION | 13 | 13 | 13 | 13 | 13 | 13 | 13 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | TCP 发送数据吞吐量 (Mbit/s)| 74.6 | 50.8 | 46.5 | 39.9 | 44.2 | 33.8 | 25.6 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | TCP 接收数据吞吐量 (Mbit/s)| 63.6 | 35.5 | 42.3 | 48.5 | 40.5 | 30.1 | 27.8 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | UDP 发送数据吞吐量 (Mbit/s)| 76.2 | 75.1 | 74.1 | 72.4 | 69.6 | 64.1 | 36.5 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ - | UDP 接收数据吞吐量 (Mbit/s)| 83.1 | 66.3 | 75.1 | 75.6 | 73.1 | 65.3 | 54.7 | - +----------------------------+-------+--------------+--------+--------------+--------+----------+-------+ + .. list-table:: + :header-rows: 1 + :widths: 10 5 5 10 5 5 10 5 + + * - 等级 + - Iperf + - 发送数据优先 + - 高性能 + - 接收数据优先 + - 默认值 + - 节省内存 + - 最小 + * - 可用内存 (KB) + - 37.1 + - 113.8 + - 123.3 + - 145.5 + - 144.5 + - 170.2 + - 185.2 + * - WIFI_STATIC_RX_BUFFER_NUM + - 16 + - 6 + - 6 + - 6 + - 6 + - 6 + - 4 + * - WIFI_DYNAMIC_RX_BUFFER_NUM + - 64 + - 16 + - 24 + - 34 + - 20 + - 12 + - 8 + * - WIFI_DYNAMIC_TX_BUFFER_NUM + - 64 + - 28 + - 24 + - 18 + - 20 + - 12 + - 8 + * - WIFI_RX_BA_WIN + - 32 + - 8 + - 12 + - 12 + - 10 + - 6 + - 禁用 + * - TCP_SND_BUF_DEFAULT (KB) + - 65 + - 28 + - 24 + - 18 + - 20 + - 12 + - 8 + * - TCP_WND_DEFAULT (KB) + - 65 + - 16 + - 24 + - 34 + - 20 + - 12 + - 8 + * - WIFI_IRAM_OPT + - 15 + - 15 + - 15 + - 15 + - 15 + - 15 + - 15 + * - WIFI_RX_IRAM_OPT + - 16 + - 16 + - 16 + - 16 + - 16 + - 16 + - 16 + * - LWIP_IRAM_OPTIMIZATION + - 13 + - 13 + - 13 + - 13 + - 13 + - 13 + - 13 + * - TCP 发送数据吞吐量 (Mbit/s) + - 74.6 + - 50.8 + - 46.5 + - 39.9 + - 44.2 + - 33.8 + - 25.6 + * - TCP 接收数据吞吐量 (Mbit/s) + - 63.6 + - 35.5 + - 42.3 + - 48.5 + - 40.5 + - 30.1 + - 27.8 + * - UDP 发送数据吞吐量 (Mbit/s) + - 76.2 + - 75.1 + - 74.1 + - 72.4 + - 69.6 + - 64.1 + - 36.5 + * - UDP 接收数据吞吐量 (Mbit/s) + - 83.1 + - 66.3 + - 75.1 + - 75.6 + - 73.1 + - 65.3 + - 54.7 .. only:: esp32s2 - +----------------------------+-------+--------+------+----------+-------+ - | 等级 | Iperf | 高性能 | 默认 | 节省内存 | 最小 | - +============================+=======+========+======+==========+=======+ - | 可用内存 (KB) | 4.1 | 24.2 | 78.4 | 86.5 | 116.4 | - +----------------------------+-------+--------+------+----------+-------+ - | WIFI_STATIC_RX_BUFFER_NUM | 8 | 6 | 6 | 4 | 3 | - +----------------------------+-------+--------+------+----------+-------+ - | WIFI_DYNAMIC_RX_BUFFER_NUM | 24 | 18 | 12 | 8 | 6 | - +----------------------------+-------+--------+------+----------+-------+ - | WIFI_DYNAMIC_TX_BUFFER_NUM | 24 | 18 | 12 | 8 | 6 | - +----------------------------+-------+--------+------+----------+-------+ - | WIFI_RX_BA_WIN | 12 | 9 | 6 | 4 | 3 | - +----------------------------+-------+--------+------+----------+-------+ - | TCP_SND_BUF_DEFAULT (KB) | 24 | 18 | 12 | 8 | 6 | - +----------------------------+-------+--------+------+----------+-------+ - | TCP_WND_DEFAULT (KB) | 24 | 18 | 12 | 8 | 6 | - +----------------------------+-------+--------+------+----------+-------+ - | WIFI_IRAM_OPT | 15 | 15 | 15 | 15 | 0 | - +----------------------------+-------+--------+------+----------+-------+ - | WIFI_RX_IRAM_OPT | 16 | 16 | 16 | 0 | 0 | - +----------------------------+-------+--------+------+----------+-------+ - | LWIP_IRAM_OPTIMIZATION | 13 | 13 | 0 | 0 | 0 | - +----------------------------+-------+--------+------+----------+-------+ - | INSTRUCTION_CACHE | 16 | 16 | 16 | 16 | 8 | - +----------------------------+-------+--------+------+----------+-------+ - | INSTRUCTION_CACHE_LINE | 16 | 16 | 16 | 16 | 16 | - +----------------------------+-------+--------+------+----------+-------+ - | TCP 发送数据吞吐量 (Mbit/s)| 37.6 | 33.1 | 22.5 | 12.2 | 5.5 | - +----------------------------+-------+--------+------+----------+-------+ - | TCP 接收数据吞吐量 (Mbit/s)| 31.5 | 28.1 | 20.1 | 13.1 | 7.2 | - +----------------------------+-------+--------+------+----------+-------+ - | UDP 发送数据吞吐量 (Mbit/s)| 58.1 | 57.3 | 28.1 | 22.6 | 8.7 | - +----------------------------+-------+--------+------+----------+-------+ - | UDP 接收数据吞吐量 (Mbit/s)| 78.1 | 66.7 | 65.3 | 53.8 | 28.5 | - +----------------------------+-------+--------+------+----------+-------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 10 10 10 + + * - 等级 + - Iperf + - 高性能 + - 默认 + - 节省内存 + - 最小 + * - 可用内存 (KB) + - 4.1 + - 24.2 + - 78.4 + - 86.5 + - 116.4 + * - WIFI_STATIC_RX_BUFFER_NUM + - 8 + - 6 + - 6 + - 4 + - 3 + * - WIFI_DYNAMIC_RX_BUFFER_NUM + - 24 + - 18 + - 12 + - 8 + - 6 + * - WIFI_DYNAMIC_TX_BUFFER_NUM + - 24 + - 18 + - 12 + - 8 + - 6 + * - WIFI_RX_BA_WIN + - 12 + - 9 + - 6 + - 4 + - 3 + * - TCP_SND_BUF_DEFAULT (KB) + - 24 + - 18 + - 12 + - 8 + - 6 + * - TCP_WND_DEFAULT (KB) + - 24 + - 18 + - 12 + - 8 + - 6 + * - WIFI_IRAM_OPT + - 15 + - 15 + - 15 + - 15 + - 0 + * - WIFI_RX_IRAM_OPT + - 16 + - 16 + - 16 + - 0 + - 0 + * - LWIP_IRAM_OPTIMIZATION + - 13 + - 13 + - 0 + - 0 + - 0 + * - INSTRUCTION_CACHE + - 16 + - 16 + - 16 + - 16 + - 8 + * - INSTRUCTION_CACHE_LINE + - 16 + - 16 + - 16 + - 16 + - 16 + * - TCP 发送数据吞吐量 (Mbit/s) + - 37.6 + - 33.1 + - 22.5 + - 12.2 + - 5.5 + * - TCP 接收数据吞吐量 (Mbit/s) + - 31.5 + - 28.1 + - 20.1 + - 13.1 + - 7.2 + * - UDP 发送数据吞吐量 (Mbit/s) + - 58.1 + - 57.3 + - 28.1 + - 22.6 + - 8.7 + * - UDP 接收数据吞吐量 (Mbit/s) + - 78.1 + - 66.7 + - 65.3 + - 53.8 + - 28.5 .. only:: esp32c3 - +----------------------------+-------+---------+---------+ - | 等级 | Iperf | 默认 | 最小 | - +============================+=======+=========+=========+ - | 可用内存(KB) | 59 | 160 | 180 | - +----------------------------+-------+---------+---------+ - | WIFI_STATIC_RX_BUFFER_NUM | 20 | 8 | 3 | - +----------------------------+-------+---------+---------+ - | WIFI_DYNAMIC_RX_BUFFER_NUM | 40 | 16 | 6 | - +----------------------------+-------+---------+---------+ - | WIFI_DYNAMIC_TX_BUFFER_NUM | 40 | 16 | 6 | - +----------------------------+-------+---------+---------+ - | WIFI_RX_BA_WIN | 32 | 16 | 6 | - +----------------------------+-------+---------+---------+ - | TCP_SND_BUF_DEFAULT(KB) | 40 | 16 | 6 | - +----------------------------+-------+---------+---------+ - | TCP_WND_DEFAULT(KB) | 40 | 16 | 6 | - +----------------------------+-------+---------+---------+ - | LWIP_IRAM_OPTIMIZATION | 13 | 13 | 0 | - +----------------------------+-------+---------+---------+ - | TCP 发送数据吞吐量 (Mbit/s)| 38.1 | 27.2 | 20.4 | - +----------------------------+-------+---------+---------+ - | TCP 接收数据吞吐量 (Mbit/s)| 35.3 | 24.2 | 17.4 | - +----------------------------+-------+---------+---------+ - | UDP 发送数据吞吐量 (Mbit/s)| 40.6 | 38.9 | 34.1 | - +----------------------------+-------+---------+---------+ - | UDP 接收数据吞吐量 (Mbit/s)| 52.4 | 44.5 | 44.2 | - +----------------------------+-------+---------+---------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 15 + + * - 等级 + - Iperf + - 默认 + - 最小 + * - 可用内存 (KB) + - 59 + - 160 + - 180 + * - WIFI_STATIC_RX_BUFFER_NUM + - 20 + - 8 + - 3 + * - WIFI_DYNAMIC_RX_BUFFER_NUM + - 40 + - 16 + - 6 + * - WIFI_DYNAMIC_TX_BUFFER_NUM + - 40 + - 16 + - 6 + * - WIFI_RX_BA_WIN + - 32 + - 16 + - 6 + * - TCP_SND_BUF_DEFAULT (KB) + - 40 + - 16 + - 6 + * - TCP_WND_DEFAULT (KB) + - 40 + - 16 + - 6 + * - LWIP_IRAM_OPTIMIZATION + - 13 + - 13 + - 0 + * - TCP 发送数据吞吐量 (Mbit/s) + - 38.1 + - 27.2 + - 20.4 + * - TCP 接收数据吞吐量 (Mbit/s) + - 35.3 + - 24.2 + - 17.4 + * - UDP 发送数据吞吐量 (Mbit/s) + - 40.6 + - 38.9 + - 34.1 + * - UDP 接收数据吞吐量 (Mbit/s) + - 52.4 + - 44.5 + - 44.2 + +.. only:: esp32 or esp32s2 .. note:: 以上结果由使用华硕RT-N66U路由器,在屏蔽箱中进行单流测试得出。{IDF_TARGET_NAME} 的 CPU 为双核,频率为 240 MHz,flash 为 QIO 模式,频率为 80 MHz。 - .. only:: esp32 **等级:** @@ -1974,81 +2266,190 @@ Wi-Fi 使用的堆内存峰值是 Wi-Fi 驱动程序 **理论上消耗的最大 .. only:: esp32 - +----------------------------+-------+-------+----------+-------+ - | 等级 | Iperf | 默认 | 节省内存 | 最小 | - +----------------------------+-------+-------+----------+-------+ - | 可用内存 (KB) | 113.8 | 152.4 | 181.2 | 202.6 | - +----------------------------+-------+-------+----------+-------+ - | WIFI_STATIC_RX_BUFFER_NUM | 16 | 8 | 4 | 2 | - +----------------------------+-------+-------+----------+-------+ - | WIFI_DYNAMIC_RX_BUFFER_NUM | 128 | 128 | 128 | 128 | - +----------------------------+-------+-------+----------+-------+ - | WIFI_STATIC_TX_BUFFER_NUM | 16 | 8 | 4 | 2 | - +----------------------------+-------+-------+----------+-------+ - | WIFI_RX_BA_WIN | 16 | 16 | 8 | 禁用 | - +----------------------------+-------+-------+----------+-------+ - | TCP_SND_BUF_DEFAULT (KB) | 65 | 65 | 65 | 65 | - +----------------------------+-------+-------+----------+-------+ - | TCP_WND_DEFAULT (KB) | 65 | 65 | 65 | 65 | - +----------------------------+-------+-------+----------+-------+ - | WIFI_IRAM_OPT | 15 | 15 | 15 | 0 | - +----------------------------+-------+-------+----------+-------+ - | WIFI_RX_IRAM_OPT | 16 | 16 | 0 | 0 | - +----------------------------+-------+-------+----------+-------+ - | LWIP_IRAM_OPTIMIZATION | 13 | 0 | 0 | 0 | - +----------------------------+-------+-------+----------+-------+ - | TCP 发送数据吞吐量 (Mbit/s)| 37.5 | 31.7 | 21.7 | 14.6 | - +----------------------------+-------+-------+----------+-------+ - | TCP 接收数据吞吐量 (Mbit/s)| 31.5 | 29.8 | 26.5 | 21.1 | - +----------------------------+-------+-------+----------+-------+ - | UDP 发送数据吞吐量 (Mbit/s)| 69.1 | 31.5 | 27.1 | 24.1 | - +----------------------------+-------+-------+----------+-------+ - | UDP 接收数据吞吐量 (Mbit/s)| 40.1 | 38.5 | 37.5 | 36.9 | - +----------------------------+-------+-------+----------+-------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 10 15 + + * - 等级 + - Iperf + - 默认 + - 节省内存 + - 最小 + * - 可用内存 (KB) + - 113.8 + - 152.4 + - 181.2 + - 202.6 + * - WIFI_STATIC_RX_BUFFER_NUM + - 16 + - 8 + - 4 + - 2 + * - WIFI_DYNAMIC_RX_BUFFER_NUM + - 128 + - 128 + - 128 + - 128 + * - WIFI_STATIC_TX_BUFFER_NUM + - 16 + - 8 + - 4 + - 2 + * - WIFI_RX_BA_WIN + - 16 + - 16 + - 8 + - 禁用 + * - TCP_SND_BUF_DEFAULT (KB) + - 65 + - 65 + - 65 + - 65 + * - TCP_WND_DEFAULT (KB) + - 65 + - 65 + - 65 + - 65 + * - WIFI_IRAM_OPT + - 15 + - 15 + - 15 + - 0 + * - WIFI_RX_IRAM_OPT + - 16 + - 16 + - 0 + - 0 + * - LWIP_IRAM_OPTIMIZATION + - 13 + - 0 + - 0 + - 0 + * - TCP 发送数据吞吐量 (Mbit/s) + - 37.5 + - 31.7 + - 21.7 + - 14.6 + * - TCP 接收数据吞吐量 (Mbit/s) + - 31.5 + - 29.8 + - 26.5 + - 21.1 + * - UDP 发送数据吞吐量 (Mbit/s) + - 69.1 + - 31.5 + - 27.1 + - 24.1 + * - UDP 接收数据吞吐量 (Mbit/s) + - 40.1 + - 38.5 + - 37.5 + - 36.9 .. only:: esp32s2 - +----------------------------+-------+------+----------+-------+ - | 等级 | Iperf | 默认 | 节省内存 | 最小 | - +----------------------------+-------+------+----------+-------+ - | 可用内存 (KB) | 70.6 | 96.4 | 118.8 | 148.2 | - +----------------------------+-------+------+----------+-------+ - | WIFI_STATIC_RX_BUFFER_NUM | 8 | 8 | 6 | 4 | - +----------------------------+-------+------+----------+-------+ - | WIFI_DYNAMIC_RX_BUFFER_NUM | 64 | 64 | 64 | 64 | - +----------------------------+-------+------+----------+-------+ - | WIFI_STATIC_TX_BUFFER_NUM | 16 | 8 | 6 | 4 | - +----------------------------+-------+------+----------+-------+ - | WIFI_RX_BA_WIN | 16 | 6 | 6 | 禁用 | - +----------------------------+-------+------+----------+-------+ - | TCP_SND_BUF_DEFAULT (KB) | 32 | 32 | 32 | 32 | - +----------------------------+-------+------+----------+-------+ - | TCP_WND_DEFAULT (KB) | 32 | 32 | 32 | 32 | - +----------------------------+-------+------+----------+-------+ - | WIFI_IRAM_OPT | 15 | 15 | 15 | 0 | - +----------------------------+-------+------+----------+-------+ - | WIFI_RX_IRAM_OPT | 16 | 16 | 0 | 0 | - +----------------------------+-------+------+----------+-------+ - | LWIP_IRAM_OPTIMIZATION | 13 | 0 | 0 | 0 | - +----------------------------+-------+------+----------+-------+ - | INSTRUCTION_CACHE | 16 | 16 | 16 | 8 | - +----------------------------+-------+------+----------+-------+ - | INSTRUCTION_CACHE_LINE | 16 | 16 | 16 | 16 | - +----------------------------+-------+------+----------+-------+ - | DATA_CACHE | 8 | 8 | 8 | 8 | - +----------------------------+-------+------+----------+-------+ - | DATA_CACHE_LINE | 32 | 32 | 32 | 32 | - +----------------------------+-------+------+----------+-------+ - | TCP 发送数据吞吐量 (Mbit/s)| 40.1 | 29.2 | 20.1 | 8.9 | - +----------------------------+-------+------+----------+-------+ - | TCP 接收数据吞吐量 (Mbit/s)| 21.9 | 16.8 | 14.8 | 9.6 | - +----------------------------+-------+------+----------+-------+ - | UDP 发送数据吞吐量 (Mbit/s)| 50.1 | 25.7 | 22.4 | 10.2 | - +----------------------------+-------+------+----------+-------+ - | UDP 接收数据吞吐量 (Mbit/s)| 45.3 | 43.1 | 28.5 | 15.1 | - +----------------------------+-------+------+----------+-------+ + .. list-table:: + :header-rows: 1 + :widths: 10 10 10 10 15 + * - 等级 + - Iperf + - 默认 + - 节省内存 + - 最小 + * - 可用内存 (KB) + - 70.6 + - 96.4 + - 118.8 + - 148.2 + * - WIFI_STATIC_RX_BUFFER_NUM + - 8 + - 8 + - 6 + - 4 + * - WIFI_DYNAMIC_RX_BUFFER_NUM + - 64 + - 64 + - 64 + - 64 + * - WIFI_STATIC_TX_BUFFER_NUM + - 16 + - 8 + - 6 + - 4 + * - WIFI_RX_BA_WIN + - 16 + - 6 + - 6 + - 禁用 + * - TCP_SND_BUF_DEFAULT (KB) + - 32 + - 32 + - 32 + - 32 + * - TCP_WND_DEFAULT (KB) + - 32 + - 32 + - 32 + - 32 + * - WIFI_IRAM_OPT + - 15 + - 15 + - 15 + - 0 + * - WIFI_RX_IRAM_OPT + - 16 + - 16 + - 0 + - 0 + * - LWIP_IRAM_OPTIMIZATION + - 13 + - 0 + - 0 + - 0 + * - INSTRUCTION_CACHE + - 16 + - 16 + - 16 + - 8 + * - INSTRUCTION_CACHE_LINE + - 16 + - 16 + - 16 + - 16 + * - DATA_CACHE + - 8 + - 8 + - 8 + - 8 + * - DATA_CACHE_LINE + - 32 + - 32 + - 32 + - 32 + * - TCP 发送数据吞吐量 (Mbit/s) + - 40.1 + - 29.2 + - 20.1 + - 8.9 + * - TCP 接收数据吞吐量 (Mbit/s) + - 21.9 + - 16.8 + - 14.8 + - 9.6 + * - UDP 发送数据吞吐量 (Mbit/s) + - 50.1 + - 25.7 + - 22.4 + - 10.2 + * - UDP 接收数据吞吐量 (Mbit/s) + - 45.3 + - 43.1 + - 28.5 + - 15.1 + .. note:: + 达到性能的峰值可能会触发任务看门狗,由于 CPU 可能没有时间处理低优先级的任务,这是一个正常现象。 Wi-Fi Menuconfig ----------------------- @@ -2134,44 +2535,58 @@ Wi-Fi 缓冲区配置 下表是 Wi-Fi 内部缓冲区的配置情况。 -+------------------------+----------+-----------------+------------+---------------------------------------------------------------+ -| 缓冲区类型 | 分配类型 | 默认 | 是否可配置 | 描述 | -+========================+==========+=================+============+===============================================================+ -| 静态接收数据缓冲区 | 静态 | 10 * 1600 Bytes | 是 | 这是一种 DMA 内存,在函数 :cpp:func:`esp_wifi_init()` | -| | | | | 中初始化,在函数 :cpp:func:`esp_wifi_deinit()` 中释放。 | -| (硬件接收数据缓冲区) | | | | 该缓冲区形成硬件接收列表。当通过空中接收到一个帧时,硬件将 | -| | | | | 该帧写入缓冲区,并向 CPU 发起一个中断。然后,Wi-Fi 驱动程 | -| | | | | 序从缓冲区中读取内容,并将缓冲区返回到列表中。 如果应用程序 | -| | | | | 希望减少 Wi-Fi 静态分配的内存,可以将该值从 10 减少到 6, | -| | | | | 从而节省 6400 Bytes 的内存。除非禁用 AMPDU 功能,否则不 | -| | | | | 建议将该值降低到 6 以下。 | -+------------------------+----------+-----------------+------------+---------------------------------------------------------------+ -| 动态接收数据缓冲区 | 动态 | 32 | 是 | 缓冲区的长度可变,取决于所接收帧的长度。当 Wi-Fi 驱动程序 | -| | | | | 从“硬件接收数据缓冲区”接收到一帧时,需要从堆中分配“动态接收 | -| | | | | 数据缓冲区”。在 Menuconfig 中配置的“动态接收数据缓冲区” | -| | | | | 数量用来限制未释放的“动态接收数据缓冲区”总数量。 | -+------------------------+----------+-----------------+------------+---------------------------------------------------------------+ -| 动态发送数据缓冲区 | 动态 | 32 | 是 | 这是一种DMA内存,位于堆内存中。当上层 (LwIP) 向 Wi-Fi | -| | | | | 驱动程序发送数据包时,该缓冲区首先分配一个“动态发送数据缓 | -| | | | | 冲区”,并复制上层缓冲区。动态发送数据缓冲区和静态发送数据 | -| | | | | 缓冲区相互排斥。 | -+------------------------+----------+-----------------+------------+---------------------------------------------------------------+ -| 静态发送数据缓冲区 | 静态 | 16 * 1600 Bytes | 是 | 这是一种 DMA 内存,在函数 :cpp:func:`esp_wifi_init()` | -| | | | | 中初始化,在函数 :cpp:func:`esp_wifi_deinit()` 中释放。 | -| | | | | 当上层 (LwIP) 向 Wi-Fi 驱动程序发送数据包时,该缓冲区首先 | -| | | | | 分配一个“静态发送数据缓冲区”,并复制上层缓冲区。动态发送数据 | -| | | | | 缓冲区和静态发送数据缓冲区相互排斥。由于发送数据缓冲区必须是 | -| | | | | DMA 缓冲区,所以当使能 PSRAM 时,发送数据缓冲区必须是静态 | -| | | | | 的。 | -+------------------------+----------+-----------------+------------+---------------------------------------------------------------+ -| 管理短缓冲区 | 动态 | 8 | 否 | Wi-Fi 驱动程序的内部缓冲区。 | -+------------------------+----------+-----------------+------------+---------------------------------------------------------------+ -| 管理长缓冲区 | 动态 | 32 | 否 | Wi-Fi 驱动程序的内部缓冲区。 | -+------------------------+----------+-----------------+------------+---------------------------------------------------------------+ -| 管理超长缓冲区 | 动态 | 32 | 否 | Wi-Fi 驱动程序的内部缓冲区。 | -+------------------------+----------+-----------------+------------+---------------------------------------------------------------+ +.. list-table:: + :header-rows: 1 + :widths: 10 10 10 10 25 + * - 缓冲区类型 + - 分配类型 + - 默认 + - 是否可配置 + - 描述 + * - 静态接收数据缓冲区(硬件接收数据缓冲区) + - 静态 + - 10 * 1600 Bytes + - 是 + - 这是一种 DMA 内存,在函数 :cpp:func:`esp_wifi_init()` 中初始化,在函数 :cpp:func:`esp_wifi_deinit()` 中释放。 该缓冲区形成硬件接收列表。当通过空中接收到一个帧时,硬件将该帧写入缓冲区,并向 CPU 发起一个中断。然后,Wi-Fi 驱动程序从缓冲区中读取内容,并将缓冲区返回到列表中。 + 如果应用程序希望减少 Wi-Fi 静态分配的内存,可以将该值从 10 减少到 6, 从而节省 6400 Bytes 的内存。除非禁用 AMPDU 功能,否则不建议将该值降低到 6 以下。 + * - 动态接收数据缓冲区 + - 动态 + - 32 + - 是 + - 缓冲区的长度可变,取决于所接收帧的长度。当 Wi-Fi 驱动程序 从“硬件接收数据缓冲区”接收到一帧时,需要从堆中分配“动态接收数据缓冲区”。在 Menuconfig 中配置的“动态接收数据缓冲区” 数量用来限制未释放的“动态接收数据缓冲区”总数量。 + * - 动态发送数据缓冲区 + - 动态 + - 32 + - 是 + - 这是一种 DMA 内存,位于堆内存中。当上层 (LwIP) 向 Wi-Fi 驱动程序发送数据包时,该缓冲区首先分配一个“动态发送数据缓 冲区”,并复制上层缓冲区。 + + 动态发送数据缓冲区和静态发送数据缓冲区相互排斥。 + * - 静态发送数据缓冲区 + - 静态 + - 16 * 1600 Bytes + - 是 + - 这是一种 DMA 内存,在函数 :cpp:func:`esp_wifi_init()` 中初始化,在函数 :cpp:func:`esp_wifi_deinit()` 中释放。 当上层 (LwIP) 向 Wi-Fi 驱动程序发送数据包时,该缓冲区首先 分配一个“静态发送数据缓冲区”,并复制上层缓冲区。 + + 动态发送数据缓冲区和静态发送数据缓冲区相互排斥。 + + 由于发送数据缓冲区必须是 DMA 缓冲区,所以当使能 PSRAM 时,发送数据缓冲区必须是静态的。 + * - 管理短缓冲区 + - 动态 + - 8 + - 否 + - Wi-Fi 驱动程序的内部缓冲区。 + * - 管理长缓冲区 + - 动态 + - 32 + - 否 + - Wi-Fi 驱动程序的内部缓冲区。 + * - 管理超长缓冲区 + - 动态 + - 32 + - 否 + - Wi-Fi 驱动程序的内部缓冲区。 Wi-Fi NVS Flash +++++++++++++++++++++ diff --git a/docs/zh_CN/api-reference/storage/nvs_flash.rst b/docs/zh_CN/api-reference/storage/nvs_flash.rst index c4dbb5ce62..2747f1cd61 100644 --- a/docs/zh_CN/api-reference/storage/nvs_flash.rst +++ b/docs/zh_CN/api-reference/storage/nvs_flash.rst @@ -11,9 +11,9 @@ 底层存储 ^^^^^^^^^^^^^^^^^^ -NVS 通过调用 ``spi_flash_{read|write|erase}`` API 对主 flash 的部分空间进行读、写、擦除操作,包括 ``data`` 类型和 ``nvs`` 子类型的所有分区。应用程序可调用 ``nvs_open`` API 选择使用带有 ``nvs`` 标签的分区,也可以通过调用 ``nvs_open_from_part`` API 选择使用指定名称的任意分区。 +NVS 库通过调用 :ref:`esp_partition ` API 使用主 flash 的部分空间,即类型为 ``data`` 且子类型为 ``nvs`` 的所有分区。应用程序可调用 :cpp:func:`nvs_open` API 选择使用带有 ``nvs`` 标签的分区,也可以通过调用 :cpp:func:`nvs_open_from_partition` API 选择使用指定名称的任意分区。 -NVS 库后续版本可能会增加其他存储器后端,实现将数据保存至其他 flash 芯片(SPI 或 I2C 接口)、RTC 或 FRAM 中。 +NVS 库后续版本可能会增加其他存储器后端,来将数据保存至其他 flash 芯片(SPI 或 I2C 接口)、RTC 或 FRAM 中。 .. note:: 如果 NVS 分区被截断(例如,更改分区表布局时),则应擦除分区内容。可以使用 ESP-IDF 构建系统中的 ``idf.py erase_flash`` 命令擦除 flash 上的所有内容。 @@ -23,15 +23,15 @@ NVS 库后续版本可能会增加其他存储器后端,实现将数据保存 键值对 ^^^^^^^^^^^^^^^ -NVS 的操作对象为键值对,其中键是 ASCII 字符串,当前支持最大键长为 15 个字符,值可以为以下几种类型: +NVS 的操作对象为键值对,其中键是 ASCII 字符串,当前支持的最大键长为 15 个字符。值可以为以下几种类型: - 整数型:``uint8_t``、``int8_t``、``uint16_t``、``int16_t``、``uint32_t``、``int32_t``、``uint64_t`` 和 ``int64_t``; -- 以 ``\0`` 结尾的字符串; +- 以 0 结尾的字符串; - 可变长度的二进制数据 (BLOB) .. note:: - 字符串值当前上限为 4000 字节,其中包括空终止符。BLOB 值上限为 508,000 字节或分区大小减去 4000 字节的 97.6%,以较低值为准。 + 字符串值当前上限为 4000 字节,其中包括空终止符。BLOB 值上限为 508,000 字节或分区大小的 97.6% 减去 4000 字节,以较低值为准。 后续可能会增加对 ``float`` 和 ``double`` 等其他类型数据的支持。 @@ -46,19 +46,139 @@ NVS 的操作对象为键值对,其中键是 ASCII 字符串,当前支持最 命名空间 ^^^^^^^^^^ -为了减少不同组件之间键名的潜在冲突,NVS 将每个键值对分配给一个命名空间。命名空间的命名规则遵循键名的命名规则,即最多可占 15 个字符。命名空间的名称在调用 ``nvs_open`` 或 ``nvs_open_from_part`` 中指定,调用后将返回一个不透明句柄,用于后续调用 ``nvs_get_*``、``nvs_set_*`` 和 ``nvs_commit`` 函数。这样,一个句柄关联一个命名空间,键名便不会与其他命名空间中相同键名冲突。请注意,不同 NVS 分区中具有相同名称的命名空间将被视为不同的命名空间。 +为了减少不同组件之间键名的潜在冲突,NVS 将每个键值对分配给一个命名空间。命名空间的命名规则遵循键名的命名规则,例如,最多可占 15 个字符。命名空间的名称在调用 :cpp:func:`nvs_open` 或 :cpp:type:`nvs_open_from_partition` 中指定,调用后将返回一个不透明句柄,用于后续调用 ``nvs_get_*``、``nvs_set_*`` 和 ``nvs_commit`` 函数。这样,一个句柄关联一个命名空间,键名便不会与其他命名空间中相同键名冲突。请注意,不同 NVS 分区中具有相同名称的命名空间将被视为不同的命名空间。 + +NVS 迭代器 +^^^^^^^^^^^^^ + +迭代器允许根据指定的分区名称、命名空间和数据类型轮询 NVS 中存储的键值对。 + +您可以使用以下函数,执行相关操作: + +- ``nvs_entry_find``:返回一个不透明句柄,用于后续调用 ``nvs_entry_next`` 和 ``nvs_entry_info`` 函数; +- ``nvs_entry_next``:返回指向下一个键值对的迭代器; +- ``nvs_entry_info``:返回每个键值对的信息。 + +如果未找到符合标准的键值对,``nvs_entry_find`` 和 ``nvs_entry_next`` 将返回 NULL,此时不必释放迭代器。若不再需要迭代器,可使用 ``nvs_release_iterator`` 释放迭代器。 安全性、篡改性及鲁棒性 ^^^^^^^^^^^^^^^^^^^^^^^^^^ -NVS 与 ESP32 flash 加密系统不直接兼容。但如果 NVS 加密与 ESP32 flash 加密一起使用时,数据仍可以加密形式存储。更多详情请参阅 :ref:`nvs_encryption`。 +NVS 与 {IDF_TARGET_NAME} flash 加密系统不直接兼容。但如果 NVS 加密与 {IDF_TARGET_NAME} flash 加密一起使用时,数据仍可以加密形式存储。详情请参阅 :ref:`nvs_encryption`。 -如果未启用 NVS 加密,任何对 flash 芯片有物理访问权限的人都可以修改、擦除或添加键值对。NVS 加密启用后,如果不知道相应的 NVS 加密密钥,则无法修改或添加键值对并将其识别为有效键值。但是,针对擦除操作没有相应的防篡改功能。 +如果未启用 NVS 加密,任何对 flash 芯片有物理访问权限的用户都可以修改、擦除或添加键值对。NVS 加密启用后,如果不知道相应的 NVS 加密密钥,则无法修改或添加键值对并将其识别为有效键值对。但是,针对擦除操作没有相应的防篡改功能。 当 flash 处于不一致状态时,NVS 库会尝试恢复。在任何时间点关闭设备电源,然后重新打开电源,不会导致数据丢失;但如果关闭设备电源时正在写入新的键值对,这一键值对可能会丢失。该库还应当能对 flash 中的任意数据进行正确初始化。 +.. _nvs_encryption: + +NVS 加密 +-------------- + +NVS 分区内存储的数据可使用 AES-XTS 进行加密,类似于 IEEE P1619 磁盘加密标准中提到的加密方式。为了实现加密,每个条目被均视为一个扇区,并将条目相对地址(相对于分区开头)传递给加密算法,用作扇区号。可通过 :ref:`CONFIG_NVS_ENCRYPTION` 启用 NVS 加密。NVS 加密所需的密钥存储于其他分区,并且被 :doc:`Flash 加密 <../../security/flash-encryption>` 保护。因此,在使用 NVS 加密前应先启用 :doc:`Flash 加密 <../../security/flash-encryption>`。 + +启用 :doc:`Flash 加密 <../../security/flash-encryption>` 时,默认启用 NVS 加密。这是因为 Wi-Fi 驱动在默认的 NVS 分区中存储了凭证(如 SSID 和密码)。启用平台级加密后,仍需将它们作为默认选项进行加密。 + +使用 NVS 加密,分区表必须包含 :ref:`nvs_key_partition`。在分区表选项 (menuconfig->Partition Table) 下,为 NVS 加密提供了两个包含 :ref:`nvs_key_partition` 的分区表,您可以通过工程配置菜单 (``idf.py menuconfig``) 进行选择。请参考 :example:`security/flash_encryption` 中的例子,了解如何配置和使用 NVS 加密功能。 + +.. _nvs_key_partition: + +NVS 密钥分区 +^^^^^^^^^^^^^^^^^ + + 应用程序如果想使用 NVS 加密,则需要编译进一个类型为 `data`,子类型为 `key` 的密钥分区。该分区应标记为 `已加密` 且最小为 4096 字节。如需了解更多详细信息,请参考 :doc:`分区表 <../../api-guides/partition-tables>`。在分区表选项 (menuconfig->Partition Table) 下提供了两个包含 :ref:`nvs_key_partition` 的额外分区表,可以直接用于 :ref:`nvs_encryption`。这些分区的具体结构见下表: + +.. highlight:: none + +:: + + +-----------+--------------+-------------+----+ + | XTS encryption key (32) | + +---------------------------------------------+ + | XTS tweak key (32) | + +---------------------------------------------+ + | CRC32 (4) | + +---------------------------------------------+ + +可以通过以下两种方式生成 :ref:`nvs_key_partition` 中的 XTS 加密密钥: + +1. 在 ESP 芯片上生成密钥: + + 启用 NVS 加密时,可用 :cpp:func:`nvs_flash_init` API 函数来初始化加密的默认 NVS 分区,在内部生成 ESP 芯片上的 XTS 加密密钥。在找到 :ref:`nvs_key_partition` 后,API 函数利用 :component_file:`nvs_flash/include/nvs_flash.h` 提供的 :cpp:func:`nvs_flash_generate_keys` 函数,自动生成并存储该分区中的 NVS 密钥。只有当各自的密钥分区为空时,才会生成并存储新的密钥。可以借助 :cpp:func:`nvs_flash_secure_init_partition` 用同一个密钥分区来读取安全配置,以初始化一个定制的加密 NVS 分区。 + + API 函数 :cpp:func:`nvs_flash_secure_init` 和 :cpp:func:`nvs_flash_secure_init_partition` 不在内部产生密钥。当这些 API 函数用于初始化加密的 NVS 分区时,可以在启动后使用 `nvs_flash.h` 提供的 :cpp:func:`nvs_flash_generate_keys` API 函数生成密钥,以加密的形式把密钥写到密钥分区上。 + +2. 使用预先生成的密钥分区: + + 若 :ref:`nvs_key_partition` 中的密钥不是由应用程序生成,则需要使用预先生成的密钥分区。可以使用 :doc:`NVS 分区生成工具 ` 生成包含 XTS 加密密钥的 :ref:`nvs_key_partition`。用户可以借助以下两个命令,将预先生成的密钥分区储存在 flash 上: + + i) 建立并烧录分区表 + :: + + idf.py partition-table partition-table-flash + + ii) 调用 :component_file:`parttool.py`,将密钥存储在 flash 上的 :ref:`nvs_key_partition` 中。详见 :doc:` 分区表 ` 的分区工具部分。 + + + parttool.py --port /dev/ttyUSB0 --partition-table-offset "nvs_key partition offset" write_partition --partition-name="name of nvs_key partition" --input "nvs_key partition" + +由于分区已标记为 `已加密`,而且启用了 :doc:`Flash 加密 <../../security/flash-encryption>`,引导程序在首次启动时将使用 flash 加密对密钥分区进行加密。 + +应用程序可以使用不同的密钥对不同的 NVS 分区进行加密,这样就会需要多个加密密钥分区。应用程序应为加解密操作提供正确的密钥或密钥分区。 + +加密读取/写入 +^^^^^^^^^^^^^^^^^^^^ + +``nvs_get_*`` 和 ``nvs_set_*`` 等 NVS API 函数同样可以对 NVS 加密分区执行读写操作。 + +**加密默认的 NVS 分区:** +无需额外步骤即可启用默认 NVS 分区的加密。启用 :ref:`CONFIG_NVS_ENCRYPTION` 时, :cpp:func:`nvs_flash_init` API 函数会在内部使用找到的第一个 :ref:`nvs_key_partition` 执行额外步骤,以启用默认 NVS 分区的加密(详情请参考 API 文档)。另外,:cpp:func:`nvs_flash_secure_init` API 函数也可以用来启用默认 NVS 分区的加密。 + +**加密一个自定义的 NVS 分区:** +使用 :cpp:func:`nvs_flash_secure_init_partition` API 函数启用自定义 NVS 分区的加密,而非 :cpp:func:`nvs_flash_init_partition`。 + +使用 :cpp:func:`nvs_flash_secure_init` 和 :cpp:func:`nvs_flash_secure_init_partition` API 函数时,应用程序如需在加密状态下执行 NVS 读写操作,应遵循以下步骤: + + 1. 使用 ``esp_partition_find*`` API 查找密钥分区和 NVS 数据分区; + 2. 使用 ``nvs_flash_read_security_cfg`` 或 ``nvs_flash_generate_keys`` API 填充 ``nvs_sec_cfg_t`` 结构; + 3. 使用 ``nvs_flash_secure_init`` 或 ``nvs_flash_secure_init_partition`` API 初始化 NVS flash 分区; + 4. 使用 ``nvs_open`` 或 ``nvs_open_from_partition`` API 打开命名空间; + 5. 使用 ``nvs_get_*`` 或 ``nvs_set_*`` API 执行 NVS 读取/写入操作; + 6. 使用 ``nvs_flash_deinit`` API 释放已初始化的 NVS 分区。 + +NVS 分区生成程序 +------------------ + +NVS 分区生成程序帮助生成 NVS 分区二进制文件,可使用烧录程序将二进制文件单独烧录至特定分区。烧录至分区上的键值对由 CSV 文件提供,详情请参考 :doc:`NVS 分区生成程序 `。 + +应用示例 +------------------- + +ESP-IDF :example:`storage` 目录下提供了数个代码示例: + +:example:`storage/nvs_rw_value` + + 演示如何读取及写入 NVS 单个整数值。 + + 此示例中的值表示 {IDF_TARGET_NAME} 模组重启次数。NVS 中数据不会因为模组重启而丢失,因此只有将这一值存储于 NVS 中,才能起到重启次数计数器的作用。 + + 该示例也演示了如何检测读取/写入操作是否成功,以及某个特定值是否在 NVS 中尚未初始化。诊断程序以纯文本形式提供,帮助您追踪程序流程,及时发现问题。 + +:example:`storage/nvs_rw_blob`  + + 演示如何读取及写入 NVS 单个整数值和 Blob(二进制大对象),并在 NVS 中存储这一数值,即便 {IDF_TARGET_NAME} 模组重启也不会消失。 + + * value - 记录 {IDF_TARGET_NAME} 模组软重启次数和硬重启次数。 + * blob - 内含记录模组运行次数的表格。此表格将被从 NVS 读取至动态分配的 RAM 上。每次手动软重启后,表格内运行次数即增加一次,新加的运行次数被写入 NVS。下拉 GPIO0 即可手动软重启。 + + 该示例也演示了如何执行诊断程序以检测读取/写入操作是否成功。 + +:example:`storage/nvs_rw_value_cxx` + + 这个例子与 :example:`storage/nvs_rw_value` 完全一样,只是使用了 C++ 的 NVS 处理类。 + 内部实现 --------- @@ -70,7 +190,7 @@ NVS 按顺序存储键值对,新的键值对添加在最后。因此,如需 页面和条目 ^^^^^^^^^^^^^^^^^ -NVS 库在其操作中主要使用两个实体:页面和条目。页面是一个逻辑结构,用于存储部分的整体日志。逻辑页面对应 flash 的一个物理扇区,正在使用中的页面具有与之相关联的序列号。序列号赋予了页面顺序,较高的序列号对应较晚创建的页面。页面有以下几种状态: +NVS 库在其操作中主要使用两个实体:页面和条目。页面是一个逻辑结构,用于存储部分的整体日志。逻辑页面对应 flash 的一个物理扇区,正在使用中的页面具有与之相关联的 *序列号*。序列号赋予了页面顺序,较高的序列号对应较晚创建的页面。页面有以下几种状态: 空或未初始化 页面对应的 flash 扇区为空白状态(所有字节均为 ``0xff``)。此时,页面未存储任何数据且没有关联的序列号。 @@ -79,7 +199,8 @@ NVS 库在其操作中主要使用两个实体:页面和条目。页面是一 此时 flash 已完成初始化,页头部写入 flash,页面已具备有效序列号。页面中存在一些空条目,可写入数据。任意时刻,至多有一个页面处于活跃状态。 写满状态 - Flash 已写满键值对,状态不再改变。用户无法向写满状态下的页面写入新键值对,但仍可将一些键值对标记为已擦除。 + Flash 已写满键值对,状态不再改变。 + 用户无法向写满状态下的页面写入新键值对,但仍可将一些键值对标记为已擦除。 擦除状态 未擦除的键值对将移至其他页面,以便擦除当前页面。这一状态仅为暂时性状态,即 API 调用返回时,页面应脱离这一状态。如果设备突然断电,下次开机时,设备将继续把未擦除的键值对移至其他页面,并继续擦除当前页面。 @@ -106,11 +227,13 @@ Flash 扇区映射至逻辑页面并没有特定的顺序,NVS 库会检查存 页面结构 ^^^^^^^^^^^^^^^^^^^ -当前,我们假设 flash 扇区大小为 4096 字节,并且 ESP32 flash 加密硬件在 32 字节块上运行。未来有可能引入一些编译时可配置项(可通过 menuconfig 进行配置),以适配具有不同扇区大小的 flash 芯片。但目前尚不清楚 SPI flash 驱动和 SPI flash cache 之类的系统组件是否支持其他扇区大小。 +当前,我们假设 flash 扇区大小为 4096 字节,并且 {IDF_TARGET_NAME} flash 加密硬件在 32 字节块上运行。未来有可能引入一些编译时可配置项(可通过 menuconfig 进行配置),以适配具有不同扇区大小的 flash 芯片。但目前尚不清楚 SPI flash 驱动和 SPI flash cache 之类的系统组件是否支持其他扇区大小。 -页面由头部、条目状态位图和条目三部分组成。为了实现与 ESP32 flash 加密功能兼容,条目大小设置为 32 字节。如果键值为整数型,条目则保存一个键值对;如果键值为字符串或 BLOB 类型,则条目仅保存一个键值对的部分内容(更多信息详见条目结构描述)。 +页面由头部、条目状态位图和条目三部分组成。为了实现与 {IDF_TARGET_NAME} flash 加密功能兼容,条目大小设置为 32 字节。如果键值为整数型,条目则保存一个键值对;如果键值为字符串或 BLOB 类型,则条目仅保存一个键值对的部分内容(更多信息详见条目结构描述)。 -页面结构如下图所示,括号内数字表示该部分的大小(以字节为单位):: +页面结构如下图所示,括号内数字表示该部分的大小(以字节为单位)。 + +:: +-----------+--------------+-------------+-------------------------+ | State (4) | Seq. no. (4) | version (1) | Unused (19) | CRC32 (4) | 页头部 (32) @@ -127,15 +250,15 @@ Flash 扇区映射至逻辑页面并没有特定的顺序,NVS 库会检查存 | Entry 125 (32) | +------------------------------------------------------------------+ -头部和条目状态位图写入 flash 时不加密。如果启用了 ESP32 flash 加密功能,则条目写入 flash 时将会加密。 +头部和条目状态位图写入 flash 时不加密。如果启用了 {IDF_TARGET_NAME} flash 加密功能,则条目写入 flash 时将会加密。 -通过将 0 写入某些位可以定义页面状态值,表示状态改变。因此,如果需要变更页面状态,并不一定要擦除页面,除非要将其变更为擦除状态。 +通过将 0 写入某些位可以定义页面状态值,表示状态改变。因此,如果需要变更页面状态,并不一定要擦除页面,除非要将其变更为 *擦除* 状态。 -头部中的 ``version`` 字段反映了所用的 NVS 格式版本。为实现向后兼容,版本升级从 0xff 开始依次递减(例如,version-1 为 0xff,version-2 为 0xfe 等)。 +头部中的 ``version`` 字段反映了所用的 NVS 格式版本。为实现向后兼容,版本升级从 0xff 开始依次递减(例如,version-1 为 0xff,version-2 为 0xfe,以此类推)。 头部中 CRC32 值是由不包含状态值的条目计算所得(4 到 28 字节)。当前未使用的条目用 ``0xff`` 字节填充。 -条目结构和条目状态位图详细信息见下文描述。 +条目结构和条目状态位图的详细信息见下文描述。 条目和条目状态位图 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -151,6 +274,7 @@ Flash 扇区映射至逻辑页面并没有特定的顺序,NVS 库会检查存 擦除(2'b00) 条目中的键值对已丢弃,条目内容不再解析。 + .. _structure_of_entry: 条目结构 @@ -167,12 +291,12 @@ Flash 扇区映射至逻辑页面并没有特定的顺序,NVS 库会检查存 Primitive +--------------------------------+ +--------> | Data (8) | | Types +--------------------------------+ - +-> Fixed length -- + +-> Fixed length -- | | +---------+--------------+---------------+-------+ | +--------> | Size(4) | ChunkCount(1)| ChunkStart(1) | Rsv(2)| Data format ---+ BLOB Index +---------+--------------+---------------+-------+ | - | +----------+---------+-----------+ + | +----------+---------+-----------+ +-> Variable length --> | Size (2) | Rsv (2) | CRC32 (4) | (Strings, BLOB Data) +----------+---------+-----------+ @@ -180,10 +304,10 @@ Flash 扇区映射至逻辑页面并没有特定的顺序,NVS 库会检查存 条目结构中各个字段含义如下: 命名空间 (NS, NameSpace) - 该条目的命名空间索引,详细信息见命名空间实现章节。 + 该条目的命名空间索引,详细信息参见命名空间实现章节。 类型 (Type) - 一个字节表示的值的数据类型,可能的类型见 ``nvs_types.h`` 中 ``ItemType`` 枚举。 + 一个字节表示的值的数据类型,:component_file:`nvs_flash/include/nvs_handle.hpp` 下的 :cpp:type:`ItemType` 枚举了可能的类型。 跨度 (Span) 该键值对所用的条目数量。如果键值为整数型,条目数量即为 1。如果键值为字符串或 BLOB,则条目数量取决于值的长度。 @@ -192,10 +316,10 @@ Flash 扇区映射至逻辑页面并没有特定的顺序,NVS 库会检查存 用于存储 BLOB 类型数据块的索引。如果键值为其他数据类型,则此处索引应写入 ``0xff``。 CRC32 - 对条目下所有字节进行校验,所得的校验和(CRC32 字段不计算在内)。 + 对条目下所有字节进行校验后,所得的校验和(CRC32 字段不计算在内)。 键 (Key) - 即以零结尾的 ASCII 字符串,字符串最长为 15 字节,不包含最后一个字节的 NULL (``\0``) 终止符。 + 即以零结尾的 ASCII 字符串,字符串最长为 15 字节,不包含最后一个字节的零终止符。 数据 (Data) 如果键值类型为整数型,则数据字段仅包含键值。如果键值小于八个字节,使用 ``0xff`` 填充未使用的部分(右侧)。 @@ -205,21 +329,22 @@ CRC32 - 块大小 整个 BLOB 数据的大小(以字节为单位)。该字段仅用于 BLOB 索引类型条目。 - - ChunkCount - 存储过程中 BLOB 分成的数据块数量。该字段仅用于 BLOB 索引类型条目。 - - - ChunkStart + - ChunkCount + 存储过程中 BLOB 分成的数据块总量。该字段仅用于 BLOB 索引类型条目。 + + - ChunkStart BLOB 第一个数据块的块索引,后续数据块索引依次递增,步长为 1。该字段仅用于 BLOB 索引类型条目。 如果键值类型为字符串或 BLOB 数据块,数据字段的这八个字节将保存该键值的一些附加信息,如下所示: - + - 数据大小 实际数据的大小(以字节为单位)。如果键值类型为字符串,此字段也应将零终止符包含在内。此字段仅用于字符串和 BLOB 类型条目。 - CRC32 数据所有字节的校验和,该字段仅用于字符串和 BLOB 类型条目。 -可变长度值(字符串和 BLOB)写入后续条目,每个条目 32 字节。第一个条目的 span 字段将指明使用了多少条目。 +可变长度值(字符串和 BLOB)写入后续条目,每个条目 32 字节。第一个条目的 `Span` 字段将指明使用了多少条目。 + 命名空间 ^^^^^^^^^^ @@ -246,89 +371,6 @@ CRC32 哈希列表中每个节点均包含一个 24 位哈希值和 8 位条目索引。哈希值根据条目命名空间、键名和块索引由 CRC32 计算所得,计算结果保留 24 位。为减少将 32 位条目存储在链表中的开销,链表采用了数组的双向链表。每个数组占用 128 个字节,包含 29 个条目、两个链表指针和一个 32 位计数字段。因此,每页额外需要的 RAM 最少为 128 字节,最多为 640 字节。 -.. _nvs_encryption: - -NVS 加密 --------------- - -NVS 分区内存储的数据可使用 AES-XTS 进行加密,类似于 IEEE P1619 磁盘加密标准中提到的加密方式。为了实现加密,每个条目被均视为一个扇区,并将条目相对地址(相对于分区开头)传递给加密算法,用作扇区号。NVS 加密所需的密钥存储于其他分区,并进行了 :doc:`flash 加密 <../../security/flash-encryption>`。因此,在使用 NVS 加密前应先启用 :doc:`flash 加密 <../../security/flash-encryption>`。 - -.. _nvs_key_partition: - -NVS 密钥分区 -^^^^^^^^^^^^^^^^^ - -应用程序如果想使用 NVS 加密,则需要编译进一个类型为 ``data``,子类型为 ``key`` 的密钥分区。该分区应标记为已加密,且最小为 4096 字节,具体结构见下表。如需了解更多详细信息,请参考 :doc:`分区表 <../../api-guides/partition-tables>`。 - -:: - - +-----------+--------------+-------------+----+ - | XTS encryption key(32) | - +---------------------------------------------+ - | XTS tweak key (32) | - +---------------------------------------------+ - | CRC32(4) | - +---------------------------------------------+ - -使用 NVS 分区生成程序生成上述分区表,并烧录至设备。由于分区已标记为已加密,而且启用了 :doc:`flash 加密 <../../security/flash-encryption>`,引导程序在首次启动时将使用 flash 加密对密钥分区进行加密。您也可以在设备启动后调用 ``nvs_flash.h`` 提供的 ``nvs_flash_generate_keys`` API 生成加密密钥,然后再将密钥以加密形式写入密钥分区。 - -应用程序可以使用不同的密钥对不同的 NVS 分区进行加密,这样就会需要多个加密密钥分区。应用程序应为加解密操作提供正确的密钥或密钥分区。 - -加密读取/写入 -^^^^^^^^^^^^^^^^^^^^ - -``nvs_get_*`` 和 ``nvs_set_*`` 等 NVS API 函数同样可以对 NVS 加密分区执行读写操作。但用于初始化 NVS 非加密分区和加密分区的 API 则有所不同:初始化 NVS 非加密分区可以使用 ``nvs_flash_init`` 和 ``nvs_flash_init_partition``,但初始化 NVS 加密分区则需调用 ``nvs_flash_secure_init`` 和 ``nvs_flash_secure_init_partition``。上述 API 函数所需的 ``nvs_sec_cfg_t`` 结构可使用 ``nvs_flash_generate_keys`` 或者 ``nvs_flash_read_security_cfg`` 进行填充。 - -应用程序如需在加密状态下执行 NVS 读写操作,应遵循以下步骤: - - 1. 使用 ``esp_partition_find*`` API 查找密钥分区和 NVS 数据分区; - 2. 使用 ``nvs_flash_read_security_cfg`` 或 ``nvs_flash_generate_keys`` API 填充 ``nvs_sec_cfg_t`` 结构; - 3. 使用 ``nvs_flash_secure_init`` 或 ``nvs_flash_secure_init_partition`` API 初始化 NVS flash 分区; - 4. 使用 ``nvs_open`` 或 ``nvs_open_from_part`` API 打开命名空间; - 5. 使用 ``nvs_get_*`` 或 ``nvs_set_*`` API 执行 NVS 读取/写入操作; - 6. 使用 ``nvs_flash_deinit`` API 释放已初始化的 NVS 分区。 - -NVS 迭代器 -^^^^^^^^^^^^^ - -迭代器允许根据指定的分区名称、命名空间和数据类型轮询 NVS 中存储的键值对。 - -您可以使用以下函数,执行相关操作: - -- ``nvs_entry_find``:返回一个不透明句柄,用于后续调用 ``nvs_entry_next`` 和 ``nvs_entry_info`` 函数; -- ``nvs_entry_next``:返回指向下一个键值对的迭代器; -- ``nvs_entry_info``:返回每个键值对的信息。 - -如果未找到符合标准的键值对,``nvs_entry_find`` 和 ``nvs_entry_next`` 将返回 NULL,此时不必释放迭代器。若不再需要迭代器,可使用 ``nvs_release_iterator`` 释放迭代器。 - -NVS 分区生成程序 ------------------- - -NVS 分区生成程序帮助生成 NVS 分区二进制文件,可使用烧录程序将二进制文件单独烧录至特定分区。烧录至分区上的键值对由 CSV 文件提供,详情请参考 :doc:`NVS 分区生成程序 `。 - -应用示例 -------------------- - -ESP-IDF :example:`storage` 目录下提供了两个代码示例: - -:example:`storage/nvs_rw_value` - - 演示如何读取及写入 NVS 单个整数值。 - - 此示例中的值表示 ESP32 模组重启次数。NVS 中数据不会因为模组重启而丢失,因此只有将这一值存储于 NVS 中,才能起到重启次数计数器的作用。 - - 该示例也演示了如何检测读取/写入操作是否成功,以及某个特定值是否在 NVS 中尚未初始化。诊断程序以纯文本形式提供,帮助您追踪程序流程,及时发现问题。 - -:example:`storage/nvs_rw_blob`  - - 演示如何读取及写入 NVS 单个整数值和 Blob(二进制大对象),并在 NVS 中存储这一数值,即便 ESP32 模组重启也不会消失。 - - * value - 记录 ESP32 模组软重启次数和硬重启次数。 - * blob - 内含记录模组运行次数的表格。此表格将被从 NVS 读取至动态分配的 RAM 上。每次手动软重启后,表格内运行次数即增加一次,新加的运行次数被写入 NVS。下拉 GPIO0 即可手动软重启。 - - 该示例也演示了如何执行诊断程序以检测读取/写入操作是否成功。 - - API 参考 -------------