| Config |
| ====== |
| |
| Config subsystem is meant for persisting per-device configuration |
| and runtime state for packages. |
| |
| Configuration items are stored as key-value pairs, where both the key and |
| the value are expected to be strings. Keys are divided into component |
| elements, where packages register their subtree using the first element. |
| E.g key ``id/serial`` consists of 2 components, ``id`` and ``serial``. |
| Package sys/id registered it's subtree of configuration elements to be |
| under ``id``. |
| |
| There are convenience routines for converting value back and forth |
| from string. |
| |
| Handlers |
| ~~~~~~~~ |
| Config handlers for subtree implement a set of handler functions. |
| These are registered using a call to ``conf_register()``. |
| |
| - ch_get |
| This gets called when somebody asks for a config element value |
| by it's name using ``conf_get_value()``. |
| |
| - ch_set |
| This is called when value is being set using ``conf_set_value()``, and |
| also when configuration is loaded from persisted storage with |
| ``conf_load()``. |
| |
| - ch_commit |
| This gets called after configuration has been loaded in full. |
| Sometimes you don't want individual configuration value to take |
| effect right away, for example if there are multiple settings |
| which are interdependent. |
| |
| - ch_export |
| This gets called to dump all current configuration. This happens |
| when ``conf_save()`` tries to save the settings, or when CLI is |
| dumping current system configuration to console. |
| |
| Persistence |
| ~~~~~~~~~~~ |
| Backend storage for the config can be either FCB, a file in filesystem, |
| or both. |
| |
| You can declare multiple sources for configuration; settings from |
| all of these are restored when ``conf_load()`` is called. |
| |
| There can be only one target for writing configuration; this is where |
| data is stored when you call ``conf_save()``, or conf_save_one(). |
| |
| FCB read target is registered using ``conf_fcb_src()``, and write target |
| using ``conf_fcb_dst()``. ``conf_fcb_src()`` as side-effect initializes the |
| FCB area, so it must be called when calling ``conf_fcb_dst()``. |
| File read target is registered using ``conf_file_src()``, and write target |
| ``conf_file_dst()``. |
| |
| Convenience initialization of one config area can be enabled by |
| setting either syscfg variable CONFIG_FCB or CONFIG_NFFS. These |
| use other syscfg variables to figure which flash_map entry of BSP |
| defines flash area, or which file to use. Check the syscfg.yml in |
| sys/config package for more detailed description. |
| |
| CLI |
| ~~~ |
| This can be enabled when shell package is enabled by setting syscfg |
| variable CONFIG_CLI to 1. |
| |
| Here you can set config variables, inspect their values and print |
| both saved configuration as well as running configuration. |
| |
| - config dump |
| Dump the current running configuration |
| |
| - config dump saved |
| Dump the saved configuration. The values are printed in the ordered |
| they're restored. |
| |
| - config <key> |
| Print the value of config variable identified by <key> |
| |
| - config <key> <value> |
| Set the value of config variable <key> to be <value> |
| |
| Example: Device Configuration |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| This is a simple example, config handler only implements ``ch_set`` and |
| ``ch_export``. ``ch_set`` is called when value is restored from storage (or |
| when set initially), and ``ch_export`` is used to write the value to |
| storage (or dump to console). |
| |
| .. code:: c |
| |
| static int8 foo_val; |
| |
| struct conf_handler my_conf = { |
| .ch_name = "foo", |
| .ch_set = foo_conf_set, |
| .ch_export = foo_conf_export |
| } |
| |
| static int |
| foo_conf_set(int argc, char **argv, char *val) |
| { |
| if (argc == 1) { |
| if (!strcmp(argv[0], "bar")) { |
| return CONF_VALUE_SET(val, CONF_INT8, foo_val); |
| } |
| } |
| return OS_ENOENT; |
| } |
| |
| static int |
| foo_conf_export(void (*func)(char *name, char *val), enum conf_export_tgt tgt) |
| { |
| char buf[4]; |
| |
| conf_str_from_value(CONF_INT8, &foo_val, buf, sizeof(buf)); |
| func("foo/bar", buf) |
| return 0; |
| } |
| |
| Example: Persist Runtime State |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| This is a simple example showing how to persist runtime state. Here |
| there is only ``ch_set`` defined, which is used when restoring value from |
| persisted storage. |
| |
| There's a os_callout function which increments foo_val, and then |
| persists the latest number. When system restarts, and calls ``conf_load()``, |
| foo_val will continue counting up from where it was before restart. |
| |
| .. code:: c |
| |
| static int8 foo_val; |
| |
| struct conf_handler my_conf = { |
| .ch_name = "foo", |
| .ch_set = foo_conf_set |
| } |
| |
| static int |
| foo_conf_set(int argc, char **argv, char *val) |
| { |
| if (argc == 1) { |
| if (!strcmp(argv[0], "bar")) { |
| return CONF_VALUE_SET(val, CONF_INT8, foo_val); |
| } |
| } |
| return OS_ENOENT; |
| } |
| |
| static void |
| foo_callout(struct os_event *ev) |
| { |
| struct os_callout *c = (struct os_callout *)ev; |
| char buf[4]; |
| |
| foo_val++; |
| conf_str_from_value(CONF_INT8, &foo_val, buf, sizeof(buf)); |
| conf_save_one("foo/bar", bar); |
| |
| callout_reset(c, OS_TICKS_PER_SEC * 120); |
| } |
| |
| API |
| ---------- |
| |
| .. doxygengroup:: SysConfig |
| :content-only: |
| :members: |