This is an automated email from the ASF dual-hosted git repository.

kasjer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit 628ec5aa6127a780a6c3e12452cb13c630364956
Author: Jerzy Kasenberg <[email protected]>
AuthorDate: Wed May 6 09:03:27 2026 +0200

    sys/config: Add static conf handlers support
    
    So far conf_handlers could be registered at run time.
    This approach delays loading of configuration till
    application start processing events.
    
    This limits what can be configured in config.
    
    Now system supports static configuration,
    conf_handler can be put in link time table
    so conf_handler is ready from the very start
    and configuration can be loaded earlier.
    
    CONFIG_AUTO_LOAD syscfg value allows to load
    configuration during initialization of config
    subsystem as static handlers are already in place.
    
    Dynamic handlers are still supported while discuraged.
    
    Signed-off-by: Jerzy Kasenberg <[email protected]>
---
 sys/config/include/config/config.h |  7 +++++
 sys/config/pkg.yml                 |  3 +++
 sys/config/src/config.c            | 53 ++++++++++++++++++++++++++++++--------
 sys/config/src/config_init.c       |  4 +++
 sys/config/src/config_store.c      | 18 ++++++++++---
 sys/config/syscfg.yml              | 17 ++++++++++++
 6 files changed, 87 insertions(+), 15 deletions(-)

diff --git a/sys/config/include/config/config.h 
b/sys/config/include/config/config.h
index 81ab7a6f4..84f67ce08 100644
--- a/sys/config/include/config/config.h
+++ b/sys/config/include/config/config.h
@@ -28,6 +28,7 @@
 #include <stdint.h>
 #include <stdbool.h>
 #include <syscfg/syscfg.h>
+#include <os/link_tables.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -426,6 +427,12 @@ void conf_lock(void);
  */
 void conf_unlock(void);
 
+typedef struct conf_handler *conf_handler_t;
+LINK_TABLE(struct conf_handler *, static_conf_handlers);
+
+#define STATIC_CONF_HANDLER(handler)                                          \
+    LINK_TABLE_ELEMENT_REF(static_conf_handlers, handler, handler);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/sys/config/pkg.yml b/sys/config/pkg.yml
index 3866f31f1..9f7829716 100644
--- a/sys/config/pkg.yml
+++ b/sys/config/pkg.yml
@@ -41,6 +41,9 @@ pkg.deps.CONFIG_LITTLEFS:
 
 pkg.whole_archive: true
 
+pkg.link_tables:
+    - static_conf_handlers
+
 pkg.init:
     config_pkg_init: 'MYNEWT_VAL(CONFIG_SYSINIT_STAGE_1)'
     config_pkg_init_stage2: 'MYNEWT_VAL(CONFIG_SYSINIT_STAGE_2)'
diff --git a/sys/config/src/config.c b/sys/config/src/config.c
index b03a285e1..3e675b6b1 100644
--- a/sys/config/src/config.c
+++ b/sys/config/src/config.c
@@ -21,6 +21,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <float.h>
+#include <os/link_tables.h>
 
 #include "os/mynewt.h"
 #include "base64/base64.h"
@@ -48,7 +49,9 @@ conf_init(void)
 
     os_mutex_init(&conf_mtx);
 
-    SLIST_INIT(&conf_handlers);
+    if (MYNEWT_VAL(CONFIG_HANDLERS_DYNAMIC)) {
+        SLIST_INIT(&conf_handlers);
+    }
     conf_store_init();
 
     (void)rc;
@@ -104,9 +107,18 @@ conf_handler_lookup(char *name)
 {
     struct conf_handler *ch;
 
-    SLIST_FOREACH(ch, &conf_handlers, ch_list) {
-        if (!strcmp(name, ch->ch_name)) {
-            return ch;
+    if (MYNEWT_VAL(CONFIG_HANDLERS_STATIC)) {
+        LINK_TABLE_FOREACH(h, static_conf_handlers) {
+            if (!strcmp(name, (*h)->ch_name)) {
+                return *h;
+            }
+        }
+    }
+    if (MYNEWT_VAL(CONFIG_HANDLERS_DYNAMIC)) {
+        SLIST_FOREACH(ch, &conf_handlers, ch_list) {
+            if (!strcmp(name, ch->ch_name)) {
+                return ch;
+            }
         }
     }
     return NULL;
@@ -412,8 +424,15 @@ conf_export(conf_export_func_t export_func, enum 
conf_export_tgt tgt)
     struct conf_handler *ch;
 
     conf_lock();
-    SLIST_FOREACH(ch, &conf_handlers, ch_list) {
-        conf_export_cb(ch, export_func, tgt);
+    if (MYNEWT_VAL(CONFIG_HANDLERS_STATIC)) {
+        LINK_TABLE_FOREACH(h, static_conf_handlers) {
+            conf_export_cb(*h, export_func, tgt);
+        }
+    }
+    if (MYNEWT_VAL(CONFIG_HANDLERS_DYNAMIC)) {
+        SLIST_FOREACH(ch, &conf_handlers, ch_list) {
+            conf_export_cb(ch, export_func, tgt);
+        }
     }
     conf_unlock();
 }
@@ -487,11 +506,23 @@ conf_commit(char *name)
         rc = conf_commit_cb(ch);
     } else {
         rc = 0;
-        SLIST_FOREACH(ch, &conf_handlers, ch_list) {
-            if (ch->ch_commit) {
-                rc2 = conf_commit_cb(ch);
-                if (!rc) {
-                    rc = rc2;
+        if (MYNEWT_VAL(CONFIG_HANDLERS_STATIC)) {
+            LINK_TABLE_FOREACH(h, static_conf_handlers) {
+                if ((*h)->ch_commit) {
+                    rc2 = conf_commit_cb(*h);
+                    if (!rc) {
+                        rc = rc2;
+                    }
+                };
+            }
+        }
+        if (MYNEWT_VAL(CONFIG_HANDLERS_DYNAMIC)) {
+            SLIST_FOREACH(ch, &conf_handlers, ch_list) {
+                if (ch->ch_commit) {
+                    rc2 = conf_commit_cb(ch);
+                    if (!rc) {
+                        rc = rc2;
+                    }
                 }
             }
         }
diff --git a/sys/config/src/config_init.c b/sys/config/src/config_init.c
index 8108713f5..2392ede50 100644
--- a/sys/config/src/config_init.c
+++ b/sys/config/src/config_init.c
@@ -125,6 +125,10 @@ config_pkg_init(void)
 #elif MYNEWT_VAL(CONFIG_FCB2)
     config_init_fcb2();
 #endif
+#if MYNEWT_VAL(CONFIG_AUTO_LOAD)
+    conf_load();
+#endif
+
 #endif
 }
 
diff --git a/sys/config/src/config_store.c b/sys/config/src/config_store.c
index a5bc5828a..f1ac586a0 100644
--- a/sys/config/src/config_store.c
+++ b/sys/config/src/config_store.c
@@ -304,10 +304,20 @@ conf_save(void)
         cs->cs_itf->csi_save_start(cs);
     }
     rc = 0;
-    SLIST_FOREACH(ch, &conf_handlers, ch_list) {
-        rc2 = conf_export_cb(ch, conf_store_one, CONF_EXPORT_PERSIST);
-        if (!rc) {
-            rc = rc2;
+    if (MYNEWT_VAL(CONFIG_HANDLERS_STATIC)) {
+        LINK_TABLE_FOREACH(h, static_conf_handlers) {
+            rc2 = conf_export_cb(*h, conf_store_one, CONF_EXPORT_PERSIST);
+            if (!rc) {
+                rc = rc2;
+            }
+        }
+    }
+    if (MYNEWT_VAL(CONFIG_HANDLERS_DYNAMIC)) {
+        SLIST_FOREACH(ch, &conf_handlers, ch_list) {
+            rc2 = conf_export_cb(ch, conf_store_one, CONF_EXPORT_PERSIST);
+            if (!rc) {
+                rc = rc2;
+            }
         }
     }
     if (cs->cs_itf->csi_save_end) {
diff --git a/sys/config/syscfg.yml b/sys/config/syscfg.yml
index f4de27fdb..49731dee2 100644
--- a/sys/config/syscfg.yml
+++ b/sys/config/syscfg.yml
@@ -83,6 +83,23 @@ syscfg.defs:
         description: 'Automatically configure a single config region at bootup'
         value: 1
 
+    CONFIG_AUTO_LOAD:
+        description: >
+            Load config values during config init stage. This could be enabled
+            if all config handlers are statically defined.
+        value: 0
+
+    CONFIG_HANDLERS_DYNAMIC:
+        description: >
+            Config handler can be registered in runtime via conf_register.
+        value: 1
+
+    CONFIG_HANDLERS_STATIC:
+        description: >
+            Config handler are configured during build. Reducing memory
+            footprint and package init dependency
+        value: 1
+
     CONFIG_SYSINIT_STAGE_1:
         description: >
             Primary sysinit stage for the config package.

Reply via email to