1.. _settings_api: 2 3Settings 4######## 5 6The settings subsystem gives modules a way to store persistent per-device 7configuration and runtime state. A variety of storage implementations are 8provided behind a common API using FCB, NVS, or a file system. These different 9implementations give the application developer flexibility to select an 10appropriate storage medium, and even change it later as needs change. This 11subsystem is used by various Zephyr components and can be used simultaneously by 12user applications. 13 14Settings items are stored as key-value pair strings. By convention, 15the keys can be organized by the package and subtree defining the key, 16for example the key ``id/serial`` would define the ``serial`` configuration 17element for the package ``id``. 18 19Convenience routines are provided for converting a key value to 20and from a string type. 21 22For an example of the settings subsystem refer to :zephyr:code-sample:`settings` sample. 23 24.. note:: 25 26 As of Zephyr release 2.1 the recommended backend for non-filesystem 27 storage is :ref:`NVS <nvs_api>`. 28 29Handlers 30******** 31 32Settings handlers for subtree implement a set of handler functions. 33These are registered using a call to :c:func:`settings_register()` for 34dynamic handlers or defined using a call to :c:macro:`SETTINGS_STATIC_HANDLER_DEFINE()` 35for static handlers. 36 37**h_get** 38 This gets called when asking for a settings element value by its name using 39 :c:func:`settings_runtime_get()` from the runtime backend. 40 41**h_set** 42 This gets called when the value is loaded from persisted storage with 43 :c:func:`settings_load()`, or when using :c:func:`settings_runtime_set()` from the 44 runtime backend. 45 46**h_commit** 47 This gets called after the settings have been loaded in full. 48 Sometimes you don't want an individual setting value to take 49 effect right away, for example if there are multiple settings 50 which are interdependent. 51 52**h_export** 53 This gets called to write all current settings. This happens 54 when :c:func:`settings_save()` tries to save the settings or transfer to any 55 user-implemented back-end. 56 57Settings handlers also have a commit priority ``cprio`` that allows to prioritize 58the ``h_commit`` calls. This can be advantageous when e.g. a subsystem initializes 59a service that other ``h_commit`` calls depend on. 60 61Settings handlers ``h_commit`` routines are by default initialized with ``cprio = 0``, 62initializing a settings handler with a different priority is done using a call to 63:c:func:`settings_register_with_cprio()` for dynamic handlers or using a call to 64:c:macro:`SETTINGS_STATIC_HANDLER_DEFINE_WITH_CPRIO()` for static handlers. The 65specified ``cprio`` value is an integer where lower values mean higher priority. 66 67Backends 68******** 69 70Backends are meant to load and save data to/from setting handlers, and 71implement a set of handler functions. These are registered using a call to 72:c:func:`settings_src_register()` for backends that can load data, and/or 73:c:func:`settings_dst_register()` for backends that can save data. The current 74implementation allows for multiple source backends but only a single destination 75backend. 76 77**csi_load** 78 This gets called when loading values from persistent storage using 79 :c:func:`settings_load()`. 80 81**csi_save** 82 This gets called when saving a single setting to persistent storage using 83 :c:func:`settings_save_one()`. 84 85**csi_save_start** 86 This gets called when starting a save of all current settings using 87 :c:func:`settings_save()` or :c:func:`settings_save_subtree()`. 88 89**csi_save_end** 90 This gets called after having saved of all current settings using 91 :c:func:`settings_save()` or :c:func:`settings_save_subtree()`. 92 93Zephyr Storage Backends 94*********************** 95 96Zephyr has three storage backends: a Flash Circular Buffer 97(:kconfig:option:`CONFIG_SETTINGS_FCB`), a file in the filesystem 98(:kconfig:option:`CONFIG_SETTINGS_FILE`), or non-volatile storage 99(:kconfig:option:`CONFIG_SETTINGS_NVS`). 100 101You can declare multiple sources for settings; settings from 102all of these are restored when :c:func:`settings_load()` is called. 103 104There can be only one target for writing settings; this is where 105data is stored when you call :c:func:`settings_save()`, or :c:func:`settings_save_one()`. 106 107FCB read target is registered using :c:func:`settings_fcb_src()`, and write target 108using :c:func:`settings_fcb_dst()`. As a side-effect, :c:func:`settings_fcb_src()` 109initializes the FCB area, so it must be called before calling 110:c:func:`settings_fcb_dst()`. File read target is registered using 111:c:func:`settings_file_src()`, and write target by using :c:func:`settings_file_dst()`. 112Non-volatile storage read target is registered using 113:c:func:`settings_nvs_src()`, and write target by using 114:c:func:`settings_nvs_dst()`. 115 116Storage Location 117**************** 118 119The FCB and non-volatile storage (NVS) backends both look for a fixed 120partition with label "storage" by default. A different partition can be 121selected by setting the ``zephyr,settings-partition`` property of the 122chosen node in the devicetree. 123 124The file path used by the file backend to store settings is selected via the 125option :kconfig:option:`CONFIG_SETTINGS_FILE_PATH`. 126 127Loading data from persisted storage 128*********************************** 129 130A call to :c:func:`settings_load()` uses an ``h_set`` implementation 131to load settings data from storage to volatile memory. 132After all data is loaded, the ``h_commit`` handler is issued, 133signalling the application that the settings were successfully 134retrieved. 135 136Technically FCB and file backends may store some history of the entities. 137This means that the newest data entity is stored after any 138older existing data entities. 139Starting with Zephyr 2.1, the back-end must filter out all old entities and 140call the callback with only the newest entity. 141 142Storing data to persistent storage 143********************************** 144 145A call to :c:func:`settings_save_one()` uses a backend implementation to store 146settings data to the storage medium. A call to :c:func:`settings_save()` uses an 147``h_export`` implementation to store different data in one operation using 148:c:func:`settings_save_one()`. 149A key need to be covered by a ``h_export`` only if it is supposed to be stored 150by :c:func:`settings_save()` call. 151 152For both FCB and file back-end only storage requests with data which 153changes most actual key's value are stored, therefore there is no need to check 154whether a value changed by the application. Such a storage mechanism implies 155that storage can contain multiple value assignments for a key , while only the 156last is the current value for the key. 157 158Garbage collection 159================== 160When storage becomes full (FCB) or consumes too much space (file), 161the backend removes non-recent key-value pairs records and unnecessary 162key-delete records. 163 164Secure domain settings 165********************** 166Currently settings doesn't provide scheme of being secure, and non-secure 167configuration storage simultaneously for the same instance. 168It is recommended that secure domain uses its own settings instance and it might 169provide data for non-secure domain using dedicated interface if needed 170(case dependent). 171 172Example: Device Configuration 173***************************** 174 175This is a simple example, where the settings handler only implements ``h_set`` 176and ``h_export``. ``h_set`` is called when the value is restored from storage 177(or when set initially), and ``h_export`` is used to write the value to 178storage thanks to ``storage_func()``. The user can also implement some other 179export functionality, for example, writing to the shell console). 180 181.. code-block:: c 182 183 #define DEFAULT_FOO_VAL_VALUE 1 184 185 static int8 foo_val = DEFAULT_FOO_VAL_VALUE; 186 187 static int foo_settings_set(const char *name, size_t len, 188 settings_read_cb read_cb, void *cb_arg) 189 { 190 const char *next; 191 int rc; 192 193 if (settings_name_steq(name, "bar", &next) && !next) { 194 if (len != sizeof(foo_val)) { 195 return -EINVAL; 196 } 197 198 rc = read_cb(cb_arg, &foo_val, sizeof(foo_val)); 199 if (rc >= 0) { 200 /* key-value pair was properly read. 201 * rc contains value length. 202 */ 203 return 0; 204 } 205 /* read-out error */ 206 return rc; 207 } 208 209 return -ENOENT; 210 } 211 212 static int foo_settings_export(int (*storage_func)(const char *name, 213 const void *value, 214 size_t val_len)) 215 { 216 return storage_func("foo/bar", &foo_val, sizeof(foo_val)); 217 } 218 219 struct settings_handler my_conf = { 220 .name = "foo", 221 .h_set = foo_settings_set, 222 .h_export = foo_settings_export 223 }; 224 225Example: Persist Runtime State 226****************************** 227 228This is a simple example showing how to persist runtime state. In this example, 229only ``h_set`` is defined, which is used when restoring value from 230persisted storage. 231 232In this example, the ``main`` function increments ``foo_val``, and then 233persists the latest number. When the system restarts, the application calls 234:c:func:`settings_load()` while initializing, and ``foo_val`` will continue counting 235up from where it was before restart. 236 237.. code-block:: c 238 239 #include <zephyr/kernel.h> 240 #include <zephyr/sys/reboot.h> 241 #include <zephyr/settings/settings.h> 242 #include <zephyr/sys/printk.h> 243 #include <inttypes.h> 244 245 #define DEFAULT_FOO_VAL_VALUE 0 246 247 static uint8_t foo_val = DEFAULT_FOO_VAL_VALUE; 248 249 static int foo_settings_set(const char *name, size_t len, 250 settings_read_cb read_cb, void *cb_arg) 251 { 252 const char *next; 253 int rc; 254 255 if (settings_name_steq(name, "bar", &next) && !next) { 256 if (len != sizeof(foo_val)) { 257 return -EINVAL; 258 } 259 260 rc = read_cb(cb_arg, &foo_val, sizeof(foo_val)); 261 if (rc >= 0) { 262 return 0; 263 } 264 265 return rc; 266 } 267 268 269 return -ENOENT; 270 } 271 272 struct settings_handler my_conf = { 273 .name = "foo", 274 .h_set = foo_settings_set 275 }; 276 277 int main(void) 278 { 279 settings_subsys_init(); 280 settings_register(&my_conf); 281 settings_load(); 282 283 foo_val++; 284 settings_save_one("foo/bar", &foo_val, sizeof(foo_val)); 285 286 printk("foo: %d\n", foo_val); 287 288 k_msleep(1000); 289 sys_reboot(SYS_REBOOT_COLD); 290 } 291 292Example: Custom Backend Implementation 293************************************** 294 295This is a simple example showing how to register a simple custom backend 296handler (:kconfig:option:`CONFIG_SETTINGS_CUSTOM`). 297 298.. code-block:: c 299 300 static int settings_custom_load(struct settings_store *cs, 301 const struct settings_load_arg *arg) 302 { 303 //... 304 } 305 306 static int settings_custom_save(struct settings_store *cs, const char *name, 307 const char *value, size_t val_len) 308 { 309 //... 310 } 311 312 /* custom backend interface */ 313 static struct settings_store_itf settings_custom_itf = { 314 .csi_load = settings_custom_load, 315 .csi_save = settings_custom_save, 316 }; 317 318 /* custom backend node */ 319 static struct settings_store settings_custom_store = { 320 .cs_itf = &settings_custom_itf 321 }; 322 323 int settings_backend_init(void) 324 { 325 /* register custom backend */ 326 settings_dst_register(&settings_custom_store); 327 settings_src_register(&settings_custom_store); 328 return 0; 329 } 330 331API Reference 332************* 333 334The Settings subsystem APIs are provided by :zephyr_file:`include/zephyr/settings/settings.h`. 335 336API for general settings usage 337============================== 338.. doxygengroup:: settings 339 340API for key-name processing 341=========================== 342.. doxygengroup:: settings_name_proc 343 344API for runtime settings manipulation 345===================================== 346.. doxygengroup:: settings_rt 347 348API of backend interface 349======================== 350.. doxygengroup:: settings_backend 351