refactor(examples/storage): update nvs_rw_blob and nvs_rw_value examples

This commit is contained in:
sonika.rathi
2025-03-26 08:50:26 +01:00
parent e4e56a4687
commit 24065c6bbd
6 changed files with 338 additions and 280 deletions

View File

@@ -14,7 +14,7 @@ Example also shows how to implement diagnostics if read / write operation was su
Detailed functional description of NVS and API is provided in [documentation](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/storage/nvs_flash.html).
If not done already, consider checking simpler example *storage/nvs_rw_value*, that has been used as a starting point for preparing this one.
If not done already, consider checking simpler example *storage/nvs/nvs_rw_value*, that has been used as a starting point for preparing this one.
## How to use example
@@ -36,34 +36,27 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui
## Example Output
First run:
```
Restart counter = 0
Run time:
Nothing saved yet!
...
I (288) main_task: Calling app_main()
I (298) nvs_blob_example: Saving test data blob...
I (308) nvs_blob_example:
Reading updated blob data:
I (308) nvs_blob_example: Reading test data blob:
I (308) nvs_blob_example: ID: 123
I (308) nvs_blob_example: Name: Test Sample
I (308) nvs_blob_example: Values: 3.140, 2.718, -0.000, 0.000
I (318) nvs_blob_example: Flags: 0xABCD1234
I (318) nvs_blob_example: Counts: -100, 100
I (328) nvs_blob_example: Active: true
I (328) nvs_blob_example:
Reading array data blob:
I (338) nvs_blob_example: Array[0] = 30
I (338) nvs_blob_example: Array[1] = 20
I (338) nvs_blob_example:
Blob operations completed. Monitoring GPIO for reset...
I (348) gpio: GPIO[0]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
...
```
At this point, press "Boot" button and hold it for a second. The board will perform software restart, printing:
```
Restarting...
```
After booting again, restart counter and run time array will be printed:
```
Restart counter = 1
Run time:
1: 5110
```
After pressing "Boot" once more:
```
Restart counter = 2
Run time:
1: 5110
2: 5860
```
To reset the counter and run time array, erase the contents of flash memory using `idf.py erase-flash`, then upload the program again as described above.
To reset nvs data, erase the contents of flash memory using `idf.py erase-flash`, then upload the program again as described above.

View File

@@ -19,11 +19,15 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "nvs.h"
#include "driver/gpio.h"
#define STORAGE_NAMESPACE "storage"
#define BLOB_EXAMPLE_DATA_SIZE 256
static const char *TAG = "nvs_blob_example";
#if CONFIG_IDF_TARGET_ESP32C3
#define BOOT_MODE_PIN GPIO_NUM_9
@@ -31,96 +35,60 @@
#define BOOT_MODE_PIN GPIO_NUM_0
#endif //CONFIG_IDF_TARGET_ESP32C3
/* Save the number of module restarts in NVS
by first reading and then incrementing
the number that has been saved previously.
Return an error if anything goes wrong
during this process.
*/
esp_err_t save_restart_counter(void)
/* Test data structure to demonstrate different data types in blob */
typedef struct {
uint8_t id;
char name[32];
float values[2];
uint32_t flags;
int16_t counts[2];
bool active;
} test_data_t;
/* Save test data as a blob in NVS */
esp_err_t save_test_data(void)
{
nvs_handle_t my_handle;
esp_err_t err;
// Open
// Create sample test data
test_data_t test_data = {
.id = 123,
.name = "Test Sample",
.values = {3.14f, 2.718f},
.flags = 0xABCD1234,
.counts = {-100, 100},
.active = true
};
// Open NVS handle
err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle);
if (err != ESP_OK) return err;
// Read
int32_t restart_counter = 0; // value will default to 0, if not set yet in NVS
err = nvs_get_i32(my_handle, "restart_conter", &restart_counter);
if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err;
// Write
restart_counter++;
err = nvs_set_i32(my_handle, "restart_conter", restart_counter);
if (err != ESP_OK) return err;
// Commit written value.
// After setting any values, nvs_commit() must be called to ensure changes are written
// to flash storage. Implementations may write to storage at other times,
// but this is not guaranteed.
err = nvs_commit(my_handle);
if (err != ESP_OK) return err;
// Close
nvs_close(my_handle);
return ESP_OK;
}
/* Save new run time value in NVS
by first reading a table of previously saved values
and then adding the new value at the end of the table.
Return an error if anything goes wrong
during this process.
*/
esp_err_t save_run_time(void)
{
nvs_handle_t my_handle;
esp_err_t err;
// Open
err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle);
if (err != ESP_OK) return err;
// Read the size of memory space required for blob
size_t required_size = 0; // value will default to 0, if not set yet in NVS
err = nvs_get_blob(my_handle, "run_time", NULL, &required_size);
if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err;
// Read previously saved blob if available
uint32_t* run_time = malloc(required_size + sizeof(uint32_t));
if (required_size > 0) {
err = nvs_get_blob(my_handle, "run_time", run_time, &required_size);
if (err != ESP_OK) {
free(run_time);
return err;
}
if (err != ESP_OK) {
ESP_LOGE(TAG, "Error (%s) opening NVS handle!", esp_err_to_name(err));
return err;
}
// Write value including previously saved blob if available
required_size += sizeof(uint32_t);
run_time[required_size / sizeof(uint32_t) - 1] = xTaskGetTickCount() * portTICK_PERIOD_MS;
err = nvs_set_blob(my_handle, "run_time", run_time, required_size);
free(run_time);
if (err != ESP_OK) return err;
// Write blob
ESP_LOGI(TAG, "Saving test data blob...");
err = nvs_set_blob(my_handle, "test_data", &test_data, sizeof(test_data_t));
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to write test data blob!");
nvs_close(my_handle);
return err;
}
// Commit
err = nvs_commit(my_handle);
if (err != ESP_OK) return err;
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to commit data");
}
// Close
nvs_close(my_handle);
return ESP_OK;
return err;
}
/* Read from NVS and print restart counter
and the table with run times.
Return an error if anything goes wrong
during this process.
*/
esp_err_t print_what_saved(void)
/* Example of storing and appending array data as a blob */
esp_err_t save_array_data(void)
{
nvs_handle_t my_handle;
esp_err_t err;
@@ -129,70 +97,137 @@ esp_err_t print_what_saved(void)
err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle);
if (err != ESP_OK) return err;
// Read restart counter
int32_t restart_counter = 0; // value will default to 0, if not set yet in NVS
err = nvs_get_i32(my_handle, "restart_conter", &restart_counter);
if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err;
printf("Restart counter = %" PRIu32 "\n", restart_counter);
// Read run time blob
size_t required_size = 0; // value will default to 0, if not set yet in NVS
// obtain required memory space to store blob being read from NVS
err = nvs_get_blob(my_handle, "run_time", NULL, &required_size);
if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err;
printf("Run time:\n");
if (required_size == 0) {
printf("Nothing saved yet!\n");
} else {
uint32_t* run_time = malloc(required_size);
err = nvs_get_blob(my_handle, "run_time", run_time, &required_size);
if (err != ESP_OK) {
free(run_time);
return err;
}
for (int i = 0; i < required_size / sizeof(uint32_t); i++) {
printf("%d: %" PRIu32 "\n", i + 1, run_time[i]);
}
free(run_time);
// First, get the size of existing data (if any)
size_t required_size = 0;
err = nvs_get_blob(my_handle, "array_data", NULL, &required_size);
if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) {
ESP_LOGE(TAG, "Error (%s) reading array size!", esp_err_to_name(err));
nvs_close(my_handle);
return err;
}
// Allocate memory and read existing data
uint32_t* array_data = malloc(required_size + sizeof(uint32_t));
if (required_size > 0) {
err = nvs_get_blob(my_handle, "array_data", array_data, &required_size);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Error (%s) reading array data!", esp_err_to_name(err));
free(array_data);
nvs_close(my_handle);
return err;
}
}
// Append new value
required_size += sizeof(uint32_t);
array_data[required_size / sizeof(uint32_t) - 1] = xTaskGetTickCount() * portTICK_PERIOD_MS;
// Save updated array
err = nvs_set_blob(my_handle, "array_data", array_data, required_size);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Error (%s) saving array data!", esp_err_to_name(err));
}
free(array_data);
// Commit
err = nvs_commit(my_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Error (%s) committing data!", esp_err_to_name(err));
}
nvs_close(my_handle);
return err;
}
/* Read and display all saved blobs */
esp_err_t read_stored_blobs(void)
{
nvs_handle_t my_handle;
esp_err_t err;
err = nvs_open(STORAGE_NAMESPACE, NVS_READONLY, &my_handle);
if (err != ESP_OK) return err;
// 1. Read test data blob
ESP_LOGI(TAG, "Reading test data blob:");
test_data_t test_data;
size_t test_data_size = sizeof(test_data_t);
err = nvs_get_blob(my_handle, "test_data", &test_data, &test_data_size);
if (err == ESP_OK) {
ESP_LOGI(TAG, "ID: %d", test_data.id);
ESP_LOGI(TAG, "Name: %s", test_data.name);
ESP_LOGI(TAG, "Values: %.3f, %.3f, %.3f, %.3f",
test_data.values[0], test_data.values[1],
test_data.values[2], test_data.values[3]);
ESP_LOGI(TAG, "Flags: 0x%08" PRIX32, test_data.flags);
ESP_LOGI(TAG, "Counts: %d, %d", test_data.counts[0], test_data.counts[1]);
ESP_LOGI(TAG, "Active: %s", test_data.active ? "true" : "false");
} else if (err == ESP_ERR_NVS_NOT_FOUND) {
ESP_LOGW(TAG, "Test data not found!");
}
// 2. Read array data blob
ESP_LOGI(TAG, "\nReading array data blob:");
size_t required_size = 0;
err = nvs_get_blob(my_handle, "array_data", NULL, &required_size);
if (err == ESP_OK) {
uint32_t* array_data = malloc(required_size);
err = nvs_get_blob(my_handle, "array_data", array_data, &required_size);
if (err == ESP_OK) {
for (int i = 0; i < required_size / sizeof(uint32_t); i++) {
ESP_LOGI(TAG, "Array[%d] = %" PRIu32, i, array_data[i]);
}
}
free(array_data);
} else if (err == ESP_ERR_NVS_NOT_FOUND) {
ESP_LOGW(TAG, "Array data not found!");
}
// Close
nvs_close(my_handle);
return ESP_OK;
}
void app_main(void)
{
// Initialize NVS
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
// NVS partition was truncated and needs to be erased
// Retry nvs_flash_init
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}
ESP_ERROR_CHECK( err );
ESP_ERROR_CHECK(err);
err = print_what_saved();
if (err != ESP_OK) printf("Error (%s) reading data from NVS!\n", esp_err_to_name(err));
// Save new test data
err = save_test_data();
if (err != ESP_OK) {
ESP_LOGE(TAG, "Error (%s) saving test data!", esp_err_to_name(err));
}
err = save_restart_counter();
if (err != ESP_OK) printf("Error (%s) saving restart counter to NVS!\n", esp_err_to_name(err));
// Save new array data
err = save_array_data();
if (err != ESP_OK) {
ESP_LOGE(TAG, "Error (%s) saving array data!", esp_err_to_name(err));
}
// Read updated data
ESP_LOGI(TAG, "\nReading updated blob data:");
err = read_stored_blobs();
if (err != ESP_OK) {
ESP_LOGE(TAG, "Error (%s) reading updated data!", esp_err_to_name(err));
}
ESP_LOGI(TAG, "\nBlob operations completed. Monitoring GPIO for reset...");
// Setup GPIO for reset monitoring
gpio_reset_pin(BOOT_MODE_PIN);
gpio_set_direction(BOOT_MODE_PIN, GPIO_MODE_INPUT);
/* Read the status of GPIO0. If GPIO0 is LOW for longer than 1000 ms,
then save module's run time and restart it
*/
while (1) {
if (gpio_get_level(BOOT_MODE_PIN) == 0) {
vTaskDelay(1000 / portTICK_PERIOD_MS);
if(gpio_get_level(BOOT_MODE_PIN) == 0) {
err = save_run_time();
if (err != ESP_OK) printf("Error (%s) saving run time blob to NVS!\n", esp_err_to_name(err));
printf("Restarting...\n");
fflush(stdout);
ESP_LOGI(TAG, "Reset button pressed, restarting...");
esp_restart();
}
}

View File

@@ -1,11 +1,5 @@
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import logging
import random
import re
import time
from typing import List
import pytest
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
@@ -14,28 +8,12 @@ from pytest_embedded_idf.utils import idf_parametrize
@pytest.mark.generic
@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target'])
def test_examples_nvs_rw_blob(dut: Dut) -> None:
def expect_start_msg(index: int) -> None:
dut.expect('Restart counter = {}'.format(index), timeout=10)
dut.expect('Run time:', timeout=10)
expect_start_msg(0)
dut.expect('Nothing saved yet!', timeout=5)
nvs_store: List[str] = []
for i in range(1, 10):
time.sleep(random.uniform(0.1, 2)) # in order to randomize the runtimes stored in NVS
try:
# Pulling pin low using DTR
dut.serial.proc.setDTR(True)
dut.expect('Restarting...', timeout=5) # the application waits for a second
finally:
dut.serial.proc.setDTR(False)
expect_start_msg(i)
for store_item in nvs_store:
dut.expect(store_item.encode(), timeout=10)
logging.info('Received: {}'.format(', '.join(nvs_store)))
new_runtime = (dut.expect(re.compile(str.encode('{}: (\\d+)'.format(i))), timeout=10)[0]).decode()
nvs_store.append(new_runtime)
logging.info('loop {} has finished with runtime {}'.format(i, new_runtime))
# Save and read test data
dut.expect('Saving test data blob...', timeout=20)
# Save array data
# Read updated data
dut.expect('Reading updated blob data:', timeout=20)
dut.expect('Reading test data blob:', timeout=20)
# Verify array data reading
dut.expect('Reading array data blob:', timeout=20)
dut.expect('Blob operations completed. Monitoring GPIO for reset...', timeout=20)

View File

@@ -13,7 +13,7 @@ Example also shows how to check if read / write operation was successful, or cer
Detailed functional description of NVS and API is provided in [documentation](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/storage/nvs_flash.html).
Check another example *storage/nvs_rw_blob*, which shows how to read and write variable length binary data (blob).
Check another example *storage/nvs/nvs_rw_blob*, which shows how to read and write variable length binary data (blob).
## How to use example
@@ -35,50 +35,32 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui
## Example Output
First run:
```
Opening Non-Volatile Storage (NVS) handle... Done
Reading restart counter from NVS ... The value is not initialized yet!
Updating restart counter in NVS ... Done
Committing updates in NVS ... Done
Restarting in 10 seconds...
Restarting in 9 seconds...
Restarting in 8 seconds...
Restarting in 7 seconds...
Restarting in 6 seconds...
Restarting in 5 seconds...
Restarting in 4 seconds...
Restarting in 3 seconds...
Restarting in 2 seconds...
Restarting in 1 seconds...
Restarting in 0 seconds...
Restarting now.
...
I (296) nvs_example:
Opening Non-Volatile Storage (NVS) handle...
I (296) nvs_example:
Writing counter to NVS...
I (306) nvs_example:
Reading counter from NVS...
I (306) nvs_example: Read counter = 42
I (306) nvs_example:
Writing string to NVS...
I (306) nvs_example:
Reading string from NVS...
I (306) nvs_example: Read string: Hello from NVS!
I (316) nvs_example:
Finding keys in NVS...
I (316) nvs_example: Key: 'message', Type: str
I (316) nvs_example: Key: 'counter', Type: i32
I (326) nvs_example:
Deleting key from NVS...
I (336) nvs_example:
Committing updates in NVS...
I (336) nvs_example: NVS handle closed.
I (336) nvs_example: Returned to app_main
I (346) main_task: Returned from app_main()
...
```
Subsequent runs:
```
Opening Non-Volatile Storage (NVS) handle... Done
Reading restart counter from NVS ... Done
Restart counter = 1
Updating restart counter in NVS ... Done
Committing updates in NVS ... Done
Restarting in 10 seconds...
Restarting in 9 seconds...
Restarting in 8 seconds...
Restarting in 7 seconds...
Restarting in 6 seconds...
Restarting in 5 seconds...
Restarting in 4 seconds...
Restarting in 3 seconds...
Restarting in 2 seconds...
Restarting in 1 seconds...
Restarting in 0 seconds...
Restarting now.
```
Restart counter will increment on each run.
To reset the counter, erase the contents of flash memory using `idf.py erase-flash`, then upload the program again as described above.
To reset nvs data, erase the contents of flash memory using `idf.py erase-flash`, then upload the program again as described above.

View File

@@ -19,9 +19,45 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "nvs.h"
static const char *TAG = "nvs_example";
typedef struct {
nvs_type_t type;
const char *str;
} type_str_pair_t;
static const type_str_pair_t type_str_pair[] = {
{ NVS_TYPE_I8, "i8" },
{ NVS_TYPE_U8, "u8" },
{ NVS_TYPE_U16, "u16" },
{ NVS_TYPE_I16, "i16" },
{ NVS_TYPE_U32, "u32" },
{ NVS_TYPE_I32, "i32" },
{ NVS_TYPE_U64, "u64" },
{ NVS_TYPE_I64, "i64" },
{ NVS_TYPE_STR, "str" },
{ NVS_TYPE_BLOB, "blob" },
{ NVS_TYPE_ANY, "any" },
};
static const size_t TYPE_STR_PAIR_SIZE = sizeof(type_str_pair) / sizeof(type_str_pair[0]);
static const char *type_to_str(nvs_type_t type)
{
for (int i = 0; i < TYPE_STR_PAIR_SIZE; i++) {
const type_str_pair_t *p = &type_str_pair[i];
if (p->type == type) {
return p->str;
}
}
return "Unknown";
}
void app_main(void)
{
// Initialize NVS
@@ -32,60 +68,94 @@ void app_main(void)
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}
ESP_ERROR_CHECK( err );
ESP_ERROR_CHECK(err);
// Open
printf("\n");
printf("Opening Non-Volatile Storage (NVS) handle... ");
// Open NVS handle
ESP_LOGI(TAG, "\nOpening Non-Volatile Storage (NVS) handle...");
nvs_handle_t my_handle;
err = nvs_open("storage", NVS_READWRITE, &my_handle);
if (err != ESP_OK) {
printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err));
} else {
printf("Done\n");
ESP_LOGE(TAG, "Error (%s) opening NVS handle!", esp_err_to_name(err));
return;
}
// Read
printf("Reading restart counter from NVS ... ");
int32_t restart_counter = 0; // value will default to 0, if not set yet in NVS
err = nvs_get_i32(my_handle, "restart_counter", &restart_counter);
switch (err) {
case ESP_OK:
printf("Done\n");
printf("Restart counter = %" PRIu32 "\n", restart_counter);
break;
case ESP_ERR_NVS_NOT_FOUND:
printf("The value is not initialized yet!\n");
break;
default :
printf("Error (%s) reading!\n", esp_err_to_name(err));
// Store and read an integer value
int32_t counter = 42;
ESP_LOGI(TAG, "\nWriting counter to NVS...");
err = nvs_set_i32(my_handle, "counter", counter);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to write counter!");
}
// Read back the value
int32_t read_counter = 0;
ESP_LOGI(TAG, "\nReading counter from NVS...");
err = nvs_get_i32(my_handle, "counter", &read_counter);
switch (err) {
case ESP_OK:
ESP_LOGI(TAG, "Read counter = %" PRIu32, read_counter);
break;
case ESP_ERR_NVS_NOT_FOUND:
ESP_LOGW(TAG, "The value is not initialized yet!");
break;
default:
ESP_LOGE(TAG, "Error (%s) reading!", esp_err_to_name(err));
}
// Store and read a string
ESP_LOGI(TAG, "\nWriting string to NVS...");
err = nvs_set_str(my_handle, "message", "Hello from NVS!");
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to write string!");
}
// Read back the string
size_t required_size = 0;
ESP_LOGI(TAG, "\nReading string from NVS...");
err = nvs_get_str(my_handle, "message", NULL, &required_size);
if (err == ESP_OK) {
char* message = malloc(required_size);
err = nvs_get_str(my_handle, "message", message, &required_size);
if (err == ESP_OK) {
ESP_LOGI(TAG, "Read string: %s", message);
}
// Write
printf("Updating restart counter in NVS ... ");
restart_counter++;
err = nvs_set_i32(my_handle, "restart_counter", restart_counter);
printf((err != ESP_OK) ? "Failed!\n" : "Done\n");
// Commit written value.
// After setting any values, nvs_commit() must be called to ensure changes are written
// to flash storage. Implementations may write to storage at other times,
// but this is not guaranteed.
printf("Committing updates in NVS ... ");
err = nvs_commit(my_handle);
printf((err != ESP_OK) ? "Failed!\n" : "Done\n");
// Close
nvs_close(my_handle);
free(message);
}
printf("\n");
// Restart module
for (int i = 10; i >= 0; i--) {
printf("Restarting in %d seconds...\n", i);
vTaskDelay(1000 / portTICK_PERIOD_MS);
// Find keys in NVS
ESP_LOGI(TAG, "\nFinding keys in NVS...");
nvs_iterator_t it = NULL;
esp_err_t res = nvs_entry_find("nvs", "storage", NVS_TYPE_ANY, &it);
while(res == ESP_OK) {
nvs_entry_info_t info;
nvs_entry_info(it, &info);
const char *type_str = type_to_str(info.type);
ESP_LOGI(TAG, "Key: '%s', Type: %s", info.key, type_str);
res = nvs_entry_next(&it);
}
printf("Restarting now.\n");
fflush(stdout);
esp_restart();
nvs_release_iterator(it);
// Delete a key from NVS
ESP_LOGI(TAG, "\nDeleting key from NVS...");
err = nvs_erase_key(my_handle, "counter");
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to erase key!");
}
// Commit changes
// After setting any values, nvs_commit() must be called to ensure changes are written
// to flash storage. Implementations may write to storage at other times,
// but this is not guaranteed.
ESP_LOGI(TAG, "\nCommitting updates in NVS...");
err = nvs_commit(my_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to commit NVS changes!");
}
// Close
nvs_close(my_handle);
ESP_LOGI(TAG, "NVS handle closed.");
ESP_LOGI(TAG, "Returned to app_main");
}

View File

@@ -1,8 +1,5 @@
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import logging
from itertools import zip_longest
import pytest
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
@@ -13,11 +10,14 @@ from pytest_embedded_idf.utils import idf_parametrize
def test_examples_nvs_rw_value(dut: Dut) -> None:
dut.serial.erase_flash()
dut.serial.flash()
for i, counter_state in zip_longest(range(4), ('The value is not initialized yet!',), fillvalue='Done'):
dut.expect('Opening Non-Volatile Storage \\(NVS\\) handle... Done', timeout=20)
dut.expect('Reading restart counter from NVS ... {}'.format(counter_state), timeout=20)
dut.expect('Restart counter = {}'.format(i) if int(i) > 0 else '', timeout=20)
dut.expect('Updating restart counter in NVS ... Done', timeout=20)
dut.expect('Committing updates in NVS ... Done', timeout=20)
dut.expect('Restarting in 10 seconds...', timeout=20)
logging.info('loop {} has finished'.format(i))
dut.expect('Opening Non-Volatile Storage \\(NVS\\) handle...', timeout=20)
dut.expect('Writing counter to NVS...', timeout=20)
dut.expect('Reading counter from NVS...', timeout=20)
dut.expect('Writing string to NVS...', timeout=20)
dut.expect('Reading string from NVS...', timeout=20)
dut.expect('Finding keys in NVS...', timeout=20)
dut.expect('Deleting key from NVS...', timeout=20)
dut.expect('Committing updates in NVS...', timeout=20)
dut.expect('NVS handle closed.', timeout=20)
dut.expect('Returned to app_main', timeout=20)