You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2017/11/20 23:28:36 UTC

[GitHub] mkiiskila closed pull request #660: sys/config; doxygen formatted comments.

mkiiskila closed pull request #660: sys/config; doxygen formatted comments.
URL: https://github.com/apache/mynewt-core/pull/660
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/docs/doxygen.xml b/docs/doxygen.xml
index 778a4f51d..35062b133 100644
--- a/docs/doxygen.xml
+++ b/docs/doxygen.xml
@@ -789,7 +789,7 @@ WARN_LOGFILE           =
 # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = kernel
+INPUT                  = kernel sys/config
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/docs/mynewt_doc/modules/config/config.rst b/docs/mynewt_doc/modules/config/config.rst
new file mode 100644
index 000000000..0fca99f81
--- /dev/null
+++ b/docs/mynewt_doc/modules/config/config.rst
@@ -0,0 +1,173 @@
+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:: sys_config
+    :content-only:
diff --git a/sys/config/include/config/config.h b/sys/config/include/config/config.h
index 7755a8bdf..7711b25d7 100644
--- a/sys/config/include/config/config.h
+++ b/sys/config/include/config/config.h
@@ -26,6 +26,11 @@
 extern "C" {
 #endif
 
+/**
+ * @defgroup sys_config sys/config package
+ * @{
+ */
+
 #define CONF_MAX_DIR_DEPTH	8	/* max depth of config tree */
 #define CONF_MAX_NAME_LEN	(8 * CONF_MAX_DIR_DEPTH)
 #define CONF_MAX_VAL_LEN	256
@@ -33,6 +38,9 @@ extern "C" {
 
 #define CONF_NMGR_OP		0
 
+/**
+ * Type of configuration value.
+ */
 enum conf_type {
     CONF_NONE = 0,
     CONF_DIR,
@@ -47,6 +55,9 @@ enum conf_type {
     CONF_BOOL,
 } __attribute__((__packed__));
 
+/**
+ * Parameter to commit handler describing where data is going to.
+ */
 enum conf_export_tgt {
     CONF_EXPORT_PERSIST,        /* Value is to be persisted. */
     CONF_EXPORT_SHOW            /* Value is to be displayed. */
@@ -63,13 +74,44 @@ struct conf_handler {
 };
 
 void conf_init(void);
-int conf_register(struct conf_handler *);
+void conf_store_init(void);
+
+/**
+ * Register a handler for configurations items.
+ *
+ * @param cf Structure containing registration info.
+ *
+ * @return 0 on success, non-zero on failure.
+ */
+int conf_register(struct conf_handler *cf);
+
+/**
+ * Load configuration from registered persistence sources. Handlers for
+ * configuration subtrees registered earlier will be called for encountered
+ * values.
+ *
+ * @return 0 on success, non-zero on failure.
+ */
 int conf_load(void);
 
+/**
+ * Save currently running configuration. All configuration which is different
+ * from currently persisted values will be saved.
+ *
+ * @return 0 on success, non-zero on failure.
+ */
 int conf_save(void);
-int conf_save_one(const char *name, char *var);
 
-void conf_store_init(void);
+/**
+ * Write a single configuration value to persisted storage (if it has
+ * changed value).
+ *
+ * @param name Name/key of the configuration item.
+ * @param var Value of the configuration item.
+ *
+ * @return 0 on success, non-zero on failure.
+ */
+int conf_save_one(const char *name, char *var);
 
 /*
   XXXX for later
@@ -77,21 +119,105 @@ void conf_store_init(void);
   int conf_save_var(char *name, char *var);
 */
 
+/**
+ * Set configuration item identified by @p name to be value @p val_str.
+ * This finds the configuration handler for this subtree and calls it's
+ * set handler.
+ *
+ * @param name Name/key of the configuration item.
+ * @param val_str Value of the configuration item.
+ *
+ * @return 0 on success, non-zero on failure.
+ */
 int conf_set_value(char *name, char *val_str);
+
+/**
+ * Get value of configuration item identified by @p name.
+ * This calls the configuration handler ch_get for the subtree.
+ *
+ * Configuration handler can copy the string to @p buf, the maximum
+ * number of bytes it will copy is limited by @p buf_len.
+ *
+ * Return value will be pointer to beginning of the value. Note that
+ * this might, or might not be the same as buf.
+ *
+ * @param name Name/key of the configuration item.
+ * @param val_str Value of the configuration item.
+ *
+ * @return 0 on success, non-zero on failure.
+ */
 char *conf_get_value(char *name, char *buf, int buf_len);
+
+/**
+ * Call commit for all configuration handler. This should apply all
+ * configuration which has been set, but not applied yet.
+ *
+ * @param name Name of the configuration subtree, or NULL to commit everything.
+ *
+ * @return 0 on success, non-zero on failure.
+ */
 int conf_commit(char *name);
 
+/**
+ * Convenience routine for converting value passed as a string to native
+ * data type.
+ *
+ * @param val_str Value of the configuration item as string.
+ * @param type Type of the value to convert to.
+ * @param vp Pointer to variable to fill with the decoded value.
+ * @param vp Size of that variable.
+ *
+ * @return 0 on success, non-zero on failure.
+ */
 int conf_value_from_str(char *val_str, enum conf_type type, void *vp,
   int maxlen);
+
+/**
+ * Convenience routine for converting byte array passed as a base64
+ * encoded string.
+ *
+ * @param val_str Value of the configuration item as string.
+ * @param vp Pointer to variable to fill with the decoded value.
+ * @param len Size of that variable. On return the number of bytes in the array.
+ *
+ * @return 0 on success, non-zero on failure.
+ */
 int conf_bytes_from_str(char *val_str, void *vp, int *len);
+
+/**
+ * Convenience routine for converting native data type to a string.
+ *
+ * @param type Type of the value to convert from.
+ * @param vp Pointer to variable to convert.
+ * @param buf Buffer where string value will be stored.
+ * @param buf_len Size of the buffer.
+ *
+ * @return 0 on success, non-zero on failure.
+ */
 char *conf_str_from_value(enum conf_type type, void *vp, char *buf,
   int buf_len);
 #define CONF_STR_FROM_BYTES_LEN(len) (((len) * 4 / 3) + 4)
+
+/**
+ * Convenience routine for converting byte array into a base64
+ * encoded string.
+ *
+ * @param vp Pointer to variable to convert.
+ * @param vp_len Number of bytes to convert.
+ * @param buf Buffer where string value will be stored.
+ * @param buf_len Size of the buffer.
+ *
+ * @return 0 on success, non-zero on failure.
+ */
 char *conf_str_from_bytes(void *vp, int vp_len, char *buf, int buf_len);
 
 #define CONF_VALUE_SET(str, type, val)                                  \
     conf_value_from_str((str), (type), &(val), sizeof(val))
 
+/**
+ * @} sys_config
+ */
+
 /*
  * Config storage
  */


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services