]> granicus.if.org Git - esp-idf/blob - components/nvs_flash/README.rst
Initial public version
[esp-idf] / components / nvs_flash / README.rst
1 Non-volatile storage library
2 ============================
3
4 Introduction
5 ------------
6
7 Non-volatile storage (NVS) library is designed to store key-value pairs in flash. This sections introduces some concepts used by NVS.
8
9 Underlying storage
10 ~~~~~~~~~~~~~~~~~~
11
12 Currently NVS uses a portion of main flash memory through ``spi_flash_{read|write|erase}`` APIs. The range of flash sectors to be used by the library is provided to ``nvs_flash_init`` function.
13
14 Future versions of this library may add other storage backends to keep data in another flash chip (SPI or I2C), RTC, FRAM, etc.
15
16 Keys and values
17 ~~~~~~~~~~~~~~~
18
19 NVS operates on key-value pairs. Keys are ASCII strings, maximum key length is currently 15 characters. Values can have one of the following types:
20
21 -  integer types: ``uint8_t``, ``int8_t``, ``uint16_t``, ``int16_t``, ``uint32_t``, ``int32_t``, ``uint64_t``, ``int64_t``
22 -  zero-terminated string
23 -  variable length binary data (blob)
24
25 Additional types, such as ``float`` and ``double`` may be added later.
26
27 Keys are required to be unique. Writing a value for a key which already exists behaves as follows:
28
29 -  if the new value is of the same type as old one, value is updated
30 -  if the new value has different data type, an error is returned
31
32 Data type check is also performed when reading a value. An error is returned if data type of read operation doesn’t match the data type of the value.
33
34 Namespaces
35 ~~~~~~~~~~
36
37 To mitigate potential conflicts in key names between different components, NVS assigns each key-value pair to one of namespaces. Namespace names follow the same rules as key names, i.e. 15 character maximum length. Namespace name is specified in the ``nvs_open`` call. This call returns an opaque handle, which is used in subsequent calls to ``nvs_read_*``, ``nvs_write_*``, and ``nvs_commit`` functions. This way, handle is associated with a namespace, and key names will not collide with same names in other namespaces.
38
39 Security, tampering, and robustness
40 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
41
42 NVS library doesn't implement tamper prevention measures. It is possible for anyone with physical access to the flash chip to alter, erase, or add key-value pairs.
43
44 NVS is compatible with the ESP32 flash encryption system, and it can store  key-value pairs in an encrypted form. Some metadata, like page state and write/erase flags of individual entries can not be encrypted as they are represented as bits of flash memory for efficient access and manipulation. Flash encryption can prevent some forms of modification:
45
46 - replacing keys or values with arbitrary data
47 - changing data types of values
48
49 The following forms of modification are still possible when flash encryption is used:
50
51 - erasing a page completely, removing all key-value pairs which were stored in that page
52 - corrupting data in a page, which will cause the page to be erased automatically when such condition is detected
53 - rolling back the contents of flash memory to an earlier snapshot
54 - merging two snapshots of flash memory, rolling back some key-value pairs to an earlier state (although this is possible to mitigate with the current design — TODO)
55
56 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, expect for the new key-value pair if it was being written at the moment of power off. The library should also be able to initialize properly with any random data present in flash memory.
57
58 Internals
59 ---------
60
61 Log of key-value pairs
62 ~~~~~~~~~~~~~~~~~~~~~~
63
64 NVS stores key-value pairs sequentially, with new key-value pairs being added at the end. When a value of any given key has to be updated, old key-value pair is marked as erased and new key-value pair is added at the end of the log.
65
66 Pages and entries
67 ~~~~~~~~~~~~~~~~~
68
69 NVS library uses two main entities in its operation: pages and entries. Page is a logical structure which stores a portion of the overall log. Logical page corresponds to one physical sector of flash memory. Pages which are in use have a *sequence number* associated with them. Sequence numbers impose an ordering on pages. Higher sequence numbers correspond to pages which were created later. Each page can be in one of the following states:
70
71 Empty/uninitialized
72     Flash storage for the page is empty (all bytes are ``0xff``). Page isn't used to store any data at this point and doesn’t have 
73
74 Active
75     Flash storage is initialized, page header has been written to flash, page has a valid sequence number. Page has some empty entries and data can be written there. Normally only one page can be in this state.
76
77 Full
78     Flash storage is in a consistent state and is filled with key-value pairs.
79     Writing new key-value pairs into this page is not possible. It is still possible to mark some key-value pairs as erased.
80
81 Erasing
82     Non-erased key-value pairs are being moved into another page so that the current page can be erased. This is a transient state, i.e. page should never stay in this state when any API call returns. In case of a sudden power off, move-and-erase process will be completed upon next power on.
83
84 Corrupted
85     Page header contains invalid data, and further parsing of page data was canceled. Any items previously written into this page will not be accessible. Corresponding flash sector will not be erased immediately, and will be kept along with sectors in *uninitialized* state for later use. This may be useful for debugging.
86
87 Mapping from flash sectors to logical pages doesn't have any particular order. Library will inspect sequence numbers of pages found in each flash sector and organize pages in a list based on these numbers.
88
89 ::
90
91     +--------+     +--------+     +--------+     +--------+
92     | Page 1 |     | Page 2 |     | Page 3 |     | Page 4 |
93     | Full   +---> | Full   +---> | Active |     | Empty  |   <- states
94     | #11    |     | #12    |     | #14    |     |        |   <- sequence numbers
95     +---+----+     +----+---+     +----+---+     +---+----+
96         |               |              |             |
97         |               |              |             |
98         |               |              |             |
99     +---v------+  +-----v----+  +------v---+  +------v---+
100     | Sector 3 |  | Sector 0 |  | Sector 2 |  | Sector 1 |    <- physical sectors
101     +----------+  +----------+  +----------+  +----------+
102
103 Structure of a page
104 ~~~~~~~~~~~~~~~~~~~
105
106 For now we assume that flash sector size is 4096 bytes and that ESP32 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).
107
108 Page consists of three parts: header, entry state bitmap, and entries themselves. To be compatible with ESP32 flash encryption, entry size is 32 bytes. For integer types, 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).
109
110 The following diagram illustrates page structure. Numbers in parentheses indicate size of each part in bytes. ::
111
112     +-----------+--------------+-------------+-----------+
113     | State (4) | Seq. no. (4) | Unused (20) | CRC32 (4) | Header (32)
114     +-----------+--------------+-------------+-----------+
115     |                Entry state bitmap (32)             |
116     +----------------------------------------------------+
117     |                       Entry 0 (32)                 |
118     +----------------------------------------------------+
119     |                       Entry 1 (32)                 |
120     +----------------------------------------------------+
121     /                                                    /
122     /                                                    /
123     +----------------------------------------------------+
124     |                       Entry 125 (32)               |
125     +----------------------------------------------------+
126
127 Page header and entry state bitmap are always written to flash unencrypted. Entries are encrypted if flash encryption feature of the ESP32 is used.
128
129 Page state values are defined in such a way that changing state is possible by writing 0 into some of the bits. Therefore it not necessary to erase the page to change page state, unless that is a change to *erased* state.
130
131 CRC32 value in header is calculated over the part which doesn't include state value (bytes 4 to 28). Unused part is currently filled with ``0xff`` bytes. Future versions of the library may store format version there.
132
133 The following sections describe structure of entry state bitmap and entry itself.
134
135 Entry and entry state bitmap
136 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
137
138 Each entry can be in one of the following three states. Each state is represented with two bits in the entry state bitmap. Final four bits in the bitmap (256 - 2 * 126) are unused.
139
140 Empty (2'b11)
141     Nothing is written into the specific entry yet. It is in an uninitialized state (all bytes ``0xff``). 
142
143 Written (2'b10)
144     A key-value pair (or part of key-value pair which spans multiple entries) has been written into the entry.
145
146 Erased (2'b00)
147     A key-value pair in this entry has been discarded. Contents of this entry will not be parsed anymore.
148
149
150 Structure of entry
151 ~~~~~~~~~~~~~~~~~~
152
153 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. In case when a key-value pair spans multiple entries, all entries are stored in the same page.
154
155 ::
156
157     +--------+----------+----------+---------+-----------+---------------+----------+
158     | NS (1) | Type (1) | Span (1) | Rsv (1) | CRC32 (4) |    Key (16)   | Data (8) |
159     +--------+----------+----------+---------+-----------+---------------+----------+
160
161                                                    +--------------------------------+
162                              +->    Fixed length:  | Data (8)                       |
163                              |                     +--------------------------------+
164               Data format ---+
165                              |                     +----------+---------+-----------+
166                              +-> Variable length:  | Size (2) | Rsv (2) | CRC32 (4) |
167                                                    +----------+---------+-----------+
168
169
170 Individual fields in entry structure have the following meanings:
171
172 NS
173     Namespace index for this entry. See section on namespaces implementation for explanation of this value.
174
175 Type
176     One byte indicating data type of value. See ``ItemType`` enumeration in ``nvs_types.h`` for possible values.
177
178 Span
179     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.
180
181 Rsv
182     Unused field, should be ``0xff``.
183
184 CRC32
185     Checksum calculated over all the bytes in this entry, except for the CRC32 field itself.
186
187 Key
188     Zero-terminated ASCII string containing key name. Maximum string length is 15 bytes, excluding zero terminator.
189
190 Data
191     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 string and blob values, these 8 bytes hold additional data about the value, described next:
192
193 Size
194     (Only for strings and blobs.) Size, in bytes, of actual data. For strings, this includes zero terminator.
195
196 CRC32
197     (Only for strings and blobs.) Checksum calculated over all bytes of data.
198
199 Variable length values (strings and blobs) are written into subsequent entries, 32 bytes per entry. `Span` field of the first entry indicates how many entries are used.
200
201
202 Namespaces
203 ~~~~~~~~~~
204
205 As mentioned above, each key-value pair belongs to one of the namespaces. Namespaces identifiers (strings) are stored as keys of key-value pairs in namespace with index 0. Values corresponding to these keys are indexes of these namespaces. 
206
207 ::
208
209     +-------------------------------------------+
210     | NS=0 Type=uint8_t Key="wifi" Value=1      |   Entry describing namespace "wifi"
211     +-------------------------------------------+
212     | NS=1 Type=uint32_t Key="channel" Value=6  |   Key "channel" in namespace "wifi"
213     +-------------------------------------------+
214     | NS=0 Type=uint8_t Key="pwm" Value=2       |   Entry describing namespace "pwm"
215     +-------------------------------------------+
216     | NS=0 Type=uint16_t Key="channel" Value=20 |   Key "channel" in namespace "pwm"
217     +-------------------------------------------+
218
219