Skip to content

Commit 94451b2

Browse files
fnde-otjukkar
authored andcommitted
subsys/settings: Allow to register custom backends in settings subsystem
Major changes are: - Expose settings backend API to enable custom backend support. - Add a new CONFIG_SETTINGS_CUSTOM backend to allow registering a custom backend. - Change api of the handlers h_set() routines to allow for backend-specific read callbacks. - Provide a customizable settings_backend_init() routine for custom backends. - Move runtime settings support to be its own backend. Signed-off-by: François Delawarde <[email protected]>
1 parent 686830b commit 94451b2

File tree

31 files changed

+727
-532
lines changed

31 files changed

+727
-532
lines changed

doc/reference/storage/settings/settings.rst

Lines changed: 73 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ Settings handlers for subtree implement a set of handler functions.
2121
These are registered using a call to ``settings_register()``.
2222

2323
**h_get**
24-
This gets called when asking for a settings element value
25-
by its name using ``settings_get_value()``.
24+
This gets called when asking for a settings element value by its name using
25+
``settings_runtime_get()`` from the runtime backend.
2626

2727
**h_set**
28-
This gets called when the value is being set using ``settings_set_value()``,
29-
and also when setting is loaded from persisted storage with
30-
``settings_load()``.
28+
This gets called when the value is loaded from persisted storage with
29+
``settings_load()``, or when using ``settings_runtime_set()`` from the
30+
runtime backend.
3131

3232
**h_commit**
3333
This gets called after the settings have been loaded in full.
@@ -40,11 +40,38 @@ These are registered using a call to ``settings_register()``.
4040
when ``settings_save()`` tries to save the settings or transfer to any
4141
user-implemented back-end.
4242

43-
Persistence
44-
***********
43+
Backends
44+
********
45+
46+
Backends are meant to load and save data to/from setting handlers, and
47+
implement a set of handler functions. These are registered using a call to
48+
``settings_src_register()`` for backends that can load data, and/or
49+
``settings_dst_register()`` for backends that can save data. The current
50+
implementation allows for multiple source backends but only a single destination
51+
backend.
52+
53+
**csi_load**
54+
This gets called when loading values from persistent storage using
55+
``settings_load()``.
56+
57+
**csi_save**
58+
This gets called when a saving a single setting to persistent storage using
59+
``settings_save_one()``.
4560

46-
Backend storage for the settings can be a Flash Circular Buffer (FCB)
47-
or a file in the filesystem.
61+
**csi_save_start**
62+
This gets called when starting a save of all current settings using
63+
``settings_save()``.
64+
65+
**csi_save_end**
66+
This gets called after having saved of all current settings using
67+
``settings_save()``.
68+
69+
Zephyr Storage Backends
70+
***********************
71+
72+
Zephyr has two existing backend storages which can be a Flash Circular Buffer
73+
(:option:`CONFIG_SETTINGS_FCB`) or a file in the filesystem
74+
(:option:`CONFIG_SETTINGS_FS`).
4875

4976
You can declare multiple sources for settings; settings from
5077
all of these are restored when ``settings_load()`` is called.
@@ -89,12 +116,12 @@ export functionality, for example, writing to the shell console).
89116
.h_export = foo_settings_export
90117
};
91118
92-
static int foo_settings_set(int argc, char **argv, void *value_ctx)
119+
static int foo_settings_set(int argc, char **argv, settings_read_cb read_cb,
120+
void *cb_arg)
93121
{
94122
if (argc == 1) {
95123
if (!strcmp(argv[0], "bar")) {
96-
return settings_val_read_cb(value_ctx, &foo_val,
97-
sizeof(foo_val));
124+
return read_cb(cb_arg, &foo_val, sizeof(foo_val));
98125
}
99126
}
100127
@@ -129,12 +156,12 @@ up from where it was before restart.
129156
.h_set = foo_settings_set
130157
};
131158
132-
static int foo_settings_set(int argc, char **argv, void *value_ctx)
159+
static int foo_settings_set(int argc, char **argv, settings_read_cb read_cb,
160+
void *cb_arg)
133161
{
134162
if (argc == 1) {
135163
if (!strcmp(argv[0], "bar")) {
136-
return settings_val_read_cb(value_ctx, &foo_val,
137-
sizeof(foo_val));
164+
return read_cb(cb_arg, &foo_val, sizeof(foo_val));
138165
}
139166
}
140167
@@ -152,6 +179,37 @@ up from where it was before restart.
152179
sys_reboot(SYS_REBOOT_COLD);
153180
}
154181
182+
Example: Custom Backend Implementation
183+
**************************************
184+
185+
This is a simple example showing how to register a simple custom backend
186+
handler (:option:`CONFIG_SETTINGS_CUSTOM`).
187+
188+
.. code-block:: c
189+
190+
static int settings_custom_load(struct settings_store *cs)
191+
{
192+
//...
193+
}
194+
195+
static int settings_custom_save(struct settings_store *cs, const char *name,
196+
const char *value, size_t val_len)
197+
{
198+
//...
199+
}
200+
201+
static struct settings_store_itf settings_custom_itf = {
202+
.csi_load = settings_custom_load,
203+
.csi_save = settings_custom_save,
204+
};
205+
206+
int settings_backend_init(void)
207+
{
208+
settings_dst_register(&settings_custom_itf);
209+
settings_src_register(&settings_custom_itf);
210+
return 0;
211+
}
212+
155213
API Reference
156214
*************
157215

include/settings/settings.h

Lines changed: 122 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ extern "C" {
3333
*/
3434
#define SETTINGS_EXTRA_LEN ((SETTINGS_MAX_DIR_DEPTH - 1) + 2)
3535

36-
#define SETTINGS_NMGR_OP 0
36+
typedef ssize_t (*settings_read_cb)(void *cb_arg, void *data, size_t len);
3737

3838
/**
3939
* @struct settings_handler
@@ -57,14 +57,16 @@ struct settings_handler {
5757
* - val_len_max - size of that buffer.
5858
*/
5959

60-
int (*h_set)(int argc, char **argv, void *value_ctx);
60+
int (*h_set)(int argc, char **argv, size_t len,
61+
settings_read_cb read_cb, void *cb_arg);
6162
/**< Set value handler of settings items identified by keyword names.
6263
*
6364
* Parameters:
64-
* - argc - count of item in argv, argv - array of pointers to keyword
65-
* names.
66-
* - value_ctx - pointer to the value context which is used parameter
67-
* for data extracting routine (@ref settings_val_read_cb).
65+
* - argc - count of item in argv.
66+
* - argv - array of pointers to keyword names.
67+
* - len - the size of the data found in the backend.
68+
* - read_cb - function provided to read the data from the backend.
69+
* - cb_arg - arguments for the read function provided by the backend.
6870
*/
6971

7072
int (*h_commit)(void);
@@ -152,86 +154,149 @@ int settings_save_one(const char *name, void *value, size_t val_len);
152154
int settings_delete(const char *name);
153155

154156
/**
155-
* Set settings item identified by @p name to be value @p value.
156-
* This finds the settings handler for this subtree and calls it's
157-
* set handler.
158-
*
159-
* @param name Name/key of the settings item.
160-
* @param value Pointer to the value of the settings item. This value will
161-
* be transferred to the @ref settings_handler::h_set handler implementation.
162-
* @param len Length of value string.
157+
* Call commit for all settings handler. This should apply all
158+
* settings which has been set, but not applied yet.
163159
*
164160
* @return 0 on success, non-zero on failure.
165161
*/
166-
int settings_set_value(char *name, void *value, size_t len);
162+
int settings_commit(void);
167163

168164
/**
169-
* Get value of settings item identified by @p name.
170-
* This calls the settings handler h_get for the subtree.
171-
*
172-
* Configuration handler should copy the string to @p buf, the maximum
173-
* number of bytes it will copy is limited by @p buf_len.
165+
* @} settings
166+
*/
167+
168+
169+
/*
170+
* API for config storage
171+
*/
172+
173+
struct settings_store_itf;
174+
175+
/**
176+
* @struct settings_store
177+
* Backend handler node for storage handling.
178+
*/
179+
struct settings_store {
180+
sys_snode_t cs_next;
181+
/**< Linked list node info for internal usage. */
182+
183+
const struct settings_store_itf *cs_itf;
184+
/**< Backend handler structure. */
185+
};
186+
187+
/**
188+
* @struct settings_store_itf
189+
* Backend handler functions.
190+
* Sources are registered using a call to @ref settings_src_register.
191+
* Destinations are registered using a call to @ref settings_dst_register.
192+
*/
193+
struct settings_store_itf {
194+
int (*csi_load)(struct settings_store *cs);
195+
/**< Loads all values from storage.
196+
*
197+
* Parameters:
198+
* - cs - Corresponding backend handler node
199+
*/
200+
201+
int (*csi_save_start)(struct settings_store *cs);
202+
/**< Handler called before an export operation.
203+
*
204+
* Parameters:
205+
* - cs - Corresponding backend handler node
206+
*/
207+
208+
int (*csi_save)(struct settings_store *cs, const char *name,
209+
const char *value, size_t val_len);
210+
/**< Save a single key-value pair to storage.
211+
*
212+
* Parameters:
213+
* - cs - Corresponding backend handler node
214+
* - name - Key in string format
215+
* - value - Binary value
216+
* - val_len - Length of value in bytes.
217+
*/
218+
219+
int (*csi_save_end)(struct settings_store *cs);
220+
/**< Handler called after an export operation.
221+
*
222+
* Parameters:
223+
* - cs - Corresponding backend handler node
224+
*/
225+
};
226+
227+
/**
228+
* Register a backend handler acting as source.
174229
*
175-
* @param name Name/key of the settings item.
230+
* @param cs Backend handler node containing handler information.
176231
*
177-
* @param buf buffer for value of the settings item.
178-
* If value is not string, the value will be filled in *buf.
232+
*/
233+
void settings_src_register(struct settings_store *cs);
234+
235+
/**
236+
* Register a backend handler acting as destination.
179237
*
180-
* @param buf_len size of buf.
238+
* @param cs Backend handler node containing handler information.
181239
*
182-
* @return Positive: Length of copied dat. Negative: -ERCODE
183240
*/
184-
int settings_get_value(char *name, char *buf, int buf_len);
241+
void settings_dst_register(struct settings_store *cs);
242+
243+
244+
/*
245+
* API for handler lookup
246+
*/
185247

186248
/**
187-
* Call commit for all settings handler. This should apply all
188-
* settings which has been set, but not applied yet.
249+
* Parses a key to an array of elements and locate corresponding module handler.
189250
*
190-
* @param name Name of the settings subtree, or NULL to commit everything.
251+
* @param name Key in string format
252+
* @param name_argc Parsed number of elements.
253+
* @param name_argv Parsed array of elements.
191254
*
192-
* @return 0 on success, non-zero on failure.
255+
* @return settings_handler node on success, NULL on failure.
256+
*/
257+
struct settings_handler *settings_parse_and_lookup(char *name, int *name_argc,
258+
char *name_argv[]);
259+
260+
261+
/*
262+
* API for runtime settings
193263
*/
194-
int settings_commit(char *name);
264+
265+
#ifdef CONFIG_SETTINGS_RUNTIME
195266

196267
/**
197-
* Persistent data extracting routine.
198-
*
199-
* This function read and decode data from non-volatile storage to user buffer
200-
* This function should be used inside set handler in order to read the settings
201-
* data from backend storage.
268+
* Set a value with a specific key to a module handler.
202269
*
203-
* @param[in] value_ctx Data context provided by the h_set handler.
204-
* @param[out] buf Buffer for data read.
205-
* @param[in] len Length of @p buf.
270+
* @param name Key in string format.
271+
* @param data Binary value.
272+
* @param len Value length in bytes.
206273
*
207-
* @retval Negative value on failure. 0 and positive: Length of data loaded to
208-
* the @p buf.
274+
* @return 0 on success, non-zero on failure.
209275
*/
210-
int settings_val_read_cb(void *value_ctx, void *buf, size_t len);
276+
int settings_runtime_set(const char *name, void *data, size_t len);
211277

212278
/**
213-
* This function fetch length of decode data.
214-
* This function should be used inside set handler in order to detect the
215-
* settings data length.
279+
* Get a value corresponding to a key from a module handler.
216280
*
217-
* @param[in] value_ctx Data context provided by the h_set handler.
281+
* @param name Key in string format.
282+
* @param data Returned binary value.
283+
* @param len Returned value length in bytes.
218284
*
219-
* @retval length of data.
285+
* @return 0 on success, non-zero on failure.
220286
*/
221-
size_t settings_val_get_len_cb(void *value_ctx);
287+
int settings_runtime_get(const char *name, void *data, size_t len);
222288

223289
/**
224-
* @} settings
290+
* Apply settings in a module handler.
291+
*
292+
* @param name Key in string format.
293+
*
294+
* @return 0 on success, non-zero on failure.
225295
*/
296+
int settings_runtime_commit(const char *name);
297+
298+
#endif /* CONFIG_SETTINGS_RUNTIME */
226299

227-
/*
228-
* Config storage
229-
*/
230-
struct settings_store_itf;
231-
struct settings_store {
232-
sys_snode_t cs_next;
233-
const struct settings_store_itf *cs_itf;
234-
};
235300

236301
#ifdef __cplusplus
237302
}

0 commit comments

Comments
 (0)