-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sys Runtime Configuration Registry #19895
base: master
Are you sure you want to change the base?
Changes from all commits
6aa217a
a12ae66
55be440
cc16efb
f38a736
cd6cd1b
e04a3c5
23ad414
8df46ed
b5ebf73
c559924
99aa25f
786f823
63562cd
47dd545
54e5f9a
502e658
d858212
52f0169
35abb4a
52d208d
40a98a7
3fa904b
efc7a94
111d73c
7b046d0
0674a1a
bf1438d
2f84e38
587d504
ba1d4c4
a70d725
49be2f9
8b00112
938b2b8
7129ca1
34a70b4
749d51a
4d40b09
75842a4
7f42945
f1cbcf5
5675174
845bf27
423d209
bdfc315
9d8da13
66a8e2b
1828302
2d88670
fb8e41e
671acff
f2b82ee
b668ccb
06adb07
0d91422
f7e4008
4a9c124
f9d8c3e
9444fe8
4f9283c
3614909
265043f
491733a
3b3734f
4e28f6a
6820c2b
3dfcd91
e8424e9
74b0a34
c252ad2
909b2f1
2f6eaad
e58fb66
57682a1
dc430db
8c9bbae
d548e02
130d1b5
3204ad6
38c6dc1
95e3ea2
b61abb0
49e643a
3e638c1
f0d6792
50f08d4
9289095
28bad94
b57f297
f74ed61
77937f8
c7d840e
082d89d
82b088a
b73f712
64bfdd9
714e7a3
68a0716
3bd0c7b
1438aa7
b0d8b3b
fc599ed
2de13de
b7577c6
0410dbd
ba4533d
f233a27
8999642
958157c
305fc97
a927ce3
500e7ef
91006b6
fd87b09
d9a7f68
f68fbb1
6102a76
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# name of the application | ||
APPLICATION = registry_example_cli | ||
|
||
# If no BOARD is found in the environment, use this default: | ||
BOARD ?= native | ||
|
||
# This has to be the absolute path to the RIOT base directory: | ||
RIOTBASE ?= $(CURDIR)/../.. | ||
|
||
# required modules | ||
# enable the shell to execute the registry CLI | ||
USEMODULE += shell | ||
USEMODULE += shell_cmds_default | ||
|
||
# enable littlefs2 for the persistent storage of the registry | ||
USEMODULE += littlefs2 | ||
# enable mtd to use it as the storage location | ||
USEMODULE += mtd | ||
|
||
# enable the string_path extension of the registry to | ||
# identify configuration parameters using strings instead of pointers | ||
USEMODULE += registry_string_path | ||
# enable the vfs storage implementation to persistently store configuration | ||
# parameters to a storage device such as the mtd | ||
USEMODULE += registry_storage_vfs | ||
# enable the rgb_led schema (sys/rgb_led) to demonstrate how to configure | ||
# RGB LEDs as an example for the registry CLI | ||
USEMODULE += registry_namespace_sys_rgb_led | ||
|
||
# Comment this out to disable code in RIOT that does safety checking | ||
# which is not needed in a production environment but helps in the | ||
# development process: | ||
DEVELHELP ?= 1 | ||
|
||
# Change this to 0 show compiler invocation lines by default: | ||
QUIET ?= 1 | ||
|
||
include $(RIOTBASE)/Makefile.include |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
examples/registry_cli | ||
================ | ||
|
||
This application demonstrates the most basic usage of the RIOT Registry. | ||
|
||
Usage | ||
===== | ||
|
||
Simply build and flash the application for your target board: | ||
|
||
``` | ||
BOARD=YOUR_BOARD_NAME_HERE make flash term | ||
``` | ||
|
||
Now you should have access to the RIOT shell on your board. For interacting | ||
with the RIOT Registry, use the `registry` shell command, e.g.: | ||
|
||
``` | ||
registry export <- prints the IDs of the whole configuration tree | ||
registry get 0/0/0/0 <- get the value of the red parameter of the instance 0 of the RGB LED Schema inside of the SYS namespace | ||
registry set 0/0/0/0 56 <- set the value of the red parameter to 56 | ||
registry commit 0/0/0/0 <- apply new value for the 0/0/0/0 path | ||
registry save <- save configurations to persistent storage | ||
registry load <- load configurations from persistent storage | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
/* | ||
* Copyright (C) 2023 HAW Hamburg | ||
* | ||
* This file is subject to the terms and conditions of the GNU Lesser | ||
* General Public License v2.1. See the file LICENSE in the top level | ||
* directory for more details. | ||
*/ | ||
|
||
/** | ||
* @ingroup examples | ||
* @{ | ||
* | ||
* @file | ||
* @brief RIOT registry CLI example application to demonstrate how | ||
* to use the RIOT registry using the CLI. | ||
* | ||
* @author Lasse Rosenow <[email protected]> | ||
* | ||
* @} | ||
*/ | ||
|
||
#include <string.h> | ||
#include <stdio.h> | ||
|
||
#include "msg.h" | ||
#include "shell.h" | ||
#include "board.h" | ||
#include "mtd.h" | ||
#include "vfs.h" | ||
#include "fs/littlefs2_fs.h" | ||
#include "registry.h" | ||
#include "registry/namespace/sys.h" | ||
#include "registry/namespace/sys/rgb_led.h" | ||
#include "registry/storage.h" | ||
#include "registry/string_path.h" | ||
|
||
/* this callback is usually implemented drivers such as an RGB LED driver */ | ||
static registry_error_t shared_commit_cb(const registry_commit_cb_scope_t scope, | ||
const registry_group_or_parameter_id_t *group_or_parameter_id, | ||
const void *context) | ||
{ | ||
/* since this function is shared by multiple commit_cb functions, we path the instance in the context */ | ||
const registry_instance_t *instance = context; | ||
const registry_sys_rgb_led_instance_t *data = instance->data; | ||
|
||
printf("RGB instance commit_cb was executed on "); | ||
|
||
/* check how much of the registry instance was committed and print the new values */ | ||
switch (scope) | ||
{ | ||
case REGISTRY_COMMIT_INSTANCE: | ||
/* in this case the whole instance and all parameters inside of it was committed */ | ||
printf("the whole instance: ID: %d\n", instance->id); | ||
printf("\tParameter ID: 0, VALUE: %d\n", data->red); | ||
printf("\tParameter ID: 1, VALUE: %d\n", data->green); | ||
printf("\tParameter ID: 2, VALUE: %d\n", data->blue); | ||
break; | ||
case REGISTRY_COMMIT_GROUP: | ||
/* in this case a group and all parameters inside of it was committed */ | ||
printf("a group: %d\n", *group_or_parameter_id); | ||
/* this instance does not have groups, so no need to print anything here */ | ||
break; | ||
case REGISTRY_COMMIT_PARAMETER: | ||
/* in this case only a single parameter was committed */ | ||
printf("a single parameter: ID: %d,", *group_or_parameter_id); | ||
switch (*group_or_parameter_id) | ||
{ | ||
case 0: printf(" VALUE: %d\n", data->red); break; | ||
case 1: printf(" VALUE: %d\n", data->green); break; | ||
case 2: printf(" VALUE: %d\n", data->blue); break; | ||
} | ||
} | ||
|
||
return REGISTRY_ERROR_NONE; | ||
} | ||
|
||
/* create instances of a configuration schema, to expose configuration parameters to the registry */ | ||
static registry_error_t rgb_led_instance_0_commit_cb(const registry_commit_cb_scope_t scope, | ||
const registry_group_or_parameter_id_t *group_or_parameter_id, | ||
const void *context); | ||
static registry_sys_rgb_led_instance_t rgb_led_instance_0_data = { | ||
.red = 0, | ||
.green = 255, | ||
.blue = 70, | ||
}; | ||
static registry_instance_t rgb_led_instance_0 = { | ||
.name = "rgb-0", | ||
.data = &rgb_led_instance_0_data, | ||
.commit_cb = &rgb_led_instance_0_commit_cb, | ||
}; | ||
static registry_error_t rgb_led_instance_0_commit_cb(const registry_commit_cb_scope_t scope, | ||
const registry_group_or_parameter_id_t *group_or_parameter_id, | ||
const void *context) | ||
{ | ||
(void)context; | ||
return shared_commit_cb(scope, group_or_parameter_id, &rgb_led_instance_0); | ||
} | ||
|
||
/* create an instance for a second RGB LED */ | ||
static registry_error_t rgb_led_instance_1_commit_cb(const registry_commit_cb_scope_t scope, | ||
const registry_group_or_parameter_id_t *group_or_parameter_id, | ||
const void *context); | ||
static registry_sys_rgb_led_instance_t rgb_led_instance_1_data = { | ||
.red = 90, | ||
.green = 4, | ||
.blue = 0, | ||
}; | ||
static registry_instance_t rgb_led_instance_1 = { | ||
.name = "rgb-1", | ||
.data = &rgb_led_instance_1_data, | ||
.commit_cb = &rgb_led_instance_1_commit_cb, | ||
}; | ||
static registry_error_t rgb_led_instance_1_commit_cb(const registry_commit_cb_scope_t scope, | ||
const registry_group_or_parameter_id_t *group_or_parameter_id, | ||
const void *context) | ||
{ | ||
(void)context; | ||
return shared_commit_cb(scope, group_or_parameter_id, &rgb_led_instance_1); | ||
} | ||
|
||
/* configure the registry storage to use littlefs2 */ | ||
static littlefs2_desc_t fs_desc = { | ||
.lock = MUTEX_INIT, | ||
}; | ||
|
||
/* set the mount point for the registry storage to /sda for this example */ | ||
static vfs_mount_t _vfs_mount = { | ||
.fs = &littlefs2_file_system, | ||
.mount_point = "/sda", | ||
.private_data = &fs_desc, | ||
}; | ||
|
||
/* create a storage instance to register the storage at the RIOT registry */ | ||
static registry_storage_instance_t vfs_instance = { | ||
.storage = ®istry_storage_vfs, | ||
.data = &_vfs_mount, | ||
}; | ||
|
||
int main(void) | ||
{ | ||
/* initialize the riot registry storage for persistent configuration parameters */ | ||
#if IS_USED(MODULE_LITTLEFS2) | ||
fs_desc.dev = MTD_0; | ||
#endif | ||
|
||
/* initialize the riot registry */ | ||
registry_init(); | ||
|
||
/* set storage instances so that the CLI can find them */ | ||
const registry_storage_instance_t* storage_instances[] = {&vfs_instance}; | ||
registry_storage_set_instances(storage_instances); | ||
|
||
/* add configuration schemas to the registry */ | ||
registry_add_schema_instance(®istry_sys_rgb_led, &rgb_led_instance_0); | ||
registry_add_schema_instance(®istry_sys_rgb_led, &rgb_led_instance_1); | ||
|
||
/* initialize and run the RIOT shell */ | ||
char line_buf[SHELL_DEFAULT_BUFSIZE]; | ||
shell_run(NULL, line_buf, sizeof(line_buf)); | ||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# name of the application | ||
APPLICATION = registry_example_core | ||
|
||
# If no BOARD is found in the environment, use this default: | ||
BOARD ?= native | ||
|
||
# This has to be the absolute path to the RIOT base directory: | ||
RIOTBASE ?= $(CURDIR)/../.. | ||
|
||
# required modules | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For an example it doesn't hurt to say what is the reason for enabling a specific module. That it is required for the example is obvious, but what is the exact effect related to enabling this module? I.e., "Activate the namespace /sys/board/led/", "Enable the default registry configurations for the board led" or something like that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
# enable board_led schema (sys/board_led) of the riot registry | ||
USEMODULE += registry_namespace_sys_board_led | ||
# enable the ztimer to turn the led on and off every second | ||
USEMODULE += ztimer_msec | ||
|
||
# Comment this out to disable code in RIOT that does safety checking | ||
# which is not needed in a production environment but helps in the | ||
# development process: | ||
DEVELHELP ?= 1 | ||
|
||
# Change this to 0 show compiler invocation lines by default: | ||
QUIET ?= 1 | ||
|
||
include $(RIOTBASE)/Makefile.include |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
examples/registry_core | ||
================ | ||
|
||
This application demonstrates the most basic usage of the RIOT Registry. | ||
It implements a RGB LED schema and continuously changes its value every second. | ||
|
||
Usage | ||
===== | ||
|
||
Simply build and flash the application for your target board: | ||
|
||
``` | ||
BOARD=YOUR_BOARD_NAME_HERE make flash term | ||
``` | ||
|
||
Now you should see the terminal continuously print out different LED states. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/* | ||
* Copyright (C) 2023 HAW Hamburg | ||
* | ||
* This file is subject to the terms and conditions of the GNU Lesser | ||
* General Public License v2.1. See the file LICENSE in the top level | ||
* directory for more details. | ||
*/ | ||
|
||
/** | ||
* @ingroup examples | ||
* @{ | ||
* | ||
* @file | ||
* @brief RIOT registry core minimal example application to demonstrate | ||
* how to use the riot registry without any of its extensions. | ||
* | ||
* @author Lasse Rosenow <[email protected]> | ||
* | ||
* @} | ||
*/ | ||
|
||
#include <string.h> | ||
#include <stdio.h> | ||
#include <unistd.h> | ||
|
||
#include "periph_cpu.h" | ||
#include "led.h" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In theory There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did have some problems when building for |
||
#include "board.h" | ||
#include "registry.h" | ||
#include "registry/namespace/sys.h" | ||
#include "registry/namespace/sys/board_led.h" | ||
#include "ztimer.h" | ||
|
||
registry_error_t board_led_instance_commit_cb(const registry_commit_cb_scope_t scope, | ||
const registry_group_or_parameter_id_t *group_or_parameter_id, | ||
const void *context); | ||
|
||
/* This belongs into the BOARD or Driver for example */ | ||
registry_sys_board_led_instance_t board_led_instance_0_data = { | ||
.enabled = 0, | ||
}; | ||
|
||
registry_instance_t board_led_instance = { | ||
.data = &board_led_instance_0_data, | ||
.commit_cb = &board_led_instance_commit_cb, | ||
}; | ||
|
||
/* this callback is usually implemented drivers such as an RGB LED driver */ | ||
registry_error_t board_led_instance_commit_cb(const registry_commit_cb_scope_t scope, | ||
const registry_group_or_parameter_id_t *group_or_parameter_id, | ||
const void *context) | ||
{ | ||
(void)scope; | ||
(void)context; | ||
|
||
/* Either commit all parameters of the instance or only the given parameter. | ||
* For a single LED there is no difference as it only has one parameter. */ | ||
if ((group_or_parameter_id == NULL) || | ||
(*group_or_parameter_id == REGISTRY_SYS_BOARD_LED_ENABLED)) { | ||
/* The Driver owns the board_led data instance, so we can just get our value from there */ | ||
bool led_state = board_led_instance_0_data.enabled; | ||
/* Turn the LED on or off depending on the led_state */ | ||
if (led_state == true) { | ||
/* This is the commit_cb function of instance 0, so we toggle LED 0 as well */ | ||
LED_ON(0); | ||
} else { | ||
LED_OFF(0); | ||
} | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
/* This belongs into our main application */ | ||
int main(void) | ||
{ | ||
registry_init(); | ||
|
||
/* init schemas */ | ||
registry_add_schema_instance(®istry_sys_board_led, &board_led_instance); | ||
|
||
bool board_led_enabled = false; | ||
|
||
while (true) { | ||
/* Invert the BOARD LED, to make it turn on and off on each subsequent cycle */ | ||
board_led_enabled = !board_led_enabled; | ||
|
||
/* Create registry_node_t for the board_led_parameter */ | ||
const registry_node_t parameter_node = { | ||
.type = REGISTRY_NODE_PARAMETER, | ||
.value.parameter = { | ||
.instance = &board_led_instance, | ||
.parameter = ®istry_sys_board_led_enabled, | ||
}, | ||
}; | ||
|
||
/* Set new registry value */ | ||
registry_set(¶meter_node, &board_led_enabled, sizeof(board_led_enabled)); | ||
|
||
/* Apply the registry value to change the LED state (in this case calls the commit_cb function: "board_led_instance_commit_cb")*/ | ||
registry_commit(¶meter_node); | ||
|
||
/* Sleep for 1 second and then do it again*/ | ||
ztimer_sleep(ZTIMER_MSEC, 1000); | ||
} | ||
|
||
return 0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a number of deviations from the coding convention regarding code formatting. This is not a big deal and coding style is IMO purely about personal preference, but keeping things consistent within the code base does (at least me) help a lot when reading code.
I won't add further comments on style, since this is best left to
uncrustify
orclang-format
.