1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs: 2*61c4878aSAndroid Build Coastguard Worker 3*61c4878aSAndroid Build Coastguard Worker====== 4*61c4878aSAndroid Build Coastguard Workerpw_kvs 5*61c4878aSAndroid Build Coastguard Worker====== 6*61c4878aSAndroid Build Coastguard Worker.. pigweed-module:: 7*61c4878aSAndroid Build Coastguard Worker :name: pw_kvs 8*61c4878aSAndroid Build Coastguard Worker 9*61c4878aSAndroid Build Coastguard Worker.. tab-set:: 10*61c4878aSAndroid Build Coastguard Worker 11*61c4878aSAndroid Build Coastguard Worker .. tab-item:: app.cpp 12*61c4878aSAndroid Build Coastguard Worker 13*61c4878aSAndroid Build Coastguard Worker .. code-block:: cpp 14*61c4878aSAndroid Build Coastguard Worker 15*61c4878aSAndroid Build Coastguard Worker #include <cstddef> 16*61c4878aSAndroid Build Coastguard Worker 17*61c4878aSAndroid Build Coastguard Worker #include "pw_kvs/flash_test_partition.h" 18*61c4878aSAndroid Build Coastguard Worker #include "pw_kvs/key_value_store.h" 19*61c4878aSAndroid Build Coastguard Worker // Not a required dep; just here for demo comms 20*61c4878aSAndroid Build Coastguard Worker #include "pw_sys_io/sys_io.h" 21*61c4878aSAndroid Build Coastguard Worker 22*61c4878aSAndroid Build Coastguard Worker // Create our key-value store (KVS). Sector and entry vals for this 23*61c4878aSAndroid Build Coastguard Worker // demo are based on @pigweed//pw_kvs:fake_flash_64_aligned_partition 24*61c4878aSAndroid Build Coastguard Worker constexpr size_t kMaxSectors = 6; 25*61c4878aSAndroid Build Coastguard Worker constexpr size_t kMaxEntries = 64; 26*61c4878aSAndroid Build Coastguard Worker static constexpr pw::kvs::EntryFormat kvs_format = { 27*61c4878aSAndroid Build Coastguard Worker .magic = 0xd253a8a9, // Prod apps should use a random number here 28*61c4878aSAndroid Build Coastguard Worker .checksum = nullptr 29*61c4878aSAndroid Build Coastguard Worker }; 30*61c4878aSAndroid Build Coastguard Worker pw::kvs::KeyValueStoreBuffer<kMaxEntries, kMaxSectors> kvs( 31*61c4878aSAndroid Build Coastguard Worker &pw::kvs::FlashTestPartition(), 32*61c4878aSAndroid Build Coastguard Worker kvs_format 33*61c4878aSAndroid Build Coastguard Worker ); 34*61c4878aSAndroid Build Coastguard Worker 35*61c4878aSAndroid Build Coastguard Worker kvs.Init(); // Initialize our KVS 36*61c4878aSAndroid Build Coastguard Worker std::byte in; 37*61c4878aSAndroid Build Coastguard Worker pw::sys_io::ReadByte(&in).IgnoreError(); // Get a char from the user 38*61c4878aSAndroid Build Coastguard Worker kvs.Put("in", in); // Save the char to our key-value store (KVS) 39*61c4878aSAndroid Build Coastguard Worker std::byte out; 40*61c4878aSAndroid Build Coastguard Worker kvs.Get("in", &out); // Test that the KVS stored the data correctly 41*61c4878aSAndroid Build Coastguard Worker pw::sys_io::WriteByte(out).IgnoreError(); // Echo the char back out 42*61c4878aSAndroid Build Coastguard Worker 43*61c4878aSAndroid Build Coastguard Worker .. tab-item:: BUILD.bazel 44*61c4878aSAndroid Build Coastguard Worker 45*61c4878aSAndroid Build Coastguard Worker .. code-block:: py 46*61c4878aSAndroid Build Coastguard Worker 47*61c4878aSAndroid Build Coastguard Worker cc_binary( 48*61c4878aSAndroid Build Coastguard Worker name = "app", 49*61c4878aSAndroid Build Coastguard Worker srcs = ["app.cc"], 50*61c4878aSAndroid Build Coastguard Worker # ... 51*61c4878aSAndroid Build Coastguard Worker deps = [ 52*61c4878aSAndroid Build Coastguard Worker # ... 53*61c4878aSAndroid Build Coastguard Worker "@pigweed//pw_kvs", 54*61c4878aSAndroid Build Coastguard Worker "@pigweed//pw_kvs:fake_flash_64_aligned_partition", 55*61c4878aSAndroid Build Coastguard Worker # ... 56*61c4878aSAndroid Build Coastguard Worker ] 57*61c4878aSAndroid Build Coastguard Worker # ... 58*61c4878aSAndroid Build Coastguard Worker ) 59*61c4878aSAndroid Build Coastguard Worker 60*61c4878aSAndroid Build Coastguard Worker``pw_kvs`` is a flash-backed, persistent key-value storage (KVS) system with 61*61c4878aSAndroid Build Coastguard Workerintegrated :ref:`wear leveling <module-pw_kvs-design-wear>`. It's a relatively 62*61c4878aSAndroid Build Coastguard Workerlightweight alternative to a file system. 63*61c4878aSAndroid Build Coastguard Worker 64*61c4878aSAndroid Build Coastguard Worker.. grid:: 2 65*61c4878aSAndroid Build Coastguard Worker 66*61c4878aSAndroid Build Coastguard Worker .. grid-item-card:: :octicon:`rocket` Get started 67*61c4878aSAndroid Build Coastguard Worker :link: module-pw_kvs-start 68*61c4878aSAndroid Build Coastguard Worker :link-type: ref 69*61c4878aSAndroid Build Coastguard Worker :class-item: sales-pitch-cta-primary 70*61c4878aSAndroid Build Coastguard Worker 71*61c4878aSAndroid Build Coastguard Worker Integrate pw_kvs into your project 72*61c4878aSAndroid Build Coastguard Worker 73*61c4878aSAndroid Build Coastguard Worker .. grid-item-card:: :octicon:`code-square` Reference 74*61c4878aSAndroid Build Coastguard Worker :link: module-pw_kvs-reference 75*61c4878aSAndroid Build Coastguard Worker :link-type: ref 76*61c4878aSAndroid Build Coastguard Worker :class-item: sales-pitch-cta-secondary 77*61c4878aSAndroid Build Coastguard Worker 78*61c4878aSAndroid Build Coastguard Worker pw_kvs API reference 79*61c4878aSAndroid Build Coastguard Worker 80*61c4878aSAndroid Build Coastguard Worker.. grid:: 2 81*61c4878aSAndroid Build Coastguard Worker 82*61c4878aSAndroid Build Coastguard Worker .. grid-item-card:: :octicon:`stack` Design 83*61c4878aSAndroid Build Coastguard Worker :link: module-pw_kvs-design 84*61c4878aSAndroid Build Coastguard Worker :link-type: ref 85*61c4878aSAndroid Build Coastguard Worker :class-item: sales-pitch-cta-secondary 86*61c4878aSAndroid Build Coastguard Worker 87*61c4878aSAndroid Build Coastguard Worker How pw_kvs manages state, does garbage collection, etc. 88*61c4878aSAndroid Build Coastguard Worker 89*61c4878aSAndroid Build Coastguard Worker .. grid-item-card:: :octicon:`graph` Code size analysis 90*61c4878aSAndroid Build Coastguard Worker :link: module-pw_kvs-size 91*61c4878aSAndroid Build Coastguard Worker :link-type: ref 92*61c4878aSAndroid Build Coastguard Worker :class-item: sales-pitch-cta-secondary 93*61c4878aSAndroid Build Coastguard Worker 94*61c4878aSAndroid Build Coastguard Worker The code size impact of using pw_kvs in your project 95*61c4878aSAndroid Build Coastguard Worker 96*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-start: 97*61c4878aSAndroid Build Coastguard Worker 98*61c4878aSAndroid Build Coastguard Worker----------- 99*61c4878aSAndroid Build Coastguard WorkerGet started 100*61c4878aSAndroid Build Coastguard Worker----------- 101*61c4878aSAndroid Build Coastguard Worker.. tab-set:: 102*61c4878aSAndroid Build Coastguard Worker 103*61c4878aSAndroid Build Coastguard Worker .. tab-item:: Bazel 104*61c4878aSAndroid Build Coastguard Worker 105*61c4878aSAndroid Build Coastguard Worker Add ``@pigweed//pw_kvs`` to your target's ``deps``: 106*61c4878aSAndroid Build Coastguard Worker 107*61c4878aSAndroid Build Coastguard Worker .. code-block:: 108*61c4878aSAndroid Build Coastguard Worker 109*61c4878aSAndroid Build Coastguard Worker cc_binary( 110*61c4878aSAndroid Build Coastguard Worker # ... 111*61c4878aSAndroid Build Coastguard Worker deps = [ 112*61c4878aSAndroid Build Coastguard Worker # ... 113*61c4878aSAndroid Build Coastguard Worker "@pigweed//pw_kvs", 114*61c4878aSAndroid Build Coastguard Worker # ... 115*61c4878aSAndroid Build Coastguard Worker ] 116*61c4878aSAndroid Build Coastguard Worker ) 117*61c4878aSAndroid Build Coastguard Worker 118*61c4878aSAndroid Build Coastguard Worker This assumes that your Bazel ``WORKSPACE`` has a `repository 119*61c4878aSAndroid Build Coastguard Worker <https://bazel.build/concepts/build-ref#repositories>`_ named ``@pigweed`` 120*61c4878aSAndroid Build Coastguard Worker that points to the upstream Pigweed repository. 121*61c4878aSAndroid Build Coastguard Worker 122*61c4878aSAndroid Build Coastguard Worker .. tab-item:: GN 123*61c4878aSAndroid Build Coastguard Worker 124*61c4878aSAndroid Build Coastguard Worker Add ``$dir_pw_kvs`` to the ``deps`` list in your ``pw_executable()`` 125*61c4878aSAndroid Build Coastguard Worker build target: 126*61c4878aSAndroid Build Coastguard Worker 127*61c4878aSAndroid Build Coastguard Worker .. code-block:: 128*61c4878aSAndroid Build Coastguard Worker 129*61c4878aSAndroid Build Coastguard Worker pw_executable("...") { 130*61c4878aSAndroid Build Coastguard Worker # ... 131*61c4878aSAndroid Build Coastguard Worker deps = [ 132*61c4878aSAndroid Build Coastguard Worker # ... 133*61c4878aSAndroid Build Coastguard Worker "$dir_pw_kvs", 134*61c4878aSAndroid Build Coastguard Worker # ... 135*61c4878aSAndroid Build Coastguard Worker ] 136*61c4878aSAndroid Build Coastguard Worker } 137*61c4878aSAndroid Build Coastguard Worker 138*61c4878aSAndroid Build Coastguard Worker .. tab-item:: CMake 139*61c4878aSAndroid Build Coastguard Worker 140*61c4878aSAndroid Build Coastguard Worker Link your library to ``pw_kvs``: 141*61c4878aSAndroid Build Coastguard Worker 142*61c4878aSAndroid Build Coastguard Worker .. code-block:: 143*61c4878aSAndroid Build Coastguard Worker 144*61c4878aSAndroid Build Coastguard Worker add_library(my_lib ...) 145*61c4878aSAndroid Build Coastguard Worker target_link_libraries(my_lib PUBLIC pw_kvs) 146*61c4878aSAndroid Build Coastguard Worker 147*61c4878aSAndroid Build Coastguard WorkerUse ``pw_kvs`` in your C++ code: 148*61c4878aSAndroid Build Coastguard Worker 149*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++ 150*61c4878aSAndroid Build Coastguard Worker 151*61c4878aSAndroid Build Coastguard Worker #include "pw_kvs/key_value_store.h" 152*61c4878aSAndroid Build Coastguard Worker 153*61c4878aSAndroid Build Coastguard Worker // ... 154*61c4878aSAndroid Build Coastguard Worker 155*61c4878aSAndroid Build Coastguard Worker.. _pw_kvs/flash_memory.h: https://cs.opensource.google/pigweed/pigweed/+/main:pw_kvs/public/pw_kvs/flash_memory.h 156*61c4878aSAndroid Build Coastguard Worker 157*61c4878aSAndroid Build Coastguard WorkerImplement the :ref:`flash memory <module-pw_kvs-design-memory>` and 158*61c4878aSAndroid Build Coastguard Worker:ref:`flash partition <module-pw_kvs-design-partitions>` interfaces for 159*61c4878aSAndroid Build Coastguard Workeryour hardware. See `pw_kvs/flash_memory.h`_. 160*61c4878aSAndroid Build Coastguard Worker 161*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-reference: 162*61c4878aSAndroid Build Coastguard Worker 163*61c4878aSAndroid Build Coastguard Worker--------- 164*61c4878aSAndroid Build Coastguard WorkerReference 165*61c4878aSAndroid Build Coastguard Worker--------- 166*61c4878aSAndroid Build Coastguard Worker 167*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-reference-keyvaluestore: 168*61c4878aSAndroid Build Coastguard Worker 169*61c4878aSAndroid Build Coastguard Worker``pw::kvs::KeyValueStore`` 170*61c4878aSAndroid Build Coastguard Worker========================== 171*61c4878aSAndroid Build Coastguard WorkerSee :ref:`module-pw_kvs-design` for architectural details. 172*61c4878aSAndroid Build Coastguard Worker 173*61c4878aSAndroid Build Coastguard Worker.. doxygenclass:: pw::kvs::KeyValueStore 174*61c4878aSAndroid Build Coastguard Worker :members: 175*61c4878aSAndroid Build Coastguard Worker 176*61c4878aSAndroid Build Coastguard WorkerConfiguration 177*61c4878aSAndroid Build Coastguard Worker============= 178*61c4878aSAndroid Build Coastguard Worker.. doxygendefine:: PW_KVS_LOG_LEVEL 179*61c4878aSAndroid Build Coastguard Worker.. doxygendefine:: PW_KVS_MAX_FLASH_ALIGNMENT 180*61c4878aSAndroid Build Coastguard Worker.. doxygendefine:: PW_KVS_REMOVE_DELETED_KEYS_IN_HEAVY_MAINTENANCE 181*61c4878aSAndroid Build Coastguard Worker 182*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design: 183*61c4878aSAndroid Build Coastguard Worker 184*61c4878aSAndroid Build Coastguard Worker------ 185*61c4878aSAndroid Build Coastguard WorkerDesign 186*61c4878aSAndroid Build Coastguard Worker------ 187*61c4878aSAndroid Build Coastguard Worker:cpp:class:`pw::kvs::KeyValueStore` ("the KVS") stores key and value data 188*61c4878aSAndroid Build Coastguard Workerpairs. The key-value pairs are stored in :ref:`flash partition 189*61c4878aSAndroid Build Coastguard Worker<module-pw_kvs-design-memory>` as a :ref:`key-value entry 190*61c4878aSAndroid Build Coastguard Worker<module-pw_kvs-design-entries>` (KV entry) that consists of a header/metadata, 191*61c4878aSAndroid Build Coastguard Workerthe key data, and value data. KV entries are accessed through ``Put()``, 192*61c4878aSAndroid Build Coastguard Worker``Get()``, and ``Delete()`` operations. 193*61c4878aSAndroid Build Coastguard Worker 194*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design-entries: 195*61c4878aSAndroid Build Coastguard Worker 196*61c4878aSAndroid Build Coastguard WorkerKey-value entries 197*61c4878aSAndroid Build Coastguard Worker================= 198*61c4878aSAndroid Build Coastguard WorkerEach key-value (KV) entry consists of a header/metadata, the key data, and 199*61c4878aSAndroid Build Coastguard Workervalue data. Individual KV entries are contained within a single flash sector; 200*61c4878aSAndroid Build Coastguard Workerthey do not cross sector boundaries. Because of this the maximum KV entry size 201*61c4878aSAndroid Build Coastguard Workeris the partition sector size. 202*61c4878aSAndroid Build Coastguard Worker 203*61c4878aSAndroid Build Coastguard WorkerKV entries are appended as needed to sectors, with append operations spread 204*61c4878aSAndroid Build Coastguard Workerover time. Each individual KV entry is written completely as a single 205*61c4878aSAndroid Build Coastguard Workerhigh-level operation. KV entries are appended to a sector as long as space is 206*61c4878aSAndroid Build Coastguard Workeravailable for a given KV entry. Multiple sectors can be active for writing at 207*61c4878aSAndroid Build Coastguard Workerany time. 208*61c4878aSAndroid Build Coastguard Worker 209*61c4878aSAndroid Build Coastguard WorkerWhen an entry is updated, an entirely new entry is written to a new location 210*61c4878aSAndroid Build Coastguard Workerthat may or may not be located in the same sectore as the old entry. The new 211*61c4878aSAndroid Build Coastguard Workerentry uses a transaction ID greater than the old entry. The old entry remains 212*61c4878aSAndroid Build Coastguard Workerunaltered "on-disk" but is considered "stale". It is :ref:`garbage collected 213*61c4878aSAndroid Build Coastguard Worker<module-pw_kvs-design-garbage>` at some future time. 214*61c4878aSAndroid Build Coastguard Worker 215*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design-state: 216*61c4878aSAndroid Build Coastguard Worker 217*61c4878aSAndroid Build Coastguard WorkerState 218*61c4878aSAndroid Build Coastguard Worker===== 219*61c4878aSAndroid Build Coastguard WorkerThe KVS does not store any data/metadata/state in flash beyond the KV 220*61c4878aSAndroid Build Coastguard Workerentries. All KVS state can be derived from the stored KV entries. 221*61c4878aSAndroid Build Coastguard WorkerCurrent state is determined at boot from flash-stored KV entries and 222*61c4878aSAndroid Build Coastguard Workerthen maintained in RAM by the KVS. At all times the KVS is in a valid state 223*61c4878aSAndroid Build Coastguard Workeron-flash; there are no windows of vulnerability to unexpected power loss or 224*61c4878aSAndroid Build Coastguard Workercrash. The old entry for a key is maintained until the new entry for that key 225*61c4878aSAndroid Build Coastguard Workeris written and verified. 226*61c4878aSAndroid Build Coastguard Worker 227*61c4878aSAndroid Build Coastguard WorkerEach KV entry has a unique transaction ID that is incremented for each KVS 228*61c4878aSAndroid Build Coastguard Workerupdate transaction. When determining system state from flash-stored KV entries, 229*61c4878aSAndroid Build Coastguard Workerthe valid entry with the highest transaction ID is considered to be the 230*61c4878aSAndroid Build Coastguard Worker"current" entry of the key. All stored entries of the same key with lower 231*61c4878aSAndroid Build Coastguard Workertransaction IDs are considered old or "stale". 232*61c4878aSAndroid Build Coastguard Worker 233*61c4878aSAndroid Build Coastguard WorkerUpdates/rewrites of a key that has been previously stored is done as a new KV 234*61c4878aSAndroid Build Coastguard Workerentry with an updated transaction ID and the new value for the key. The 235*61c4878aSAndroid Build Coastguard Workerinternal state of the KVS is updated to reflect the new entry. The 236*61c4878aSAndroid Build Coastguard Workerpreviously stored KV entries for that key are not modified or removed from 237*61c4878aSAndroid Build Coastguard Workerflash storage, until garbage collection reclaims the "stale" entries. 238*61c4878aSAndroid Build Coastguard Worker 239*61c4878aSAndroid Build Coastguard Worker`Garbage collection`_ is done by copying any currently valid KV entries in the 240*61c4878aSAndroid Build Coastguard Workersector to be garbage collected to a different sector and then erasing the 241*61c4878aSAndroid Build Coastguard Workersector. 242*61c4878aSAndroid Build Coastguard Worker 243*61c4878aSAndroid Build Coastguard WorkerFlash sectors 244*61c4878aSAndroid Build Coastguard Worker============= 245*61c4878aSAndroid Build Coastguard WorkerEach flash sector is written sequentially in an append-only manner, with each 246*61c4878aSAndroid Build Coastguard Workerfollowing entry write being at a higher address than all of the previous entry 247*61c4878aSAndroid Build Coastguard Workerwrites to that sector since erase. Once information (header, metadata, data, 248*61c4878aSAndroid Build Coastguard Workeretc.) is written to flash, that information is not modified or cleared until a 249*61c4878aSAndroid Build Coastguard Workerfull sector erase occurs as part of garbage collection. 250*61c4878aSAndroid Build Coastguard Worker 251*61c4878aSAndroid Build Coastguard WorkerIndividual KV entries are contained within a single flash sector; they do 252*61c4878aSAndroid Build Coastguard Workernot cross sector boundaries. Flash sectors can contain as many KV entries as 253*61c4878aSAndroid Build Coastguard Workerfit in the sector. 254*61c4878aSAndroid Build Coastguard Worker 255*61c4878aSAndroid Build Coastguard WorkerSectors are the minimum erase size for both :ref:`module-pw_kvs-design-memory` 256*61c4878aSAndroid Build Coastguard Workerand :ref:`module-pw_kvs-design-partitions`. Partitions may have a different 257*61c4878aSAndroid Build Coastguard Workerlogical sector size than the memory they are part of. Partition logical sectors 258*61c4878aSAndroid Build Coastguard Workermay be smaller due to partition overhead (encryption, wear tracking, etc) or 259*61c4878aSAndroid Build Coastguard Workerlarger due to combining raw sectors into larger logical sectors. 260*61c4878aSAndroid Build Coastguard Worker 261*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design-layers: 262*61c4878aSAndroid Build Coastguard Worker 263*61c4878aSAndroid Build Coastguard WorkerStorage layers 264*61c4878aSAndroid Build Coastguard Worker============== 265*61c4878aSAndroid Build Coastguard WorkerThe flash storage used by the KVS is comprised of two layers, flash memory 266*61c4878aSAndroid Build Coastguard Workerand flash partitions. 267*61c4878aSAndroid Build Coastguard Worker 268*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design-memory: 269*61c4878aSAndroid Build Coastguard Worker 270*61c4878aSAndroid Build Coastguard WorkerFlash memory 271*61c4878aSAndroid Build Coastguard Worker------------ 272*61c4878aSAndroid Build Coastguard Worker``pw::kvs::FlashMemory`` is the lower storage layer that manages the raw 273*61c4878aSAndroid Build Coastguard Workerread/write/erase of the flash memory device. It is an abstract base class that 274*61c4878aSAndroid Build Coastguard Workerneeds a concrete implementation before it can be used. 275*61c4878aSAndroid Build Coastguard Worker 276*61c4878aSAndroid Build Coastguard Worker``pw::kvs::FakeFlashMemory`` is a variant that uses RAM rather than flash as 277*61c4878aSAndroid Build Coastguard Workerthe storage media. This is helpful for reducing physical flash wear during unit 278*61c4878aSAndroid Build Coastguard Workertests and development. 279*61c4878aSAndroid Build Coastguard Worker 280*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design-partitions: 281*61c4878aSAndroid Build Coastguard Worker 282*61c4878aSAndroid Build Coastguard WorkerFlash partitions 283*61c4878aSAndroid Build Coastguard Worker---------------- 284*61c4878aSAndroid Build Coastguard Worker``pw::kvs::FlashPartition`` is a subset of a ``pw::kvs::FlashMemory``. Flash 285*61c4878aSAndroid Build Coastguard Workermemory may have one or multiple partition instances that represent different 286*61c4878aSAndroid Build Coastguard Workerparts of the memory, such as partitions for KVS, OTA, snapshots/crashlogs, etc. 287*61c4878aSAndroid Build Coastguard WorkerEach partition has its own separate logical address space starting from zero to 288*61c4878aSAndroid Build Coastguard Worker``size`` bytes of the partition. Partition logical addresses do not always map 289*61c4878aSAndroid Build Coastguard Workerdirectly to memory addresses due to partition encryption, sector headers, etc. 290*61c4878aSAndroid Build Coastguard Worker 291*61c4878aSAndroid Build Coastguard WorkerPartitions support access via ``pw::kvs::NonSeekableWriter`` and 292*61c4878aSAndroid Build Coastguard Worker``pw::kvs::SeekableReader``. The reader defaults to the full size of the 293*61c4878aSAndroid Build Coastguard Workerpartition but can optionally be limited to a smaller range. 294*61c4878aSAndroid Build Coastguard Worker 295*61c4878aSAndroid Build Coastguard Worker``pw::kvs::FlashPartition`` is a concrete class that can be used directly. It 296*61c4878aSAndroid Build Coastguard Workerhas several derived variants available, such as 297*61c4878aSAndroid Build Coastguard Worker``pw::kvs::FlashPartitionWithStats`` and 298*61c4878aSAndroid Build Coastguard Worker``pw::kvs::FlashPartitionWithLogicalSectors``. 299*61c4878aSAndroid Build Coastguard Worker 300*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design-alignment: 301*61c4878aSAndroid Build Coastguard Worker 302*61c4878aSAndroid Build Coastguard WorkerAlignment 303*61c4878aSAndroid Build Coastguard Worker========= 304*61c4878aSAndroid Build Coastguard WorkerWrites to flash must have a start address that is a multiple of the flash 305*61c4878aSAndroid Build Coastguard Workerwrite alignment. Write size must also be a multiple of flash write alignment. 306*61c4878aSAndroid Build Coastguard WorkerWrite alignment varies by flash device and partition type. Reads from flash do 307*61c4878aSAndroid Build Coastguard Workernot have any address or size alignment requirement; reads always have a 308*61c4878aSAndroid Build Coastguard Workerminimum alignment of 1. 309*61c4878aSAndroid Build Coastguard Worker 310*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_kvs-design-partitions` may have a different alignment than the 311*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_kvs-design-memory` they are part of, so long as the partition's 312*61c4878aSAndroid Build Coastguard Workeralignment is a multiple of the alignment for the memory. 313*61c4878aSAndroid Build Coastguard Worker 314*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design-allocation: 315*61c4878aSAndroid Build Coastguard Worker 316*61c4878aSAndroid Build Coastguard WorkerAllocation 317*61c4878aSAndroid Build Coastguard Worker---------- 318*61c4878aSAndroid Build Coastguard WorkerThe KVS requires more storage space than the size of the key-value data 319*61c4878aSAndroid Build Coastguard Workerstored. This is due to the always-free sector required for garbage collection 320*61c4878aSAndroid Build Coastguard Workerand the "write and garbage collect later" approach it uses. 321*61c4878aSAndroid Build Coastguard Worker 322*61c4878aSAndroid Build Coastguard WorkerThe KVS works poorly when stored data takes up more than 75% of the 323*61c4878aSAndroid Build Coastguard Workeravailable storage. It works best when stored data is less than 50%. 324*61c4878aSAndroid Build Coastguard WorkerApplications that need to do garbage collection at scheduled times or that 325*61c4878aSAndroid Build Coastguard Workerwrite very heavily can benefit from additional flash store space. 326*61c4878aSAndroid Build Coastguard Worker 327*61c4878aSAndroid Build Coastguard WorkerThe flash storage used by the KVS is multiplied by the amount of 328*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_kvs-design-redundancy` used. A redundancy of 2 will use twice 329*61c4878aSAndroid Build Coastguard Workerthe storage, for example. 330*61c4878aSAndroid Build Coastguard Worker 331*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design-redundancy: 332*61c4878aSAndroid Build Coastguard Worker 333*61c4878aSAndroid Build Coastguard WorkerRedundancy 334*61c4878aSAndroid Build Coastguard Worker========== 335*61c4878aSAndroid Build Coastguard WorkerThe KVS supports storing redundant copies of KV entries. For a given redundancy 336*61c4878aSAndroid Build Coastguard Workerlevel (N), N total copies of each KV entry are stored. Redundant copies are 337*61c4878aSAndroid Build Coastguard Workeralways stored in different sectors. This protects against corruption or even 338*61c4878aSAndroid Build Coastguard Workerfull sector loss in N-1 sectors without data loss. 339*61c4878aSAndroid Build Coastguard Worker 340*61c4878aSAndroid Build Coastguard WorkerRedundancy increases flash usage proportional to the redundancy level. The RAM 341*61c4878aSAndroid Build Coastguard Workerusage for KVS internal state has a small increase with redundancy. 342*61c4878aSAndroid Build Coastguard Worker 343*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design-garbage: 344*61c4878aSAndroid Build Coastguard Worker 345*61c4878aSAndroid Build Coastguard WorkerGarbage collection 346*61c4878aSAndroid Build Coastguard Worker================== 347*61c4878aSAndroid Build Coastguard WorkerStorage space occupied by stale :ref:`module-pw_kvs-design-entries` is 348*61c4878aSAndroid Build Coastguard Workerreclaimed and made available for reuse through a garbage collection process. 349*61c4878aSAndroid Build Coastguard WorkerThe base garbage collection operation is done to reclaim one sector at a time. 350*61c4878aSAndroid Build Coastguard Worker 351*61c4878aSAndroid Build Coastguard WorkerThe KVS always keeps at least one sector free at all times to ensure the 352*61c4878aSAndroid Build Coastguard Workerability to garbage collect. This free sector is used to copy valid entries from 353*61c4878aSAndroid Build Coastguard Workerthe sector to be garbage collected before erasing the sector to be garbage 354*61c4878aSAndroid Build Coastguard Workercollected. The always-free sector is rotated as part of the KVS 355*61c4878aSAndroid Build Coastguard Worker:ref:`wear leveling <module-pw_kvs-design-wear>`. 356*61c4878aSAndroid Build Coastguard Worker 357*61c4878aSAndroid Build Coastguard WorkerGarbage collection can be performed manually, by invoking the methods below, 358*61c4878aSAndroid Build Coastguard Workeror it can be configured to happen automatically. 359*61c4878aSAndroid Build Coastguard Worker 360*61c4878aSAndroid Build Coastguard Worker* :cpp:func:`pw::kvs::KeyValueStore::HeavyMaintenance()` 361*61c4878aSAndroid Build Coastguard Worker* :cpp:func:`pw::kvs::KeyValueStore::FullMaintenance()` 362*61c4878aSAndroid Build Coastguard Worker* :cpp:func:`pw::kvs::KeyValueStore::PartialMaintenance()` 363*61c4878aSAndroid Build Coastguard Worker 364*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-design-wear: 365*61c4878aSAndroid Build Coastguard Worker 366*61c4878aSAndroid Build Coastguard WorkerWear leveling (flash wear management) 367*61c4878aSAndroid Build Coastguard Worker===================================== 368*61c4878aSAndroid Build Coastguard WorkerWear leveling is accomplished by cycling selection of the next sector to write 369*61c4878aSAndroid Build Coastguard Workerto. This cycling spreads flash wear across all free sectors so that no one 370*61c4878aSAndroid Build Coastguard Workersector is prematurely worn out. 371*61c4878aSAndroid Build Coastguard Worker 372*61c4878aSAndroid Build Coastguard WorkerThe wear leveling decision-making process follows these guidelines: 373*61c4878aSAndroid Build Coastguard Worker 374*61c4878aSAndroid Build Coastguard Worker* Location of new writes/rewrites of KV entries will prefer sectors already 375*61c4878aSAndroid Build Coastguard Worker in-use (partially filled), with new (blank) sectors used when no in-use 376*61c4878aSAndroid Build Coastguard Worker sectors have large enough available space for the new write. 377*61c4878aSAndroid Build Coastguard Worker* New (blank) sectors selected cycle sequentially between available free 378*61c4878aSAndroid Build Coastguard Worker sectors. 379*61c4878aSAndroid Build Coastguard Worker* The wear leveling system searches for the first available sector, starting 380*61c4878aSAndroid Build Coastguard Worker from the current write sector + 1 and wraps around to start at the end of a 381*61c4878aSAndroid Build Coastguard Worker partition. This spreads the erase/write cycles for heavily written/rewritten 382*61c4878aSAndroid Build Coastguard Worker KV entries across all free sectors, reducing wear on any single sector. 383*61c4878aSAndroid Build Coastguard Worker* Erase count is not considered in the wear leveling decision-making process. 384*61c4878aSAndroid Build Coastguard Worker* Sectors with already written KV entries that are not modified will remain in 385*61c4878aSAndroid Build Coastguard Worker the original sector and not participate in wear-leveling, so long as the 386*61c4878aSAndroid Build Coastguard Worker KV entries in the sector remain unchanged. 387*61c4878aSAndroid Build Coastguard Worker 388*61c4878aSAndroid Build Coastguard Worker.. _module-pw_kvs-size: 389*61c4878aSAndroid Build Coastguard Worker 390*61c4878aSAndroid Build Coastguard Worker------------------ 391*61c4878aSAndroid Build Coastguard WorkerCode size analysis 392*61c4878aSAndroid Build Coastguard Worker------------------ 393*61c4878aSAndroid Build Coastguard WorkerThe following size report details the memory usage of ``KeyValueStore`` and 394*61c4878aSAndroid Build Coastguard Worker``FlashPartition``. 395*61c4878aSAndroid Build Coastguard Worker 396*61c4878aSAndroid Build Coastguard Worker.. include:: kvs_size 397