forked from zephyrproject-rtos/zephyr
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
subsys: settings: Reworked settings module
Preparation to fix zephyrproject-rtos#12160 - settings NVS backend To allow easier integration of backends the settings module has been reworked. Major changes are: 1. Change to the api: the set() routines are now of the form: ''set(int argc, char **argv, size_t len, read_cb read, void *cb_arg)'' the length that was found in the backend in len, and the data can be read using: ''read(data, len, cb_arg); 2. The reading of data in the set routines is directly reading in the backend. 3. The records no longer need to be in the line format 4. The runtime interface has been removed (temporarily). A runtime backend will be added. 5. Only the fcb backend is supported at the moment 6. A sample is added under samples/subsys/nsettings Signed-off-by: Laczen JMS <laczenjms@gmail.com>
- Loading branch information
Showing
16 changed files
with
1,506 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
/* | ||
* Copyright (c) 2018 Nordic Semiconductor ASA | ||
* Copyright (c) 2015 Runtime Inc | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#ifndef ZEPHYR_INCLUDE_SETTINGS_SETTINGS_H_ | ||
#define ZEPHYR_INCLUDE_SETTINGS_SETTINGS_H_ | ||
|
||
#include <sys/types.h> | ||
#include <misc/util.h> | ||
#include <misc/slist.h> | ||
#include <stdint.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* @defgroup settings Settings subsystem | ||
* @ingroup file_system_storage | ||
* @{ | ||
*/ | ||
|
||
#define SETTINGS_MAX_DIR_DEPTH 8 /* max depth of settings tree */ | ||
#define SETTINGS_MAX_NAME_LEN (8 * SETTINGS_MAX_DIR_DEPTH) | ||
#define SETTINGS_MAX_VAL_LEN 256 | ||
#define SETTINGS_NAME_SEPARATOR "/" | ||
|
||
/* pleace for settings additions: | ||
* up to 7 separators, '=', '\0' | ||
*/ | ||
#define SETTINGS_EXTRA_LEN ((SETTINGS_MAX_DIR_DEPTH - 1) + 2) | ||
|
||
#define SETTINGS_NMGR_OP 0 | ||
|
||
typedef ssize_t (*read_cb)(void *data, size_t len, void *cb_arg); | ||
|
||
/** | ||
* @struct settings_handler | ||
* Config handlers for subtree implement a set of handler functions. | ||
* These are registered using a call to @ref settings_register. | ||
*/ | ||
struct settings_handler { | ||
sys_snode_t node; | ||
/**< Linked list node info for module internal usage. */ | ||
|
||
char *name; | ||
/**< Name of subtree. */ | ||
|
||
int (*h_get)(int argc, char **argv, char *val, int val_len_max); | ||
/**< Get values handler of settings items identified by keyword names. | ||
* | ||
* Parameters: | ||
* - argc - count of item in argv. | ||
* - argv - array of pointers to keyword names. | ||
* - val - buffer for a value. | ||
* - val_len_max - size of that buffer. | ||
*/ | ||
|
||
int (*h_set)(int argc, char **argv, size_t len, read_cb read, | ||
void *cb_arg); | ||
/**< Set value handler of settings items identified by keyword names. | ||
* | ||
* Parameters: | ||
* - argc - count of item in argv, argv - array of pointers to keyword | ||
* names. | ||
* - len - the size of the data found in the backend | ||
* - read - function provided to read the data from the backend | ||
* - cb_arg - arguments for the read function provided by the backend | ||
*/ | ||
|
||
int (*h_commit)(void); | ||
/**< This handler gets called after settings has been loaded in full. | ||
* User might use it to apply setting to the application. | ||
*/ | ||
|
||
int (*h_export)(int (*export_func)(const char *name, void *val, | ||
size_t val_len)); | ||
/**< This gets called to dump all current settings items. | ||
* | ||
* This happens when @ref settings_save tries to save the settings. | ||
* Parameters: | ||
* - export_func: the pointer to the internal function which appends | ||
* a single key-value pair to persisted settings. Don't store | ||
* duplicated value. The name is subtree/key string, val is the string | ||
* with value. | ||
* | ||
* @remarks The User might limit a implementations of handler to serving | ||
* only one keyword at one call - what will impose limit to get/set | ||
* values using full subtree/key name. | ||
*/ | ||
}; | ||
|
||
/** | ||
* Initialization of settings and backend | ||
* | ||
* Can be called at application startup. | ||
* In case the backend is NFFS Remember to call it after FS was mounted. | ||
* For FCB backend it can be called without such a restriction. | ||
* | ||
* @return 0 on success, non-zero on failure. | ||
*/ | ||
int settings_subsys_init(void); | ||
|
||
/** | ||
* Register a handler for settings items. | ||
* | ||
* @param cf Structure containing registration info. | ||
* | ||
* @return 0 on success, non-zero on failure. | ||
*/ | ||
int settings_register(struct settings_handler *cf); | ||
|
||
/** | ||
* Load serialized items from registered persistence sources. Handlers for | ||
* serialized item subtrees registered earlier will be called for encountered | ||
* values. | ||
* | ||
* @return 0 on success, non-zero on failure. | ||
*/ | ||
int settings_load(void); | ||
|
||
/** | ||
* Save currently running serialized items. All serialized items which are | ||
* different from currently persisted values will be saved. | ||
* | ||
* @return 0 on success, non-zero on failure. | ||
*/ | ||
int settings_save(void); | ||
|
||
/** | ||
* Write a single serialized value to persisted storage (if it has | ||
* changed value). | ||
* | ||
* @param name Name/key of the settings item. | ||
* @param value Pointer to the value of the settings item. This value will | ||
* be transferred to the @ref settings_handler::h_export handler implementation. | ||
* @param val_len Length of the value. | ||
* | ||
* @return 0 on success, non-zero on failure. | ||
*/ | ||
int settings_save_one(const char *name, void *value, size_t val_len); | ||
|
||
/** | ||
* Delete a single serialized in persisted storage. | ||
* | ||
* Deleting an existing key-value pair in the settings mean | ||
* to set its value to NULL. | ||
* | ||
* @param name Name/key of the settings item. | ||
* | ||
* @return 0 on success, non-zero on failure. | ||
*/ | ||
int settings_delete(const char *name); | ||
|
||
/** | ||
* Call commit for all settings handler. This should apply all | ||
* settings which has been set, but not applied yet. | ||
* | ||
* @param name Name of the settings subtree, or NULL to commit everything. | ||
* | ||
* @return 0 on success, non-zero on failure. | ||
*/ | ||
int settings_commit(char *name); | ||
|
||
/** | ||
* @} settings | ||
*/ | ||
|
||
/* | ||
* Config storage | ||
*/ | ||
struct settings_store_itf; | ||
struct settings_store { | ||
sys_snode_t cs_next; | ||
const struct settings_store_itf *cs_itf; | ||
}; | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* ZEPHYR_INCLUDE_SETTINGS_SETTINGS_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
cmake_minimum_required(VERSION 3.8.2) | ||
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE) | ||
project(nsetting) | ||
|
||
FILE(GLOB app_sources src/*.c) | ||
target_sources(app PRIVATE ${app_sources}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
.. _nvs-sample: | ||
|
||
NVS: Non-Volatile Storage | ||
######################### | ||
|
||
Overview | ||
******** | ||
|
||
This is a simple application demonstrating use of the NVS | ||
module for non-volatile (flash) storage. In this application, | ||
a counter is incremented on every reboot and stored in flash, | ||
the application reboots, and the reboot counter data is retrieved. | ||
|
||
Requirements | ||
************ | ||
|
||
* A board with flash support | ||
|
||
Building and Running | ||
******************** | ||
|
||
This sample can be found under :file:`samples/subsys/nvs` in the Zephyr tree. | ||
|
||
The sample can be build for several platforms, the following commands build the | ||
application for the nrf51_pca10028 board. | ||
|
||
.. zephyr-app-commands:: | ||
:zephyr-app: samples/subsys/nvs | ||
:board: nrf51_pca10028 | ||
:goals: build flash | ||
:compact: | ||
|
||
After flashing the image to the board the output on the console shows the | ||
reboot counter and the boards reboots several times to show the reboot counter | ||
is incremented. | ||
|
||
Sample Output | ||
============= | ||
|
||
.. code-block:: console | ||
***** Booting Zephyr OS v1.12.0-rc1-176-gf091be783 ***** | ||
[fs/nvs] [DBG] nvs_reinit: (Re)Initializing sectors | ||
[fs/nvs] [DBG] _nvs_sector_init: f->write_location set to c | ||
[fs/nvs] [INF] nvs_init: maximum storage length 256 byte | ||
[fs/nvs] [INF] nvs_init: write-align: 1, write-addr: c | ||
[fs/nvs] [INF] nvs_init: entry sector: 0, entry sector ID: 1 | ||
No address found, adding 192.168.1.1 at id 1 | ||
No key found, adding it at id 2 | ||
No Reboot counter found, adding it at id 3 | ||
Id: 4 not found, adding it | ||
Longarray not found, adding it as id 4 | ||
Reboot counter history: ...0 | ||
Oldest reboot counter: 0 | ||
Rebooting in ...5...4...3...2...1 | ||
***** Booting Zephyr OS v1.12.0-rc1-176-gf091be783 ***** | ||
[fs/nvs] [INF] nvs_init: maximum storage length 256 byte | ||
[fs/nvs] [INF] nvs_init: write-align: 1, write-addr: c7 | ||
[fs/nvs] [INF] nvs_init: entry sector: 0, entry sector ID: 1 | ||
Entry: 1, Address: 192.168.1.1 | ||
Id: 2, Key: ff fe fd fc fb fa f9 f8 | ||
Id: 3, Reboot_counter: 1 | ||
Id: 4, Data: DATA | ||
Id: 5, Longarray: 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 13 14 15 16 17 18 | ||
Reboot counter history: ...1...0 | ||
Oldest reboot counter: 0 | ||
Rebooting in ...5...4...3...2...1 | ||
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
CONFIG_FLASH=y | ||
CONFIG_FLASH_PAGE_LAYOUT=y | ||
CONFIG_FLASH_MAP=y | ||
CONFIG_FCB=y | ||
CONFIG_NSETTINGS=y | ||
CONFIG_NSETTINGS_FCB=y | ||
|
||
CONFIG_LOG=y | ||
CONFIG_REBOOT=y | ||
CONFIG_MPU_ALLOW_FLASH_WRITE=y |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
sample: | ||
name: Settings Sample | ||
|
||
tests: | ||
test: | ||
tags: settings | ||
depends_on: nsettings |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/* | ||
* NSETTINGS Sample for Zephyr | ||
* | ||
* Copyright (c) 2018 Laczen | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
|
||
#include <zephyr.h> | ||
#include <misc/reboot.h> | ||
#include <device.h> | ||
#include <string.h> | ||
#include <nsettings/settings.h> | ||
|
||
/* 1000 msec = 1 sec */ | ||
#define SLEEP_TIME 10000 | ||
|
||
u8_t reset_counter; | ||
|
||
static int ps_set(int argc, char **argv, size_t len, read_cb read, void *cb_arg) | ||
{ | ||
int rc; | ||
|
||
if (argc == 1) { | ||
if (!strcmp(argv[0], "ra0")) { | ||
rc = read(&reset_counter, sizeof(reset_counter), | ||
cb_arg); | ||
printk("ra0 found\n"); | ||
} | ||
if (!strcmp(argv[0], "ra1")) { | ||
printk("ra1 found\n"); | ||
} | ||
if (!strcmp(argv[0], "ra2")) { | ||
printk("ra2 found\n"); | ||
} | ||
if (!strcmp(argv[0], "rb")) { | ||
printk("rb found\n"); | ||
} | ||
return (len < 0) ? len : 0; | ||
} | ||
|
||
return -ENOENT; | ||
} | ||
|
||
static struct settings_handler ps_settings = { | ||
.name = "ps", | ||
.h_set = ps_set, | ||
}; | ||
|
||
int ps_settings_init(void) | ||
{ | ||
int err; | ||
|
||
err = settings_subsys_init(); | ||
if (err) { | ||
printk("settings_subsys_init failed (err %d)\n", err); | ||
return err; | ||
} | ||
|
||
err = settings_register(&ps_settings); | ||
if (err) { | ||
printk("ps_settings_register failed (err %d)\n", err); | ||
return err; | ||
} | ||
return 0; | ||
} | ||
|
||
void main(void) | ||
{ | ||
reset_counter = 0U; | ||
ps_settings_init(); | ||
settings_load(); | ||
|
||
while (reset_counter < 6) { | ||
k_sleep(SLEEP_TIME); | ||
reset_counter++; | ||
printk("Reset counter %u\n", reset_counter); | ||
settings_save_one("ps/ra0", &reset_counter, | ||
sizeof(reset_counter)); | ||
settings_save_one("ps/ra1", &reset_counter, | ||
sizeof(reset_counter)); | ||
settings_save_one("ps/ra2", &reset_counter, | ||
sizeof(reset_counter)); | ||
settings_save_one("ps/rb", &reset_counter, | ||
sizeof(reset_counter)); | ||
if (reset_counter == 2) { | ||
settings_delete("ps/rb"); | ||
} | ||
if (reset_counter == 4) { | ||
settings_delete("ps/r"); | ||
} | ||
sys_reboot(0); | ||
} | ||
printk("Finished"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.