docs: Update CN translation for nvs_flash.rst

This commit is contained in:
Zhang Shuxian
2026-07-31 12:11:45 +08:00
parent c6c0734a7b
commit f9ba81e396
2 changed files with 85 additions and 47 deletions

View File

@@ -35,7 +35,7 @@ NVS operates on key-value pairs. Keys are ASCII strings; the maximum key length
- integer types: ``uint8_t``, ``int8_t``, ``uint16_t``, ``int16_t``, ``uint32_t``, ``int32_t``, ``uint64_t``, ``int64_t``
- floating point types: ``float`` and ``double``
- zero-terminated C-like string
- variable length binary data - blob
- variable length binary data - BLOB
.. note::
@@ -64,12 +64,12 @@ The maximum size of a single stored value depends on its data type:
- Fixed by the type (1 to 8 bytes); always stored in a single entry.
* - String
- 4000 bytes, including the null terminator.
* - Blob
* - BLOB
- 508,000 bytes, or 97.6% of the partition size minus 4000 bytes, whichever is lower.
.. note::
The string and blob limits above are absolute upper bounds valid on an empty (non-fragmented) data partition. The size that can actually be stored at run time is typically lower and depends on how the partition is fragmented. See :ref:`nvs_space_consumption` for how NVS allocates entries and why fragmentation matters.
The string and BLOB limits above are absolute upper bounds valid on an empty (non-fragmented) data partition. The size that can actually be stored at run time is typically lower and depends on how the partition is fragmented. See :ref:`nvs_space_consumption` for how NVS allocates entries and why fragmentation matters.
Namespaces
^^^^^^^^^^
@@ -89,7 +89,7 @@ The open mode parameter controls the access level and security behavior:
NVS Iterators
^^^^^^^^^^^^^
Iterators allow to list key-value pairs stored in NVS, based on specified partition name, namespace, and data type.
Iterators allow listing key-value pairs stored in NVS, based on specified partition name, namespace, and data type.
There are the following functions available:
@@ -113,7 +113,7 @@ Security, Tampering, and Robustness
NVS is not directly compatible with the {IDF_TARGET_NAME} flash encryption system. However, data can still be stored in encrypted form if NVS encryption is used together with {IDF_TARGET_NAME} flash encryption or with the help of the HMAC peripheral. Please refer to :doc:`nvs_encryption` for more details.
If NVS encryption is not used, it is possible for anyone with physical access to the flash chip to read, alter, erase, or add key-value pairs. With NVS encryption enabled, it is not possible to read, alter or add a key-value pair and get recognized as a valid pair without knowing corresponding NVS encryption keys. However, there is no tamper-resistance against the erase operation.
If NVS encryption is not used, it is possible for anyone with physical access to the flash chip to read, alter, erase, or add key-value pairs. With NVS encryption enabled, it is not possible to read, alter, or add a key-value pair and get recognized as a valid pair without knowing corresponding NVS encryption keys. However, there is no tamper-resistance against the erase operation.
The library does try to recover from conditions when flash memory is in an inconsistent state. In particular, one should be able to power off the device at any point and time and then power it back on. This should not result in loss of data, except for the new key-value pair if it was being written at the moment of powering off. The library should also be able to initialize properly with any random data present in flash memory.
@@ -184,7 +184,7 @@ To address this issue, the Kconfig option :ref:`CONFIG_NVS_FLASH_VERIFY_ERASE` e
.. note::
When NVS is initialized on the writeable partition, the library will attempt to perform recovery operations if the partition is found to be in an inconsistent state. This may involve erasing and rewriting some pages and in continuously unstable power environment subsequently lead to the unintended loss of factory default data. For this reason, it is recommended to keep vital factory default data in separate, read-only partition where the recovery is not performed.
When NVS is initialized on a writable partition, the library will attempt to perform recovery operations if the partition is found to be in an inconsistent state. This may involve erasing and rewriting some pages and, in a continuously unstable power environment, subsequently lead to the unintended loss of factory default data. For this reason, it is recommended to keep vital factory default data in a separate, read-only partition where the recovery is not performed.
.. _nvs_bootloader:
@@ -231,7 +231,7 @@ Instead of calling the ``nvs_partition_gen.py`` tool manually, the creation of t
* - Parameter
- Description
* - ``FLASH_IN_PROJECT``
- Name of the NVS partition
- Flash the generated image together with the project
* - ``DEPENDS``
- Specify files on which the command depends
@@ -255,7 +255,7 @@ You can find code examples in the :example:`storage/nvs` directory of ESP-IDF ex
:example:`storage/nvs/nvs_rw_blob`
Demonstrates how to read a single integer value and a blob (binary large object), and write them to NVS to preserve this value between {IDF_TARGET_NAME} module restarts.
Demonstrates how to read a single integer value and a BLOB (Binary Large Object), and write them to NVS to preserve this value between {IDF_TARGET_NAME} module restarts.
* value - tracks the number of the {IDF_TARGET_NAME} module soft and hard restarts.
* blob - contains a table with module run times. The table is read from NVS to dynamically allocated RAM. A new run time is added to the table on each manually triggered soft restart, and then the added run time is written to NVS. Triggering is done by pulling down GPIO0.
@@ -274,7 +274,7 @@ You can find code examples in the :example:`storage/nvs` directory of ESP-IDF ex
Usage statistics are obtained prior to and post writing, with the differences being compared to expected values of newly used entries.
The second part of example shows the effect of NVS partition fragmentation to the blob storage overhead.
The second part of example shows the effect of NVS partition fragmentation to the BLOB storage overhead.
:example:`storage/nvs/nvs_iteration`
@@ -296,7 +296,7 @@ NVS stores key-value pairs sequentially, with new key-value pairs being added at
.. note::
The NVS component includes flash wear levelling by design. Set operations append new data to the free space after existing entries, and invalidation of old values does not trigger immediate flash erase operations. The organization of NVS space into pages and entries reduces the frequency of flash erase to flash write operations for data types fitting one entry by up to a factor of 126 in the ideal case (one page of single-entry writes per erase). The actual factor is lower in practice and is primarily driven by how full the partition is: as live data grows, NVS space reclaim runs more often, and the erase/write ratio worsens. Large, never-overwritten data chunks may occupy the same NVS page indefinitely — reclaim only selects pages that contain erased entries, so such pages never participate in the erase cycle and therefore reduce the share of flash memory subject to wear levelling.
The NVS component includes flash wear leveling by design. Set operations append new data to the free space after existing entries, and invalidation of old values does not trigger immediate flash erase operations. The organization of NVS space into pages and entries reduces the frequency of flash erase to flash write operations for data types fitting one entry by up to a factor of 126 in the ideal case (one page of single-entry writes per erase). The actual factor is lower in practice and is primarily driven by how full the partition is: as live data grows, NVS space reclaim runs more often, and the erase/write ratio worsens. Large, never-overwritten data chunks may occupy the same NVS page indefinitely — reclaim only selects pages that contain erased entries, so such pages never participate in the erase cycle and therefore reduce the share of flash memory subject to wear leveling.
Pages and Entries
^^^^^^^^^^^^^^^^^
@@ -340,7 +340,7 @@ Structure of a Page
For now, we assume that flash sector size is 4096 bytes and that {IDF_TARGET_NAME} flash encryption hardware operates on 32-byte blocks. It is possible to introduce some settings configurable at compile-time (e.g., via menuconfig) to accommodate flash chips with different sector sizes (although it is not clear if other components in the system, e.g., SPI flash driver and SPI flash cache can support these other sizes).
Page consists of three parts: header, entry state bitmap, and entries themselves. To be compatible with {IDF_TARGET_NAME} flash encryption, the entry size is 32 bytes. For integer types, an entry holds one key-value pair. For strings and blobs, an entry holds part of key-value pair (more on that in the entry structure description).
Page consists of three parts: header, entry state bitmap, and entries themselves. To be compatible with {IDF_TARGET_NAME} flash encryption, the entry size is 32 bytes. For integer types, an entry holds one key-value pair. For strings and BLOBs, an entry holds part of key-value pair (more on that in the entry structure description).
The following diagram illustrates the page structure. Numbers in parentheses indicate the size of each part in bytes.
@@ -391,7 +391,7 @@ Erased (2'b00)
Structure of Entry
^^^^^^^^^^^^^^^^^^
For values of primitive types (currently integers from 1 to 8 bytes long), entry holds one key-value pair. For string and blob types, entry holds part of the whole key-value pair. For strings, in case when a key-value pair spans multiple entries, all entries are stored in the same page. Blobs are allowed to span over multiple pages by dividing them into smaller chunks. For tracking these chunks, an additional fixed length metadata entry is stored called "blob index". Earlier formats of blobs are still supported (can be read and modified). However, once the blobs are modified, they are stored using the new format.
For values of primitive types (currently integers from 1 to 8 bytes long), entry holds one key-value pair. For string and BLOB types, entry holds part of the whole key-value pair. For strings, in case when a key-value pair spans multiple entries, all entries are stored in the same page. BLOBs are allowed to span over multiple pages by dividing them into smaller chunks. For tracking these chunks, an additional fixed length metadata entry is stored called "BLOB index". Earlier formats of BLOBs are still supported (can be read and modified). However, once the BLOBs are modified, they are stored using the new format.
::
@@ -405,11 +405,11 @@ For values of primitive types (currently integers from 1 to 8 bytes long), entry
+-> Fixed length --
| | +---------+--------------+---------------+-------+
| +--------> | Size(4) | ChunkCount(1)| ChunkStart(1) | Rsv(2)|
Data format ---+ Blob Index +---------+--------------+---------------+-------+
Data format ---+ BLOB Index +---------+--------------+---------------+-------+
|
| +----------+---------+-----------+
+-> Variable length --> | Size (2) | Rsv (2) | CRC32 (4) |
(Strings, Blob Data) +----------+---------+-----------+
(Strings, BLOB Data) +----------+---------+-----------+
Individual fields in entry structure have the following meanings:
@@ -421,10 +421,10 @@ Type
One byte indicating the value data type. See the :cpp:type:`ItemType` enumeration in :component_file:`nvs_flash/include/nvs_handle.hpp` for possible values.
Span
Number of entries used by this key-value pair. For integer types, this is equal to 1. For strings and blobs, this depends on value length.
Number of entries used by this key-value pair. For integer types, this is equal to 1. For strings and BLOBs, this depends on value length.
ChunkIndex
Used to store the index of a blob-data chunk for blob types. For other types, this should be ``0xff``.
Used to store the index of a BLOB-data chunk for BLOB types. For other types, this should be ``0xff``.
CRC32
Checksum calculated over all the bytes in this entry, except for the CRC32 field itself.
@@ -435,26 +435,26 @@ Key
Data
For integer types, this field contains the value itself. If the value itself is shorter than 8 bytes, it is padded to the right, with unused bytes filled with ``0xff``.
For "blob index" entry, these 8 bytes hold the following information about data-chunks:
For "BLOB index" entry, these 8 bytes hold the following information about data-chunks:
- Size
(Only for blob index.) Size, in bytes, of complete blob data.
(Only for BLOB index.) Size, in bytes, of complete BLOB data.
- ChunkCount
(Only for blob index.) Total number of blob-data chunks into which the blob was divided during storage.
(Only for BLOB index.) Total number of BLOB-data chunks into which the BLOB was divided during storage.
- ChunkStart
(Only for blob index.) ChunkIndex of the first blob-data chunk of this blob. Subsequent chunks have chunkIndex incrementally allocated (step of 1).
(Only for BLOB index.) ChunkIndex of the first BLOB-data chunk of this BLOB. Subsequent chunks have chunkIndex incrementally allocated (step of 1).
For string and blob data chunks, these 8 bytes hold additional data about the value, which are described below:
For string and BLOB data chunks, these 8 bytes hold additional data about the value, which are described below:
- Size
(Only for strings and blobs.) Size, in bytes, of actual data. For strings, this includes zero terminators.
(Only for strings and BLOBs.) Size, in bytes, of actual data. For strings, this includes zero terminators.
- CRC32
(Only for strings and blobs.) Checksum calculated over all bytes of data.
(Only for strings and BLOBs.) Checksum calculated over all bytes of data.
Variable length values (strings and blobs) are written into subsequent entries, 32 bytes per entry. The ``Span`` field of the first entry indicates how many entries are used.
Variable length values (strings and BLOBs) are written into subsequent entries, 32 bytes per entry. The ``Span`` field of the first entry indicates how many entries are used.
.. _nvs_space_consumption:
@@ -466,14 +466,14 @@ NVS stores every record as one or more 32-byte entries within a 4096-byte data p
- Integer and floating point values use one self-contained entry; a single free entry available anywhere is enough to store them.
- A string uses one metadata entry followed by ``ceil(payload_size / entry_size)`` data entries (the null terminator counts toward the payload). All of them have to be available as a contiguous run within a single page.
- A blob uses one ``BLOB_INDEX`` metadata entry plus one or more data chunks; each chunk is a metadata entry followed by its payload entries and lives on a different page. Storing a blob therefore needs ``1 + k + ceil(blob_size / entry_size)`` entries, where ``k`` is the number of pages the data is split across.
- A BLOB uses one ``BLOB_INDEX`` metadata entry plus one or more data chunks; each chunk is a metadata entry followed by its payload entries and lives on a different page. Storing a BLOB therefore needs ``1 + k + ceil(blob_size / entry_size)`` entries, where ``k`` is the number of pages the data is split across.
Before setting a new key-value pair or updating an existing one, NVS looks for a page with enough free (or reclaimable) entries. The space reclaim algorithm is designed for sudden-power-off resiliency and consolidates free space on a single candidate page per call, so the largest contiguous run of available entries is determined on a per-page basis. This has two consequences:
- The effective maximum string length is bound by the highest sum of free and deleted entries offered by any single page.
- A blob is split into chunks sized to the entries available on each page after reclaim, and the split continues until the whole value is stored. This lets NVS reuse pages with as few as two free entries, at the cost of one metadata entry per chunk. In the extreme case, the metadata overhead can exceed 100% of the payload size.
- A BLOB is split into chunks sized to the entries available on each page after reclaim, and the split continues until the whole value is stored. This lets NVS reuse pages with as few as two free entries, at the cost of one metadata entry per chunk. In the extreme case, the metadata overhead can exceed 100% of the payload size.
Because of this per-page behavior, the actual limits are lower than the absolute maximums listed in `Record Size Limitations`_ and get tighter as the partition fills up and fragments. The related effect on flash endurance is described in the wear levelling note under `Log of Key-Value Pairs`_.
Because of this per-page behavior, the actual limits are lower than the absolute maximums listed in `Record Size Limitations`_ and get tighter as the partition fills up and fragments. The related effect on flash endurance is described in the wear leveling note under `Log of Key-Value Pairs`_.
.. note::