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