mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-04 05:04:33 +02:00
Merge branch 'bugfix/nvs_idfgh_issue' into 'master'
feat(esp_wifi): Add example to write wifi config in nvs Closes IDFGH-13678 See merge request espressif/esp-idf!36693
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -37,6 +37,7 @@ components/**/build/
|
|||||||
components/**/build_*_*/
|
components/**/build_*_*/
|
||||||
components/**/sdkconfig
|
components/**/sdkconfig
|
||||||
components/**/sdkconfig.old
|
components/**/sdkconfig.old
|
||||||
|
components/**/test_apps/wifi_nvs_config/nvs_data_suffix.csv
|
||||||
|
|
||||||
# Example project files
|
# Example project files
|
||||||
examples/**/build/
|
examples/**/build/
|
||||||
|
@@ -3,3 +3,7 @@
|
|||||||
components/esp_wifi/test_apps/:
|
components/esp_wifi/test_apps/:
|
||||||
disable:
|
disable:
|
||||||
- if: SOC_WIFI_SUPPORTED != 1
|
- if: SOC_WIFI_SUPPORTED != 1
|
||||||
|
|
||||||
|
components/esp_wifi/test_apps/wifi_nvs_config:
|
||||||
|
disable:
|
||||||
|
- if: SOC_WIFI_SUPPORTED != 1
|
||||||
|
25
components/esp_wifi/test_apps/wifi_nvs_config/CMakeLists.txt
Normal file
25
components/esp_wifi/test_apps/wifi_nvs_config/CMakeLists.txt
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#This is the project CMakeLists.txt file for the test subproject
|
||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/unit-test-app/components")
|
||||||
|
|
||||||
|
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
|
||||||
|
set(COMPONENTS main)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
|
||||||
|
if($ENV{CI_PIPELINE_ID})
|
||||||
|
idf_build_set_property(COMPILE_DEFINITIONS TEST_SUFFIX_STR="_$ENV{CI_PIPELINE_ID}" APPEND)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(DEFINED ENV{CI_PIPELINE_ID})
|
||||||
|
set(TEST_SUFFIX_STR "_$ENV{CI_PIPELINE_ID}")
|
||||||
|
else()
|
||||||
|
string(TIMESTAMP TEST_SUFFIX_STR "%Y%m%d%H%M%S")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND python3 ${CMAKE_SOURCE_DIR}/update_csv_suffix.py ${TEST_SUFFIX_STR}
|
||||||
|
)
|
||||||
|
|
||||||
|
project(wifi_nvs_conn_test)
|
2
components/esp_wifi/test_apps/wifi_nvs_config/README.md
Normal file
2
components/esp_wifi/test_apps/wifi_nvs_config/README.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-S2 | ESP32-S3 |
|
||||||
|
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
@@ -0,0 +1,10 @@
|
|||||||
|
idf_component_register(SRC_DIRS .
|
||||||
|
PRIV_INCLUDE_DIRS . ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
PRIV_REQUIRES cmock test_utils nvs_flash esp_wifi esp_event
|
||||||
|
WHOLE_ARCHIVE)
|
||||||
|
|
||||||
|
# Create a NVS image from the contents of the `nvs_data` CSV file
|
||||||
|
# that fits the partition named 'nvs'. FLASH_IN_PROJECT indicates that
|
||||||
|
# the generated image should be flashed when the entire project is flashed to
|
||||||
|
# the target with 'idf.py -p PORT flash'.
|
||||||
|
nvs_create_partition_image(nvs ../nvs_data_suffix.csv FLASH_IN_PROJECT)
|
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
*/
|
||||||
|
#include "unity.h"
|
||||||
|
#include "nvs_flash.h"
|
||||||
|
#include "nvs.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_netif.h"
|
||||||
|
#include "esp_wifi.h"
|
||||||
|
|
||||||
|
#include "esp_heap_caps.h"
|
||||||
|
|
||||||
|
// Some resources are lazy allocated in wifi and lwip
|
||||||
|
#define TEST_MEMORY_LEAK_THRESHOLD (-1536)
|
||||||
|
|
||||||
|
static size_t before_free_8bit;
|
||||||
|
static size_t before_free_32bit;
|
||||||
|
|
||||||
|
static void check_leak(size_t before_free, size_t after_free, const char *type)
|
||||||
|
{
|
||||||
|
ssize_t delta = after_free - before_free;
|
||||||
|
printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta);
|
||||||
|
TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak");
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUp(void)
|
||||||
|
{
|
||||||
|
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||||
|
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
|
||||||
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||||
|
}
|
||||||
|
|
||||||
|
void tearDown(void)
|
||||||
|
{
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_deinit());
|
||||||
|
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||||
|
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
|
||||||
|
check_leak(before_free_8bit, after_free_8bit, "8BIT");
|
||||||
|
check_leak(before_free_32bit, after_free_32bit, "32BIT");
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_main(void)
|
||||||
|
{
|
||||||
|
ESP_ERROR_CHECK(nvs_flash_init());
|
||||||
|
ESP_ERROR_CHECK(esp_netif_init());
|
||||||
|
unity_run_menu();
|
||||||
|
ESP_ERROR_CHECK(esp_netif_deinit());
|
||||||
|
ESP_ERROR_CHECK(nvs_flash_deinit());
|
||||||
|
}
|
@@ -0,0 +1,219 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
*
|
||||||
|
* This test code is in the Public Domain (or CC0 licensed, at your option.)
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, this
|
||||||
|
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
* CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "unity.h"
|
||||||
|
#include "esp_mac.h"
|
||||||
|
#include "esp_event.h"
|
||||||
|
#include "esp_wifi.h"
|
||||||
|
#include "esp_wifi_types.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "nvs_flash.h"
|
||||||
|
#include "test_utils.h"
|
||||||
|
#include "memory_checks.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/event_groups.h"
|
||||||
|
|
||||||
|
#define CONNECT_TIMEOUT_MS (10000)
|
||||||
|
|
||||||
|
#define GOT_IP_EVENT (1)
|
||||||
|
#define WIFI_DISCONNECT_EVENT (1<<1)
|
||||||
|
#define WIFI_STA_CONNECTED (1<<2)
|
||||||
|
#define WIFI_AP_STA_CONNECTED (1<<3)
|
||||||
|
|
||||||
|
#define EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT 0x00000001
|
||||||
|
|
||||||
|
static uint32_t wifi_event_handler_flag;
|
||||||
|
static const char* TAG = "test_wifi";
|
||||||
|
static esp_netif_t* s_ap_netif = NULL;
|
||||||
|
static esp_netif_t* s_sta_netif = NULL;
|
||||||
|
|
||||||
|
static EventGroupHandle_t wifi_events;
|
||||||
|
static void stop_wifi(void);
|
||||||
|
|
||||||
|
static void wifi_ap_event_handler(void* arg, esp_event_base_t event_base,
|
||||||
|
int32_t event_id, void* event_data)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "wifi event handler: %"PRIi32, event_id);
|
||||||
|
switch (event_id) {
|
||||||
|
case WIFI_EVENT_AP_START:
|
||||||
|
ESP_LOGI(TAG, "WIFI_EVENT_AP_START");
|
||||||
|
break;
|
||||||
|
case WIFI_EVENT_AP_STACONNECTED:
|
||||||
|
ESP_LOGI(TAG, "WIFI_EVENT_AP_STACONNECTED");
|
||||||
|
if (wifi_events) {
|
||||||
|
xEventGroupSetBits(wifi_events, WIFI_AP_STA_CONNECTED);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WIFI_EVENT_AP_STADISCONNECTED:
|
||||||
|
ESP_LOGI(TAG, "WIFI_EVENT_AP_STADISCONNECTED");
|
||||||
|
ESP_LOGI(TAG, "sta disconnected");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wifi_sta_event_handler(void* arg, esp_event_base_t event_base,
|
||||||
|
int32_t event_id, void* event_data)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "wifi event handler: %"PRIi32, event_id);
|
||||||
|
switch (event_id) {
|
||||||
|
case WIFI_EVENT_STA_START:
|
||||||
|
ESP_LOGI(TAG, "WIFI_EVENT_STA_START");
|
||||||
|
// make sure softap has started
|
||||||
|
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||||
|
TEST_ESP_OK(esp_wifi_connect());
|
||||||
|
ESP_LOGI(TAG, "start esp_wifi_connect");
|
||||||
|
break;
|
||||||
|
case WIFI_EVENT_STA_CONNECTED:
|
||||||
|
ESP_LOGI(TAG, "WIFI_EVENT_STA_CONNECTED");
|
||||||
|
if (wifi_events) {
|
||||||
|
xEventGroupSetBits(wifi_events, WIFI_STA_CONNECTED);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WIFI_EVENT_STA_DISCONNECTED:
|
||||||
|
ESP_LOGI(TAG, "WIFI_EVENT_STA_DISCONNECTED");
|
||||||
|
wifi_event_sta_disconnected_t *event = (wifi_event_sta_disconnected_t *)event_data;
|
||||||
|
ESP_LOGI(TAG, "disconnect reason: %u", event->reason);
|
||||||
|
if (!(EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT & wifi_event_handler_flag)) {
|
||||||
|
TEST_ESP_OK(esp_wifi_connect());
|
||||||
|
}
|
||||||
|
if (wifi_events) {
|
||||||
|
xEventGroupSetBits(wifi_events, WIFI_DISCONNECT_EVENT);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ip_event_handler(void* arg, esp_event_base_t event_base,
|
||||||
|
int32_t event_id, void* event_data)
|
||||||
|
{
|
||||||
|
ip_event_got_ip_t *event;
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "ip event handler");
|
||||||
|
switch (event_id) {
|
||||||
|
case IP_EVENT_STA_GOT_IP:
|
||||||
|
event = (ip_event_got_ip_t*)event_data;
|
||||||
|
ESP_LOGI(TAG, "IP_EVENT_STA_GOT_IP");
|
||||||
|
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
|
||||||
|
if (wifi_events) {
|
||||||
|
xEventGroupSetBits(wifi_events, GOT_IP_EVENT);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t event_init(void)
|
||||||
|
{
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, &ip_event_handler, NULL));
|
||||||
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||||
|
esp_wifi_init(&cfg);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t event_deinit(void)
|
||||||
|
{
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, &ip_event_handler));
|
||||||
|
ESP_ERROR_CHECK(esp_event_loop_delete_default());
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EMPH_STR(s) "****** "s" ******"
|
||||||
|
|
||||||
|
static void start_wifi(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
event_init();
|
||||||
|
|
||||||
|
if (wifi_events == NULL) {
|
||||||
|
wifi_events = xEventGroupCreate();
|
||||||
|
}
|
||||||
|
xEventGroupClearBits(wifi_events, 0x00ffffff);
|
||||||
|
|
||||||
|
TEST_ESP_OK(esp_wifi_start());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void stop_wifi(void)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Stopping wifi now");
|
||||||
|
TEST_ESP_OK(esp_wifi_stop());
|
||||||
|
event_deinit();
|
||||||
|
if (wifi_events) {
|
||||||
|
vEventGroupDelete(wifi_events);
|
||||||
|
wifi_events = NULL;
|
||||||
|
}
|
||||||
|
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_wifi_connection_sta(void)
|
||||||
|
{
|
||||||
|
EventBits_t bits;
|
||||||
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_sta_event_handler, NULL));
|
||||||
|
s_sta_netif = esp_netif_create_default_wifi_sta();
|
||||||
|
esp_wifi_set_mode(WIFI_MODE_STA);
|
||||||
|
|
||||||
|
start_wifi();
|
||||||
|
|
||||||
|
wifi_config_t cfg;
|
||||||
|
esp_wifi_get_config(WIFI_IF_STA, &cfg);
|
||||||
|
ESP_LOGI(TAG, "STA mode, %s %s", cfg.sta.ssid, cfg.sta.password);
|
||||||
|
|
||||||
|
bits = xEventGroupWaitBits(wifi_events, GOT_IP_EVENT, 1, 0, CONNECT_TIMEOUT_MS / portTICK_PERIOD_MS);
|
||||||
|
TEST_ASSERT(bits & GOT_IP_EVENT);
|
||||||
|
|
||||||
|
xEventGroupClearBits(wifi_events, WIFI_DISCONNECT_EVENT);
|
||||||
|
wifi_event_handler_flag |= EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT;
|
||||||
|
|
||||||
|
// Wait for 60s and the stop wifi
|
||||||
|
vTaskDelay(60000 / portTICK_PERIOD_MS);
|
||||||
|
esp_netif_destroy_default_wifi(s_sta_netif);
|
||||||
|
|
||||||
|
stop_wifi();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_wifi_connection_softap(void)
|
||||||
|
{
|
||||||
|
EventBits_t bits;
|
||||||
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_ap_event_handler, NULL));
|
||||||
|
s_ap_netif = esp_netif_create_default_wifi_ap();
|
||||||
|
|
||||||
|
esp_wifi_set_mode(WIFI_MODE_AP);
|
||||||
|
start_wifi();
|
||||||
|
|
||||||
|
wifi_config_t cfg;
|
||||||
|
esp_wifi_get_config(WIFI_IF_AP, &cfg);
|
||||||
|
ESP_LOGI(TAG, "AP mode, %s %s", cfg.ap.ssid, cfg.ap.password);
|
||||||
|
|
||||||
|
// wait station connected
|
||||||
|
bits = xEventGroupWaitBits(wifi_events, WIFI_AP_STA_CONNECTED, 1, 0, CONNECT_TIMEOUT_MS / portTICK_PERIOD_MS);
|
||||||
|
TEST_ASSERT(bits & WIFI_AP_STA_CONNECTED);
|
||||||
|
|
||||||
|
// wait 70s (longer than station side)
|
||||||
|
vTaskDelay((60000 + CONNECT_TIMEOUT_MS) / portTICK_PERIOD_MS);
|
||||||
|
esp_netif_destroy_default_wifi(s_ap_netif);
|
||||||
|
|
||||||
|
stop_wifi();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE_MULTIPLE_DEVICES("test wifi connection with station and AP", "[wifi][timeout=90]", test_wifi_connection_sta, test_wifi_connection_softap);
|
@@ -0,0 +1,7 @@
|
|||||||
|
key,type,encoding,value
|
||||||
|
nvs.net80211,namespace,,
|
||||||
|
sta.ssid,data,blob_sz_fill(32;0x00),TESTSSID
|
||||||
|
sta.pswd,data,blob_fill(64;0x00),TESTPASSWORD
|
||||||
|
ap.ssid,data,blob_sz_fill(32;0x00),TESTSSID
|
||||||
|
ap.passwd,data,blob_fill(64;0x00),TESTPASSWORD
|
||||||
|
ap.authmode,data,u8,3
|
|
@@ -0,0 +1,6 @@
|
|||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
nvs, data, nvs, 0x9000, 0x6000,
|
||||||
|
phy_init, data, phy, 0xf000, 0x1000,
|
||||||
|
factory, app, factory, 0x10000, 1M,
|
|
@@ -0,0 +1,30 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded_idf.unity_tester import CaseTester
|
||||||
|
from pytest_embedded_idf.utils import idf_parametrize
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.wifi_two_dut
|
||||||
|
@pytest.mark.parametrize('count', [2], indirect=True)
|
||||||
|
@idf_parametrize(
|
||||||
|
'target',
|
||||||
|
['esp32', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32c61', 'esp32s2', 'esp32s3'],
|
||||||
|
indirect=['target'],
|
||||||
|
)
|
||||||
|
def test_wifi_nvs_connect_cases(case_tester: CaseTester) -> None: # type: ignore
|
||||||
|
case_tester.run_all_cases()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.wifi_two_dut
|
||||||
|
@pytest.mark.xtal_26mhz
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'count, config, baud',
|
||||||
|
[
|
||||||
|
(2, 'esp32c2_xtal26m', '74880'),
|
||||||
|
],
|
||||||
|
indirect=True,
|
||||||
|
)
|
||||||
|
@idf_parametrize('target', ['esp32c2'], indirect=['target'])
|
||||||
|
def test_wifi_nvs_connect_cases_esp32c2_xtal26m(case_tester: CaseTester) -> None:
|
||||||
|
case_tester.run_all_cases()
|
@@ -0,0 +1,2 @@
|
|||||||
|
CONFIG_IDF_TARGET="esp32c2"
|
||||||
|
CONFIG_XTAL_FREQ_26=y
|
@@ -0,0 +1,5 @@
|
|||||||
|
# ignore task watchdog triggered by unity_run_menu
|
||||||
|
CONFIG_ESP_TASK_WDT_EN=n
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example.csv"
|
||||||
|
CONFIG_PARTITION_TABLE_FILENAME="partitions_example.csv"
|
@@ -0,0 +1,39 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
|
||||||
|
import csv
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def update_csv_suffix(suffix: str) -> None:
|
||||||
|
# Hardcoded CSV file path
|
||||||
|
CSV_FILE = os.path.join(os.path.dirname(__file__), 'nvs_data.csv')
|
||||||
|
|
||||||
|
# Output CSV file path with suffix
|
||||||
|
NEW_CSV_FILE = os.path.join(os.path.dirname(__file__), 'nvs_data_suffix.csv')
|
||||||
|
|
||||||
|
with open(NEW_CSV_FILE, 'w', newline='') as outfile:
|
||||||
|
with open(CSV_FILE, 'r', newline='') as infile:
|
||||||
|
reader = csv.DictReader(infile)
|
||||||
|
fieldnames = reader.fieldnames if reader.fieldnames else []
|
||||||
|
writer = csv.DictWriter(outfile, fieldnames=fieldnames)
|
||||||
|
writer.writeheader()
|
||||||
|
|
||||||
|
for row in reader:
|
||||||
|
if row['value'] == 'TESTSSID':
|
||||||
|
row['value'] = f'TESTSSID_{suffix}'
|
||||||
|
elif row['value'] == 'TESTPASSWORD':
|
||||||
|
row['value'] = f'TESTPASSWORD_{suffix}'
|
||||||
|
writer.writerow(row)
|
||||||
|
|
||||||
|
print(f'[update_csv.py] Patched CSV with suffix: {suffix}, saved as {NEW_CSV_FILE}')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print('Usage: python update_csv_suffix.py <suffix>')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
suffix = sys.argv[1]
|
||||||
|
update_csv_suffix(suffix)
|
8
examples/wifi/wifi_nvs_config/CMakeLists.txt
Normal file
8
examples/wifi/wifi_nvs_config/CMakeLists.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# The following five lines of boilerplate have to be in your project's
|
||||||
|
# CMakeLists in this exact order for cmake to work correctly
|
||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
|
||||||
|
idf_build_set_property(MINIMAL_BUILD ON)
|
||||||
|
project(wifi_nvs_config)
|
217
examples/wifi/wifi_nvs_config/README.md
Normal file
217
examples/wifi/wifi_nvs_config/README.md
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-S2 | ESP32-S3 |
|
||||||
|
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||||
|
|
||||||
|
# WiFi NVS Config Example
|
||||||
|
|
||||||
|
(See the `README.md` file in the upper-level 'examples' directory for more information about examples.)
|
||||||
|
|
||||||
|
This example demonstrates how to configure Wi-Fi settings in NVS directly using a CSV file and utilize the Wi-Fi functionality of the ESP Wi-Fi driver.
|
||||||
|
|
||||||
|
## How to Use the Example
|
||||||
|
|
||||||
|
### 1) Configuration
|
||||||
|
|
||||||
|
Open the CSV file `nvs_station_data.csv` or `nvs_ap_data.csv`.
|
||||||
|
|
||||||
|
- Set the Wi-Fi configuration keys as explained below. These values are written into the NVS partition and read by the Wi-Fi driver during `esp_wifi_init()`.
|
||||||
|
- If needed, adjust or set other options as per your requirements. The AP and station keys along with their encoding types are listed [here](#key-configuration).
|
||||||
|
|
||||||
|
**Note 1:** To set the device in SoftAP mode, enable the `CONFIG_ESP_WIFI_SOFTAP_SUPPORT` flag in `menuconfig`.
|
||||||
|
|
||||||
|
**Note 2:** Setting these values is optional. Defaults are applied when `esp_wifi_init()` is called.
|
||||||
|
|
||||||
|
### 2) Generate the Binary File Using the NVS Partition Generator Utility
|
||||||
|
|
||||||
|
- Check the size of the NVS partition in the `partition_example.csv` file provided in this example.
|
||||||
|
- Generate a `.bin` file of the specified size using the following command:
|
||||||
|
|
||||||
|
**Usage:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python nvs_partition_gen.py generate [-h] [--version {1,2}] [--outdir OUTDIR] input output size
|
||||||
|
```
|
||||||
|
|
||||||
|
- Sample command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python nvs_partition_gen.py generate nvs_station_data.csv sample_nvs.bin 0x6000
|
||||||
|
```
|
||||||
|
|
||||||
|
- Please update the NVS Partition Generator to the latest version to avoid encoding type errors.
|
||||||
|
- For more information, see the [NVS Partition Generator Utility Documentation](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/storage/nvs_partition_gen.html).
|
||||||
|
|
||||||
|
### 3) Flash the NVS Binary File to the ESP Device
|
||||||
|
|
||||||
|
- Check the offset of the NVS partition in the `partition_example.csv` file.
|
||||||
|
- After flashing the build, flash the `sample_nvs.bin` file to the ESP device at the specified offset using `esptool.py`.
|
||||||
|
- Refer to the [Esptool Documentation](https://docs.espressif.com/projects/esptool/en/latest/esp32/esptool/index.html) for detailed usage.
|
||||||
|
|
||||||
|
### 4) Build and Flash
|
||||||
|
|
||||||
|
Build the project and flash it to the board, then run the monitor tool to view the serial output.
|
||||||
|
|
||||||
|
Run `idf.py -p PORT flash monitor` to build, flash and monitor the project.
|
||||||
|
|
||||||
|
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||||
|
|
||||||
|
### 5) Monitor the Output
|
||||||
|
|
||||||
|
- Use `idf.py monitor` to view the console output of the example.
|
||||||
|
|
||||||
|
See the Getting Started Guide for all the steps to configure and use the ESP-IDF to build projects.
|
||||||
|
|
||||||
|
* [ESP-IDF Getting Started Guide on ESP32](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html)
|
||||||
|
|
||||||
|
## Key Configuration
|
||||||
|
|
||||||
|
### Station Keys
|
||||||
|
|
||||||
|
|
||||||
|
| Key Name | Encoding Type | Mandatory/Optional | Description / Meaning |
|
||||||
|
|--------------------------|---------------|---------------------|----------------------------------------------------|
|
||||||
|
| sta.ssid | blob_sz_fill | Mandatory | SSID (Service Set Identifier) for station. (Refer parameter `uint8_t ssid[32]` from `struct wifi_sta_config_t`) |
|
||||||
|
| sta.pswd | blob_fill | Mandatory | Password for connecting to the Wi-Fi network. (Refer parameter `uint8_t password[64]` from `struct wifi_sta_config_t`) |
|
||||||
|
| bssid.set | u8 | Optional | Whether the BSSID is set or not. (Refer parameter `bool bssid_set` from `struct wifi_sta_config_t`) |
|
||||||
|
| sta.bssid | blob | Optional | BSSID (Basic Service Set Identifier) of the network. (Refer parameter `uint8_t bssid[6]` from `struct wifi_sta_config_t`) |
|
||||||
|
| sta.lis_intval | u16 | Optional | Listen interval (Refer parameter `uint16_t listen_interval` from `struct wifi_sta_config_t`) |
|
||||||
|
| sta.phym | u8 | Optional | Physical mode e.g., 802.11a/b/g/n/ac/ax. (Refer `esp_err_t esp_wifi_set_protocol(wifi_interface_t ifx, uint8_t protocol_bitmap)`) |
|
||||||
|
| sta.phybw | u8 | Optional | Physical bandwidth (e.g., 20MHz, 40MHz) (Refer `esp_err_t esp_wifi_set_bandwidth(wifi_interface_t ifx, wifi_bandwidths_t* bw)`) |
|
||||||
|
| sta.sort_method | u8 | Optional | Sorting method for APs e.g. enum wifi_sort_method_t (Refer parameter `wifi_sort_method_t sort_method` from `struct wifi_sta_config_t`)|
|
||||||
|
| sta.minrssi | i8 | Optional | Minimum RSSI for the station to connect. (Refer `esp_err_t esp_wifi_set_rssi_threshold()` OR `int8_t rssi` from `wifi_scan_threshold_t threshold`) |
|
||||||
|
| sta.minauth | u8 | Optional | Minimum authentication level required for APs. (Refer `wifi_auth_mode_t authmode` from `wifi_scan_threshold_t threshold`) |
|
||||||
|
| sta.pmf_r | u8 | Optional | Whether PMF is required. (Refer `wifi_pmf_config_t pmf_cfg` parameter from `struct wifi_sta_config_t`) |
|
||||||
|
| sta.btm_e | u8 | Optional | Whether BTM is enabled. (Refer parameter `uint32_t btm_enabled` from `struct wifi_sta_config_t`) |
|
||||||
|
| sta.rrm_e | u8 | Optional | Whether RRM is enabled. (Refer parameter `uint32_t rm_enabled` from `struct wifi_sta_config_t`) |
|
||||||
|
| sta.mbo_e | u8 | Optional | Whether MBO (Multi-band Operation) is enabled. (Refer parameter `uint32_t mbo_enabled` from `struct wifi_sta_config_t`) |
|
||||||
|
| sta.phym5g | u8 | Optional | 5 GHz physical mode. (Only for chips supporting 5GHz bandwidth. (Refer `esp_err_t esp_wifi_set_protocol(wifi_interface_t ifx, uint8_t protocol_bitmap)`) |
|
||||||
|
| sta.phybw5g | u8 | Optional | 5 GHz bandwidth setting.(Only for chips supporting 5GHz bandwidth. (Refer `esp_err_t esp_wifi_set_bandwidths(wifi_interface_t ifx, wifi_bandwidths_t* bw)` |
|
||||||
|
| sta.ft | u8 | Optional | Whether fast transition is enabled. (Refer parameter `uint32_t ft_enabled` from `struct wifi_sta_config_t`) |
|
||||||
|
| sta.owe | u8 | Optional | Whether OWE (Opportunistic Wireless Encryption) is enabled. (Refer parameter `uint32_t owe_enabled` from `struct wifi_sta_config_t`) |
|
||||||
|
| sta.trans_d | u8 | Optional | Transition disabled setting. (Refer parameter `uint32_t transition_disable` from `struct wifi_sta_config_t`) |
|
||||||
|
| sta.sae_h2e | u8 | Optional | SAE PWE method (e.g. enum wifi_sae_pwe_method_t). (Refer parameter `wifi_sae_pwe_method_t sae_pwe_h2e` from `struct wifi_sta_config_t`) |
|
||||||
|
| sta.sae_pk_mode | u8 | Optional | SAE-pk mode setting (e.g. enum wifi_sae_pk_mode_t) (Refer parameter `wifi_sae_pk_mode_t sae_pk_mode` from `struct wifi_sta_config_t`) |
|
||||||
|
| sta.bss_retry | u8 | Optional | BSS retry counter. (Refer parameter `uint8_t failure_retry_cnt` from `struct wifi_sta_config_t`) |
|
||||||
|
| sta.sae_h2e_id | blob | Optional | Password identifier for H2E. This must be a null-terminated string (Refer parameter `uint8_t sae_h2e_identifier[SAE_H2E_IDENTIFIER_LEN]` from `struct wifi_sta_config_t`) |
|
||||||
|
| sta.rssi_5g_adj | u8 | Optional | RSSI adjustment for 5 GHz. (Refer `uint8_t rssi_5g_adjustment` from `wifi_scan_threshold_t threshold`) |
|
||||||
|
|
||||||
|
|
||||||
|
### AP Keys
|
||||||
|
|
||||||
|
| Key Name | Encoding Type | Mandatory/Optional | Description / Meaning |
|
||||||
|
|--------------------------|---------------|---------------------|----------------------------------------------------|
|
||||||
|
| ap.ssid | blob_sz_fill | Mandatory | SSID (Service Set Identifier) for the AP prefixed with the length of the SSID. (Refer parameter `uint8_t ssid[32]` from `struct wifi_ap_config_t`) |
|
||||||
|
| ap.passwd | blob_fill | Mandatory | Password for the AP's Wi-Fi network. (Refer parameter `uint8_t password[64]` from `struct wifi_ap_config_t`) |
|
||||||
|
| ap.chan | u8 | Mandatory | Channel number on which the AP is broadcasting. (Refer parameter `uint8_t channel` from `struct wifi_ap_config_t`) |
|
||||||
|
| ap.authmode | u8 | Mandatory | Authentication mode for the AP e.g. enum wifi_auth_mode_t. (Refer parameter `wifi_auth_mode_t authmode` from `struct wifi_ap_config_t`) |
|
||||||
|
| ap.hidden | u8 | Optional | Whether the AP is hidden (1 for hidden, 0 for visible). (Refer parameter `uint8_t ssid_hidden` from `struct wifi_ap_config_t`) |
|
||||||
|
| ap.max.conn | u8 | Optional | Maximum number of connections the AP supports. It is different for different chips.(Please refer parameter `uint8_t max_connection` from `struct wifi_ap_config_t` and [AP Basic Configurations](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#ap-basic-configuration) for more details). |
|
||||||
|
| bcn.interval | u8 | Optional | Beacon interval time for the AP. (Refer parameter `uint16_t beacon_interval` from `struct wifi_ap_config_t`)) |
|
||||||
|
| ap.pmf_r | u8 | Optional | Whether PMF is required on the AP. (Refer parameter `wifi_pmf_config_t pmf_cfg` from `struct wifi_ap_config_t`)) |
|
||||||
|
| ap.p_cipher | u8 | Optional | Pairwise Cipher suite used by the AP e.g. enum wifi_cipher_type_t (Refer parameter `wifi_cipher_type_t pairwise_cipher` from `struct wifi_ap_config_t`) |
|
||||||
|
| ap.ftm_r | u8 | Optional | Whether FTM (Fine Timing Measurement) responder is enabled. (Refer parameter `bool ftm_responder` from `struct wifi_ap_config_t`) |
|
||||||
|
| ap.sae_h2e | u8 | Optional | Config method for SAE e.g. enum `wifi_sae_pwe_method_t` (Refer parameter `wifi_sae_pwe_method_t sae_pwe_h2e` from `struct wifi_ap_config_t`) |
|
||||||
|
| ap.csa_count | u8 | Optional | Channel Switch Announcement count for the AP. (Refer parameter `uint8_t csa_count` from `struct wifi_ap_config_t`) |
|
||||||
|
| ap.dtim_period | u8 | Optional | DTIM period for the AP. (Refer parameter `uint8_t dtim_period` from `struct wifi_ap_config_t`) |
|
||||||
|
| ap.phym5g | u8 | Optional | 5 GHz physical mode. (Refer `esp_err_t esp_wifi_set_protocol(wifi_interface_t ifx, uint8_t protocol_bitmap)`) |
|
||||||
|
| ap.phybw5g | u8 | Optional | 5 GHz bandwidth setting. (Refer `esp_err_t esp_wifi_set_bandwidths(wifi_interface_t ifx, wifi_bandwidth_t bw)`) |
|
||||||
|
|
||||||
|
### Generic Keys
|
||||||
|
|
||||||
|
| Key Name | Encoding Type | Mandatory/Optional | Description / Meaning |
|
||||||
|
|--------------------------|---------------|---------------------|----------------------------------------------------|
|
||||||
|
| opmode | u8 | Mandatory | Operating mode (e.g. enum `wifi_mode_t` OR refer `esp_err_t esp_wifi_set_mode(wifi_mode_t mode)`) |
|
||||||
|
| country | blob | Optional | Operating country (e.g. enum `wifi_country_t` OR refer `esp_err_t esp_wifi_set_country_code(const char *country, bool ieee80211d_enabled)`) |
|
||||||
|
| band_mode | u8 | Optional | Operating band (e.g. enum `wifi_band_t` or refer [esp_err_t esp_wifi_set_band_mode(wifi_band_mode_t band_mode)](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv422esp_wifi_set_band_mode16wifi_band_mode_t)) |
|
||||||
|
|
||||||
|
These keys can be configured by setting the desired values in `nvs_station_data.csv` or `nvs_ap_data.csv`.
|
||||||
|
|
||||||
|
For more details on station and AP configurations, refer to the following:
|
||||||
|
|
||||||
|
- [Station Basic Configuration](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#station-basic-configuration)
|
||||||
|
- [AP Basic Configuration](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#ap-basic-configuration)
|
||||||
|
|
||||||
|
Also review the limitations for values of each key in the [ESP-IDF API Reference Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html).
|
||||||
|
|
||||||
|
|
||||||
|
## Example Output
|
||||||
|
Note that the output, in particular the order of the output, may vary depending on the environment.
|
||||||
|
|
||||||
|
Console output if station connects to AP successfully:
|
||||||
|
```
|
||||||
|
I (599) wifi: wifi driver task: 3ffc08b4, prio:23, stack:3584, core=0
|
||||||
|
I (599) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
|
||||||
|
I (599) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
|
||||||
|
I (629) wifi: wifi firmware version: 2d94f02
|
||||||
|
I (629) wifi: config NVS flash: enabled
|
||||||
|
I (629) wifi: config nano formatting: disabled
|
||||||
|
I (629) wifi: Init dynamic tx buffer num: 32
|
||||||
|
I (629) wifi: Init data frame dynamic rx buffer num: 32
|
||||||
|
I (639) wifi: Init management frame dynamic rx buffer num: 32
|
||||||
|
I (639) wifi: Init management short buffer num: 32
|
||||||
|
I (649) wifi: Init static rx buffer size: 1600
|
||||||
|
I (649) wifi: Init static rx buffer num: 10
|
||||||
|
I (659) wifi: Init dynamic rx buffer num: 32
|
||||||
|
I (759) phy: phy_version: 4180, cb3948e, Sep 12 2019, 16:39:13, 0, 0
|
||||||
|
I (769) wifi: mode : sta (30:ae:a4:d9:bc:c4)
|
||||||
|
I (769) wifi station: wifi_init_sta finished.
|
||||||
|
I (889) wifi: new:<6,0>, old:<1,0>, ap:<255,255>, sta:<6,0>, prof:1
|
||||||
|
I (889) wifi: state: init -> auth (b0)
|
||||||
|
I (899) wifi: state: auth -> assoc (0)
|
||||||
|
I (909) wifi: state: assoc -> run (10)
|
||||||
|
I (939) wifi: connected with #!/bin/test, aid = 1, channel 6, BW20, bssid = ac:9e:17:7e:31:40
|
||||||
|
I (939) wifi: security type: 3, phy: bgn, rssi: -68
|
||||||
|
I (949) wifi: pm start, type: 1
|
||||||
|
|
||||||
|
I (1029) wifi: AP's beacon interval = 102400 us, DTIM period = 3
|
||||||
|
I (2089) esp_netif_handlers: sta ip: 192.168.77.89, mask: 255.255.255.0, gw: 192.168.77.1
|
||||||
|
I (2089) wifi station: got ip:192.168.77.89
|
||||||
|
I (2089) wifi station: connected to ap SSID:myssid password:mypassword
|
||||||
|
```
|
||||||
|
|
||||||
|
Console output if the station failed to connect to AP:
|
||||||
|
```
|
||||||
|
I (599) wifi: wifi driver task: 3ffc08b4, prio:23, stack:3584, core=0
|
||||||
|
I (599) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
|
||||||
|
I (599) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
|
||||||
|
I (629) wifi: wifi firmware version: 2d94f02
|
||||||
|
I (629) wifi: config NVS flash: enabled
|
||||||
|
I (629) wifi: config nano formatting: disabled
|
||||||
|
I (629) wifi: Init dynamic tx buffer num: 32
|
||||||
|
I (629) wifi: Init data frame dynamic rx buffer num: 32
|
||||||
|
I (639) wifi: Init management frame dynamic rx buffer num: 32
|
||||||
|
I (639) wifi: Init management short buffer num: 32
|
||||||
|
I (649) wifi: Init static rx buffer size: 1600
|
||||||
|
I (649) wifi: Init static rx buffer num: 10
|
||||||
|
I (659) wifi: Init dynamic rx buffer num: 32
|
||||||
|
I (759) phy: phy_version: 4180, cb3948e, Sep 12 2019, 16:39:13, 0, 0
|
||||||
|
I (759) wifi: mode : sta (30:ae:a4:d9:bc:c4)
|
||||||
|
I (769) wifi station: wifi_init_sta finished.
|
||||||
|
I (889) wifi: new:<6,0>, old:<1,0>, ap:<255,255>, sta:<6,0>, prof:1
|
||||||
|
I (889) wifi: state: init -> auth (b0)
|
||||||
|
I (1889) wifi: state: auth -> init (200)
|
||||||
|
I (1889) wifi: new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1
|
||||||
|
I (1889) wifi station: retry to connect to the AP
|
||||||
|
I (1899) wifi station: connect to the AP fail
|
||||||
|
I (3949) wifi station: retry to connect to the AP
|
||||||
|
I (3949) wifi station: connect to the AP fail
|
||||||
|
I (4069) wifi: new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1
|
||||||
|
I (4069) wifi: state: init -> auth (b0)
|
||||||
|
I (5069) wifi: state: auth -> init (200)
|
||||||
|
I (5069) wifi: new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1
|
||||||
|
I (5069) wifi station: retry to connect to the AP
|
||||||
|
I (5069) wifi station: connect to the AP fail
|
||||||
|
I (7129) wifi station: retry to connect to the AP
|
||||||
|
I (7129) wifi station: connect to the AP fail
|
||||||
|
I (7249) wifi: new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1
|
||||||
|
I (7249) wifi: state: init -> auth (b0)
|
||||||
|
I (8249) wifi: state: auth -> init (200)
|
||||||
|
I (8249) wifi: new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1
|
||||||
|
I (8249) wifi station: retry to connect to the AP
|
||||||
|
I (8249) wifi station: connect to the AP fail
|
||||||
|
I (10299) wifi station: connect to the AP fail
|
||||||
|
I (10299) wifi station: Failed to connect to SSID:myssid, password:mypassword
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.
|
3
examples/wifi/wifi_nvs_config/main/CMakeLists.txt
Normal file
3
examples/wifi/wifi_nvs_config/main/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
idf_component_register(SRCS "wifi_nvs_config_main.c"
|
||||||
|
INCLUDE_DIRS "."
|
||||||
|
PRIV_REQUIRES esp_wifi nvs_flash)
|
136
examples/wifi/wifi_nvs_config/main/wifi_nvs_config_main.c
Normal file
136
examples/wifi/wifi_nvs_config/main/wifi_nvs_config_main.c
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
*/
|
||||||
|
/* WiFi example
|
||||||
|
|
||||||
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, this
|
||||||
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
*/
|
||||||
|
#include <string.h>
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/event_groups.h"
|
||||||
|
#include "esp_system.h"
|
||||||
|
#include "esp_wifi.h"
|
||||||
|
#include "esp_event.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "nvs_flash.h"
|
||||||
|
|
||||||
|
#include "lwip/err.h"
|
||||||
|
#include "lwip/sys.h"
|
||||||
|
|
||||||
|
/* The examples use WiFi configuration that you can set via flashing nvs partition */
|
||||||
|
|
||||||
|
/* FreeRTOS event group to signal when we are connected*/
|
||||||
|
static EventGroupHandle_t s_wifi_event_group;
|
||||||
|
|
||||||
|
/* The event group allows multiple bits for each event, but we only care about two events:
|
||||||
|
* - we are connected to the AP with an IP
|
||||||
|
* - we failed to connect after the maximum amount of retries */
|
||||||
|
#define WIFI_CONNECTED_BIT BIT0
|
||||||
|
#define WIFI_FAIL_BIT BIT1
|
||||||
|
|
||||||
|
#define MAXIMUM_RETRY_COUNT 5
|
||||||
|
|
||||||
|
static const char *TAG = "wifi_nvs_config";
|
||||||
|
|
||||||
|
static int s_retry_num = 0;
|
||||||
|
|
||||||
|
|
||||||
|
static void event_handler(void* arg, esp_event_base_t event_base,
|
||||||
|
int32_t event_id, void* event_data)
|
||||||
|
{
|
||||||
|
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_START) {
|
||||||
|
ESP_LOGI(TAG, "SoftAP started successfully!");
|
||||||
|
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STACONNECTED) {
|
||||||
|
wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;
|
||||||
|
ESP_LOGI(TAG, "station join, AID=%d", event->aid);
|
||||||
|
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STADISCONNECTED) {
|
||||||
|
wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;
|
||||||
|
ESP_LOGI(TAG, "station leave, AID=%d, reason=%d", event->aid, event->reason);
|
||||||
|
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
|
||||||
|
esp_wifi_connect();
|
||||||
|
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
||||||
|
if (s_retry_num < MAXIMUM_RETRY_COUNT) {
|
||||||
|
esp_wifi_connect();
|
||||||
|
s_retry_num++;
|
||||||
|
ESP_LOGI(TAG, "retry to connect to the AP");
|
||||||
|
} else {
|
||||||
|
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
|
||||||
|
}
|
||||||
|
ESP_LOGI(TAG,"connect to the AP fail");
|
||||||
|
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
||||||
|
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
|
||||||
|
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
|
||||||
|
s_retry_num = 0;
|
||||||
|
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wifi_init(void)
|
||||||
|
{
|
||||||
|
s_wifi_event_group = xEventGroupCreate();
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_netif_init());
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||||
|
|
||||||
|
esp_netif_create_default_wifi_sta();
|
||||||
|
esp_netif_create_default_wifi_ap();
|
||||||
|
|
||||||
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||||
|
|
||||||
|
esp_event_handler_instance_t instance_any_id;
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
||||||
|
ESP_EVENT_ANY_ID,
|
||||||
|
&event_handler,
|
||||||
|
NULL,
|
||||||
|
&instance_any_id));
|
||||||
|
esp_event_handler_instance_t instance_got_ip;
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
|
||||||
|
IP_EVENT_STA_GOT_IP,
|
||||||
|
&event_handler,
|
||||||
|
NULL,
|
||||||
|
&instance_got_ip));
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_start() );
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "wifi_init finished.");
|
||||||
|
|
||||||
|
/* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
|
||||||
|
* number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
|
||||||
|
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
|
||||||
|
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
|
||||||
|
pdFALSE,
|
||||||
|
pdFALSE,
|
||||||
|
portMAX_DELAY);
|
||||||
|
|
||||||
|
/* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
|
||||||
|
* happened. */
|
||||||
|
if (bits & WIFI_CONNECTED_BIT) {
|
||||||
|
ESP_LOGI(TAG, "Successfully connected to AP");
|
||||||
|
} else if (bits & WIFI_FAIL_BIT) {
|
||||||
|
ESP_LOGI(TAG, "Failed to connect to AP");
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "UNEXPECTED EVENT");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_main(void)
|
||||||
|
{
|
||||||
|
//Initialize NVS
|
||||||
|
esp_err_t ret = nvs_flash_init();
|
||||||
|
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||||
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||||
|
ret = nvs_flash_init();
|
||||||
|
}
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
|
||||||
|
wifi_init();
|
||||||
|
}
|
8
examples/wifi/wifi_nvs_config/nvs_ap_data.csv
Normal file
8
examples/wifi/wifi_nvs_config/nvs_ap_data.csv
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
key,type,encoding,value
|
||||||
|
nvs.net80211,namespace,,
|
||||||
|
opmode,data,u8,2
|
||||||
|
ap.ssid,data,blob_sz_fill(32;0x00),myssid
|
||||||
|
ap.passwd,data,blob_fill(64;0x00),mypassword
|
||||||
|
ap.authmode,data,u8,3
|
||||||
|
ap.max.conn,data,u8,3
|
||||||
|
ap.pmf_r,data,u8,0
|
|
17
examples/wifi/wifi_nvs_config/nvs_station_data.csv
Normal file
17
examples/wifi/wifi_nvs_config/nvs_station_data.csv
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
key,type,encoding,value
|
||||||
|
nvs.net80211,namespace,,
|
||||||
|
opmode,data,u8,1
|
||||||
|
sta.ssid,data,blob_sz_fill(32;0x00),myssid
|
||||||
|
sta.pswd,data,blob_fill(64;0x00),mypassword
|
||||||
|
bssid.set,data,u8,0
|
||||||
|
sta.lis_intval,data,u16,3
|
||||||
|
sta.scan_method,data,u8,1
|
||||||
|
sta.sort_method,data,u8,0
|
||||||
|
sta.pmf_r,data,u8,0
|
||||||
|
sta.btm_e,data,u8,0
|
||||||
|
sta.rrm_e,data,u8,0
|
||||||
|
sta.mbo_e,data,u8,0
|
||||||
|
sta.ft,data,u8,0
|
||||||
|
sta.trans_d,data,u8,0
|
||||||
|
sta.sae_h2e,data,u8,0
|
||||||
|
sta.sae_pk_mode,data,u8,0
|
|
6
examples/wifi/wifi_nvs_config/partitions_example.csv
Normal file
6
examples/wifi/wifi_nvs_config/partitions_example.csv
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
nvs, data, nvs, 0x9000, 0x6000,
|
||||||
|
phy_init, data, phy, 0xf000, 0x1000,
|
||||||
|
factory, app, factory, 0x10000, 1M,
|
|
3
examples/wifi/wifi_nvs_config/sdkconfig.defaults
Normal file
3
examples/wifi/wifi_nvs_config/sdkconfig.defaults
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example.csv"
|
||||||
|
CONFIG_PARTITION_TABLE_FILENAME="partitions_example.csv"
|
Reference in New Issue
Block a user