diff --git a/components/nvs_flash/host_test/nvs_page_test/main/test_fixtures.hpp b/components/nvs_flash/host_test/nvs_page_test/main/test_fixtures.hpp index 6561dc6458..5a50ba65fe 100644 --- a/components/nvs_flash/host_test/nvs_page_test/main/test_fixtures.hpp +++ b/components/nvs_flash/host_test/nvs_page_test/main/test_fixtures.hpp @@ -110,7 +110,7 @@ public: size_t columns = size / column_size; size_t column; - for(column = 0; column < columns; column = column + 1) + for(column = 0; column < columns; ++column) { // read column if((err = esp_partition_read_raw(&esp_partition, dst_offset + (column * column_size), buff, column_size)) != ESP_OK) return err; diff --git a/components/nvs_flash/src/nvs_pagemanager.cpp b/components/nvs_flash/src/nvs_pagemanager.cpp index 9bbe32c98a..39017464ea 100644 --- a/components/nvs_flash/src/nvs_pagemanager.cpp +++ b/components/nvs_flash/src/nvs_pagemanager.cpp @@ -124,8 +124,8 @@ esp_err_t PageManager::load(Partition *partition, uint32_t baseSector, uint32_t } } - // partition should have at least one free page - if (mFreePageList.empty()) { + // partition should have at least one free page if it is not read-only + if (!partition->get_readonly() && mFreePageList.empty()) { return ESP_ERR_NVS_NO_FREE_PAGES; } diff --git a/components/partition_table/gen_esp32part.py b/components/partition_table/gen_esp32part.py index cf6993b9ae..05f8233297 100755 --- a/components/partition_table/gen_esp32part.py +++ b/components/partition_table/gen_esp32part.py @@ -7,7 +7,7 @@ # See https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/partition-tables.html # for explanation of partition table structure and uses. # -# SPDX-FileCopyrightText: 2016-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2016-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 import argparse import binascii @@ -31,7 +31,7 @@ SECURE_NONE = None SECURE_V1 = 'v1' SECURE_V2 = 'v2' -__version__ = '1.4' +__version__ = '1.5' APP_TYPE = 0x00 DATA_TYPE = 0x01 @@ -45,6 +45,8 @@ TYPES = { 'data': DATA_TYPE, } +NVS_RW_MIN_PARTITION_SIZE = 0x3000 + def get_ptype_as_int(ptype): """ Convert a string which might be numeric or the name of a partition type to an integer """ @@ -533,6 +535,11 @@ class PartitionDefinition(object): raise ValidationError(self, "'%s' partition of type %s and subtype %s is always read-write and cannot be read-only" % (self.name, self.type, self.subtype)) + if self.type == TYPES['data'] and self.subtype == SUBTYPES[DATA_TYPE]['nvs']: + if self.size < NVS_RW_MIN_PARTITION_SIZE and self.readonly is False: + raise ValidationError(self, """'%s' partition of type %s and subtype %s of this size (0x%x) must be flagged as 'readonly' \ +(the size of read/write NVS has to be at least 0x%x)""" % (self.name, self.type, self.subtype, self.size, NVS_RW_MIN_PARTITION_SIZE)) + STRUCT_FORMAT = b'<2sBBLL16sL' @classmethod diff --git a/docs/en/api-guides/partition-tables.rst b/docs/en/api-guides/partition-tables.rst index b53eea158c..e2d1cd3220 100644 --- a/docs/en/api-guides/partition-tables.rst +++ b/docs/en/api-guides/partition-tables.rst @@ -176,6 +176,7 @@ See enum :cpp:type:`esp_partition_subtype_t` for the full list of subtypes defin - The NVS API can also be used for other application data. - It is strongly recommended that you include an NVS partition of at least 0x3000 bytes in your project. - If using NVS API to store a lot of data, increase the NVS partition size from the default 0x6000 bytes. + - When NVS is used to store factory settings, it is recommended to keep these settings in a separate read-only NVS partition. The minimal size of a read-only NVS partition is 0x1000 bytes. See :ref:`read-only-nvs` for more details. ESP-IDF provides :doc:`NVS Partition Generator Utility ` to generate NVS partitions with factory settings and to flash them along with the application. - ``nvs_keys`` (4) is for the NVS key partition. See :doc:`Non-Volatile Storage (NVS) API <../api-reference/storage/nvs_flash>` for more details. - It is used to store NVS encryption keys when `NVS Encryption` feature is enabled. diff --git a/docs/en/api-reference/storage/nvs_flash.rst b/docs/en/api-reference/storage/nvs_flash.rst index a5025ae972..d96d4c8f44 100644 --- a/docs/en/api-reference/storage/nvs_flash.rst +++ b/docs/en/api-reference/storage/nvs_flash.rst @@ -369,6 +369,14 @@ To reduce the number of reads from flash memory, each member of the Page class m Each node in the hash list contains a 24-bit hash and 8-bit item index. Hash is calculated based on item namespace, key name, and ChunkIndex. CRC32 is used for calculation; the result is truncated to 24 bits. To reduce the overhead for storing 32-bit entries in a linked list, the list is implemented as a double-linked list of arrays. Each array holds 29 entries, for the total size of 128 bytes, together with linked list pointers and a 32-bit count field. The minimum amount of extra RAM usage per page is therefore 128 bytes; maximum is 640 bytes. +.. _read-only-nvs: + +Read-only NVS +^^^^^^^^^^^^^^ + +The default minimal size for NVS to function properly is 12kiB (``0x3000``), meaning there have to be at least 3 pages with one of them being in Empty state. However if the NVS partition is flagged as ``readonly`` in the partition table CSV and is being opened in read-only mode, the partition can be as small as 4kiB (``0x1000``) with only one page in Active state and no Empty page. This is because the library does not need to write any data to the partition in this case. The partition can be used to store data that is not expected to change, such as calibration data or factory settings. Partitions of sizes 0x1000 and 0x2000 are always read-only and partitions of size 0x3000 and above are always read-write capable (still can be opened in read-only mode in the code). + + API Reference ------------- diff --git a/examples/storage/parttool/partitions_example.csv b/examples/storage/parttool/partitions_example.csv index 6c09529c47..e03a43c17e 100644 --- a/examples/storage/parttool/partitions_example.csv +++ b/examples/storage/parttool/partitions_example.csv @@ -3,5 +3,5 @@ nvs, data, nvs, 0x9000, 0x6000, phy_init, data, phy, 0xf000, 0x1000, factory, app, factory, 0x10000, 1M, -custom, data, nvs, , 0x1000, +custom, data, nvs, , 0x1000, readonly storage, data, spiffs, , 0x10000,