You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by je...@apache.org on 2025/07/06 06:27:47 UTC
(mynewt-core) branch master updated (71b9c035d -> f0c90b9bb)
This is an automated email from the ASF dual-hosted git repository.
jerzy pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
from 71b9c035d hw/drivers/i2s: Fix setting for bypass mode
new eda163370 util: Fix link section attribute
new 00fd862e2 sys/shell: Add macros for creating link time commands
new 15cc2b317 sys/shell: Register os commands staticaly
new f0c90b9bb sys/shell: Register prompt module statically
The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
kernel/os/include/os/link_tables.h | 4 +-
sys/shell/include/shell/shell.h | 187 +++++++++++++++++++
sys/shell/pkg.yml | 6 +
sys/shell/src/shell.c | 365 +++++++++++++++++++++----------------
sys/shell/src/shell_os.c | 28 +--
sys/shell/src/shell_priv.h | 3 -
sys/shell/src/shell_prompt.c | 14 +-
7 files changed, 411 insertions(+), 196 deletions(-)
(mynewt-core) 03/04: sys/shell: Register os commands staticaly
Posted by je...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
jerzy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit 15cc2b31721032c3597e4d9bfdf2ab402532140d
Author: Jerzy Kasenberg <je...@codecoup.pl>
AuthorDate: Sat May 31 00:45:30 2025 +0200
sys/shell: Register os commands staticaly
Shell commands are now registered at link time
instead of compile time to compat module commands.
Signed-off-by: Jerzy Kasenberg <je...@apache.org>
---
sys/shell/src/shell_os.c | 28 ++++++----------------------
sys/shell/src/shell_priv.h | 1 -
2 files changed, 6 insertions(+), 23 deletions(-)
diff --git a/sys/shell/src/shell_os.c b/sys/shell/src/shell_os.c
index 9d65ca4d4..d65dae1bc 100644
--- a/sys/shell/src/shell_os.c
+++ b/sys/shell/src/shell_os.c
@@ -273,25 +273,9 @@ static const struct shell_cmd_help ls_dev_help = {
};
#endif
-static const struct shell_cmd os_commands[] = {
- SHELL_CMD_EXT("tasks", shell_os_tasks_display_cmd, &tasks_help),
- SHELL_CMD_EXT("mpool", shell_os_mpool_display_cmd, &mpool_help),
- SHELL_CMD_EXT("date", shell_os_date_cmd, &date_help),
- SHELL_CMD_EXT("reset", shell_os_reset_cmd, &reset_help),
- SHELL_CMD_EXT("reset_cause", shell_os_print_reset_cause, &print_reset_cause_help),
- SHELL_CMD_EXT("lsdev", shell_os_ls_dev_cmd, &ls_dev_help),
- { 0 },
-};
-
-void
-shell_os_register(void)
-{
- const struct shell_cmd *cmd;
- int rc;
-
- for (cmd = os_commands; cmd->sc_cmd != NULL; cmd++) {
- rc = shell_cmd_register(cmd);
- SYSINIT_PANIC_ASSERT_MSG(
- rc == 0, "Failed to register OS shell commands");
- }
-}
+MAKE_SHELL_EXT_CMD(tasks, shell_os_tasks_display_cmd, &tasks_help)
+MAKE_SHELL_EXT_CMD(mpool, shell_os_mpool_display_cmd, &mpool_help)
+MAKE_SHELL_EXT_CMD(date, shell_os_date_cmd, &date_help)
+MAKE_SHELL_EXT_CMD(reset, shell_os_reset_cmd, &reset_help)
+MAKE_SHELL_EXT_CMD(reset_cause, shell_os_print_reset_cause, &print_reset_cause_help)
+MAKE_SHELL_EXT_CMD(lsdev, shell_os_ls_dev_cmd, &ls_dev_help)
diff --git a/sys/shell/src/shell_priv.h b/sys/shell/src/shell_priv.h
index 22e97ba88..6c85d1ac7 100644
--- a/sys/shell/src/shell_priv.h
+++ b/sys/shell/src/shell_priv.h
@@ -49,7 +49,6 @@ void shell_nlip_init(void);
void shell_nlip_clear_pkt(void);
#endif
-void shell_os_register(void);
void shell_prompt_register(void);
#if MYNEWT_VAL(SHELL_BRIDGE)
(mynewt-core) 02/04: sys/shell: Add macros for creating link time commands
Posted by je...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
jerzy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit 00fd862e268bd281e417ad81bd706c11faec5abb
Author: Jerzy Kasenberg <je...@codecoup.pl>
AuthorDate: Sat May 31 00:40:59 2025 +0200
sys/shell: Add macros for creating link time commands
Shell commands and modules used to be registered at
run time by packages. This required code and RAM space.
Both shell modules and commands required RAM of some fixed
size (specified in syscfg). When more commands or shell
modules were registered assertion failed at run time.
Now it's possibly to create shell commands that will be
'registered' at link time and will not require RAM
nor explicit function call.
This should eliminate problem of registering to
many modules or commands.
Signed-off-by: Jerzy Kasenberg <je...@apache.org>
---
sys/shell/include/shell/shell.h | 187 ++++++++++++++++++++
sys/shell/pkg.yml | 6 +
sys/shell/src/shell.c | 365 ++++++++++++++++++++++------------------
3 files changed, 398 insertions(+), 160 deletions(-)
diff --git a/sys/shell/include/shell/shell.h b/sys/shell/include/shell/shell.h
index efb56beb2..691489b16 100644
--- a/sys/shell/include/shell/shell.h
+++ b/sys/shell/include/shell/shell.h
@@ -25,6 +25,7 @@ extern "C" {
#endif
#include "os/mynewt.h"
+#include "os/link_tables.h"
#include "streamer/streamer.h"
struct os_eventq;
@@ -85,6 +86,192 @@ struct shell_module {
const struct shell_cmd *commands;
};
+typedef const struct shell_mod *shell_mod_t;
+typedef const struct shell_cmd *shell_cmd_t;
+
+/*
+ * Shell module enumeration functions
+ */
+typedef struct shell_mod_ops {
+ /** Returns number of module commands */
+ size_t (*count)(shell_mod_t mod);
+ /** Return module command by it's index */
+ shell_cmd_t (*get)(shell_mod_t mod, size_t ix);
+} shell_mod_ops_t;
+
+/*
+ * Shell module
+ */
+struct shell_mod {
+ /* Shell module functions */
+ const shell_mod_ops_t *ops;
+ /* Shell module name visible to end use */
+ const char *name;
+};
+
+/*
+ * Shell module with static array of commands
+ */
+typedef struct shell_mod_std {
+ /* Inherited shell module */
+ struct shell_mod mod;
+ /* Beginning of command array */
+ const struct shell_cmd *commands;
+ /* Pointer to end of command array */
+ const struct shell_cmd *commands_end;
+} shell_mod_std_t;
+extern const struct shell_mod_ops shell_mod_std_ops;
+
+static inline int
+shell_mod_command_count(shell_mod_t mod)
+{
+ return mod->ops->count(mod);
+}
+
+static inline shell_cmd_t
+shell_mod_command(shell_mod_t mod, size_t ix)
+{
+ return mod->ops->get(mod, ix);
+}
+
+LINK_TABLE(shell_mod_t, shell_modules)
+/* Section name for shell modules */
+#define SHELL_MODULES_SECTION LINK_TABLE_SECTION(shell_modules)
+#define SHELL_MODULE_SECTION(mod) \
+ LINK_TABLE_ELEMENT_SECTION(shell_modules, mod)
+
+/**
+ * Create shell module with commands designated by begin and end pointers
+ *
+ * This will create object of type shell_mod_std and pointer to this object.
+ * Pointer will be placed in .shell_modules section so it will be put
+ * together with all other shell modules on one link time table.
+ *
+ * @param _name - name of the module
+ * @param _command_begin - pointer to start of the table with commands
+ * @param _command_end - pointer to end of the table with commands
+ */
+#define SHELL_MODULE_STD(_name, _command_begin, _command_end) \
+ const shell_mod_std_t shell_module_##_name = { \
+ { &shell_mod_std_ops, #_name }, \
+ _command_begin, _command_end \
+ }; \
+ LINK_TABLE_ELEMENT_REF(shell_modules, _name, shell_module_##_name.mod)
+
+/**
+ * Create shell module with static command table
+ *
+ * @param _name - name of the module
+ * @parma _table - standard table of const struct shell_cmd with know size
+ */
+#define SHELL_MODULE_WITH_TABLE(name_, table_) \
+ SHELL_MODULE_STD(name_, table_, table_ + ARRAY_SIZE(table_))
+
+#define SHELL_MODULE_CMD_SECTION(mod_, cmd_) \
+ LINK_TABLE_ELEMENT_SECTION(mod_##_commands, cmd_)
+/* Section name for shell compat (global) commands */
+#define SHELL_COMPAT_CMDS_SECTION LINK_TABLE_SECTION(compat_commands)
+/* Section name for shell compat command */
+#define SHELL_COMPAT_CMD_SECTION(cmd_) SHELL_MODULE_CMD_SECTION(compat, cmd_)
+
+/**
+ * Create shell module with link time table (name derived from _name)
+ *
+ * Link table will have name derived from shell module.
+ * Link table must be declared in some pkg.yml in pkg.link_tables: section
+ *
+ * i.e.
+ * pkg.yml
+ *
+ * pkg.link_tables:
+ * - mcu_commands
+ *
+ * mcu_cli.c
+ *
+ * SHELL_MODULE_WITH_LINK_TABLE(mcu)
+ *
+ * @param _name - name of the shell module
+ */
+#define SHELL_MODULE_WITH_LINK_TABLE(_name) \
+ LINK_TABLE(struct shell_cmd, _name##_commands) \
+ SHELL_MODULE_STD(_name, LINK_TABLE_START(_name##_commands), \
+ LINK_TABLE_END(_name##_commands))
+
+/**
+ * Create command for module
+ *
+ * Macro creates object of struct shell_cmd and puts it in link table
+ * for module
+ *
+ * @param mod_ - module name
+ * @param cmd_ - command name
+ * @param name_ - command name as string
+ * @param ext_ - 1 for extended command with streamer
+ * @param func_ - function to execute
+ * @param help_ - help structure for function
+ */
+#define SHELL_MODULE_CMD_WITH_NAME(mod_, cmd_, name_, ext_, func_, help_) \
+ const struct shell_cmd shell_cmd_##cmd_ SHELL_MODULE_CMD_SECTION(mod_, cmd_) = { \
+ .sc_ext = ext_, \
+ .sc_cmd_ext_func = (shell_cmd_ext_func_t)(func_), \
+ .sc_cmd = name_, \
+ .help = SHELL_HELP_(help_), \
+ };
+
+/**
+ * Create command for module
+ *
+ * Macro creates object of struct shell_cmd and puts it in link table
+ * for module
+ *
+ * @param mod_ - module name
+ * @param cmd_ - command name
+ * @param func_ - function to execute
+ * @param help_ - help structure for function
+ */
+#define SHELL_MODULE_CMD(mod_, cmd_, func_, help_) \
+ SHELL_MODULE_CMD_WITH_NAME(mod_, cmd_, #cmd_, 0, func_, help_)
+
+/**
+ * Create command for module
+ *
+ * Macro creates object of struct shell_cmd and puts it in link table
+ * for module
+ *
+ * @param mod_ - module name
+ * @param cmd_ - command name
+ * @param func_ - function to execute
+ * @param help_ - help structure for function
+ */
+#define SHELL_MODULE_EXT_CMD(mod_, cmd_, func_, help_) \
+ SHELL_MODULE_CMD_WITH_NAME(mod_, cmd_, #cmd_, 1, func_, help_)
+
+/**
+ * @brief Register global shell command function
+ *
+ * Macro creates shell command that can be used when shell task is enabled
+ * This is equivalent of calling deprecated function shell_cmd_register.
+ *
+ * @name - cmd_name command name (it will be put in "" to make string
+ * @func - command function function of shell_cmd_ext_func_t
+ * @help pointer to shell_cmd_help
+ */
+#define MAKE_SHELL_CMD(cmd_name, func, help) \
+ SHELL_MODULE_CMD(compat, cmd_name, func, help)
+
+/**
+ * @brief Register global extended shell command function
+ *
+ * Macro creates shell command that can be used when shell task is enabled
+ * This is equivalent of calling deprecated function shell_cmd_register.
+ *
+ * @name - cmd_name command name (it will be put in "" to make string
+ * @func - command function function of shell_cmd_ext_func_t
+ * @help pointer to shell_cmd_help
+ */
+#define MAKE_SHELL_EXT_CMD(cmd_name, func, help) \
+ SHELL_MODULE_EXT_CMD(compat, cmd_name, func, help)
+
#if MYNEWT_VAL(SHELL_CMD_HELP)
#define SHELL_HELP_(help_) (help_)
#else
diff --git a/sys/shell/pkg.yml b/sys/shell/pkg.yml
index a0c158d87..9d8e7757d 100644
--- a/sys/shell/pkg.yml
+++ b/sys/shell/pkg.yml
@@ -39,5 +39,11 @@ pkg.deps.SHELL_BRIDGE:
pkg.req_apis:
- console
+pkg.whole_archive: true
+
+pkg.link_tables:
+ - shell_modules
+ - compat_commands
+
pkg.init:
shell_init: 'MYNEWT_VAL(SHELL_SYSINIT_STAGE)'
diff --git a/sys/shell/src/shell.c b/sys/shell/src/shell.c
index f14e423ae..8de736c35 100644
--- a/sys/shell/src/shell.c
+++ b/sys/shell/src/shell.c
@@ -27,14 +27,82 @@
#include "modlog/modlog.h"
#include "shell/shell.h"
#include "shell_priv.h"
+#include "os/link_tables.h"
#define SHELL_PROMPT "shell"
-static struct shell_module shell_modules[MYNEWT_VAL(SHELL_MAX_MODULES)];
+static size_t
+shell_mod_std_count(shell_mod_t mod)
+{
+ const struct shell_mod_std *std_mod = (const struct shell_mod_std *)mod;
+ return std_mod->commands_end - std_mod->commands;
+}
+
+static shell_cmd_t
+shell_mod_std_get(shell_mod_t mod, size_t ix)
+{
+ const struct shell_mod_std *std_mod = (const struct shell_mod_std *)mod;
+ size_t limit = std_mod->commands_end - std_mod->commands;
+ return ix < limit ? &std_mod->commands[ix] : NULL;
+}
+
+const struct shell_mod_ops shell_mod_std_ops = {
+ .count = shell_mod_std_count,
+ .get = shell_mod_std_get,
+};
+
+static struct shell_mod_std registered_shell_modules[MYNEWT_VAL(SHELL_MAX_MODULES)];
+
static size_t num_of_shell_entities;
+#if MYNEWT_VAL(SHELL_COMPAT)
+#define SHELL_COMPAT_MODULE_NAME "compat"
+static struct shell_cmd registered_compat_commands[MYNEWT_VAL(SHELL_MAX_COMPAT_COMMANDS)];
+static size_t num_compat_commands;
+
+static size_t
+shell_mod_compat_count(shell_mod_t mod)
+{
+ return shell_mod_std_count(mod) + num_of_shell_entities;
+}
+
+static shell_cmd_t
+shell_mod_compat_get(shell_mod_t mod, size_t ix)
+{
+ size_t linked_commands = shell_mod_std_count(mod);
+
+ if (ix < linked_commands) {
+ return shell_mod_std_get(mod, ix);
+ } else if (MYNEWT_VAL(SHELL_MAX_MODULES) > 0) {
+ ix -= linked_commands;
+ if (ix < num_compat_commands) {
+ return ®istered_compat_commands[ix];
+ }
+ }
+
+ return NULL;
+}
+
+const shell_mod_ops_t shell_mod_compat_ops = {
+ .count = shell_mod_compat_count,
+ .get = shell_mod_compat_get,
+};
+
+LINK_TABLE(struct shell_cmd, compat_commands)
+const struct shell_mod_std shell_mod_compat = {
+ .mod = {
+ .name = "compat",
+ .ops = &shell_mod_compat_ops,
+ },
+ .commands = LINK_TABLE_START(compat_commands),
+ .commands_end = LINK_TABLE_END(compat_commands),
+};
+/* This pointer goes to link table, it's the pointer to actual shell_mod_std */
+LINK_TABLE_ELEMENT_REF(shell_modules, compat, shell_mod_compat.mod)
+
static const char *prompt;
-static int default_module = -1;
+/* Set default module */
+static const struct shell_mod *default_module = &shell_mod_compat.mod;
static struct shell_cmd app_cmd;
static shell_prompt_function_t app_prompt_handler;
@@ -65,8 +133,8 @@ get_prompt(void)
}
}
- if (default_module != -1) {
- return shell_modules[default_module].name;
+ if (default_module) {
+ return default_module->name;
}
return prompt;
@@ -134,35 +202,56 @@ line2argv(char *str, char *argv[], size_t size, struct streamer *streamer)
return argc;
}
-static int
+static shell_mod_t
+shell_module_get(size_t ix)
+{
+ size_t build_time_module_count = shell_modules_size();
+
+ if (ix < build_time_module_count) {
+ return shell_modules[ix];
+ } else if (MYNEWT_VAL_SHELL_MAX_MODULES > 0) {
+ ix -= build_time_module_count;
+ if (ix < num_of_shell_entities) {
+ return (shell_mod_t)®istered_shell_modules[ix];
+ }
+ }
+ return NULL;
+}
+
+static bool
+module_str_matches(shell_mod_t mod, const char *str, int len)
+{
+ if (len < 0) {
+ return strcmp(str, mod->name) == 0;
+ } else {
+ return strncmp(str, mod->name, len) == 0;
+ }
+}
+
+const struct shell_mod *
get_destination_module(const char *module_str, int len)
{
- int i;
+ shell_mod_t mod;
- for (i = 0; i < num_of_shell_entities; i++) {
- if (len < 0) {
- if (!strcmp(module_str, shell_modules[i].name)) {
- return i;
- }
- } else {
- if (!strncmp(module_str, shell_modules[i].name, len)) {
- return i;
- }
+ for (size_t i = 0; NULL != (mod = shell_module_get(i)); ++i) {
+ if (module_str_matches(mod, module_str, len)) {
+ return mod;
}
}
- return -1;
+ return NULL;
}
/* For a specific command: argv[0] = module name, argv[1] = command name
* If a default module was selected: argv[0] = command name
*/
static const char *
-get_command_and_module(char *argv[], int *module, struct streamer *streamer)
+get_command_and_module(char *argv[], const struct shell_mod **module,
+ struct streamer *streamer)
{
- int def_module = default_module;
+ const struct shell_mod *def_module = default_module;
const char *first_arg = argv[0];
- *module = -1;
+ *module = NULL;
if (!argv[0]) {
streamer_printf(streamer, "Unrecognized command\n");
@@ -171,17 +260,17 @@ get_command_and_module(char *argv[], int *module, struct streamer *streamer)
if (first_arg[0] == '/') {
first_arg++;
- def_module = -1;
+ def_module = NULL;
}
- if (def_module == -1) {
+ if (def_module == NULL) {
if (!argv[1] || argv[1][0] == '\0') {
streamer_printf(streamer, "Unrecognized command: %s\n", argv[0]);
return NULL;
}
*module = get_destination_module(first_arg, -1);
- if (*module == -1) {
+ if (*module == NULL) {
streamer_printf(streamer, "Illegal module %s\n", argv[0]);
return NULL;
}
@@ -194,11 +283,8 @@ get_command_and_module(char *argv[], int *module, struct streamer *streamer)
}
static void
-print_command_params(const int module, const int command,
- struct streamer *streamer)
+print_command_params(const struct shell_cmd *shell_cmd, struct streamer *streamer)
{
- const struct shell_module *shell_module = &shell_modules[module];
- const struct shell_cmd *shell_cmd = &shell_module->commands[command];
int i;
if (!(shell_cmd->help && shell_cmd->help->params)) {
@@ -216,19 +302,16 @@ static int
show_cmd_help(char *argv[], struct streamer *streamer)
{
const char *command = NULL;
- int module = -1;
- const struct shell_module *shell_module = NULL;
+ const struct shell_mod *shell_module = NULL;
const struct shell_cmd *cmd;
int i;
- command = get_command_and_module(argv, &module, streamer);
- if ((module == -1) || (command == NULL)) {
+ command = get_command_and_module(argv, &shell_module, streamer);
+ if ((shell_module == NULL) || (command == NULL)) {
return 0;
}
- shell_module = &shell_modules[module];
- for (i = 0; shell_module->commands[i].sc_cmd; i++) {
- cmd = &shell_module->commands[i];
+ for (i = 0; (cmd = shell_mod_command(shell_module, i)) != NULL; ++i) {
if (!strcmp(command, cmd->sc_cmd)) {
if (!cmd->help || (!cmd->help->summary &&
@@ -250,7 +333,7 @@ show_cmd_help(char *argv[], struct streamer *streamer)
if (cmd->help->params) {
streamer_printf(streamer, "Parameters:\n");
- print_command_params(module, i, streamer);
+ print_command_params(cmd, streamer);
}
return 0;
@@ -264,28 +347,21 @@ show_cmd_help(char *argv[], struct streamer *streamer)
static void
print_modules(struct streamer *streamer)
{
- int module;
-
- for (module = 0; module < num_of_shell_entities; module++) {
- streamer_printf(streamer, "%s\n", shell_modules[module].name);
+ LINK_TABLE_FOREACH(mod, shell_modules) {
+ streamer_printf(streamer, "%s\n", (*mod)->name);
}
}
static void
-print_module_commands(const int module, struct streamer *streamer)
+print_module_commands(const struct shell_mod *shell_module, struct streamer *streamer)
{
- const struct shell_module *shell_module = &shell_modules[module];
+ const struct shell_cmd *cmd;
int i;
- streamer_printf(streamer, "help\n");
-
- for (i = 0; shell_module->commands[i].sc_cmd; i++) {
- streamer_printf(streamer, "%-30s", shell_module->commands[i].sc_cmd);
- if (shell_module->commands[i].help &&
- shell_module->commands[i].help->summary) {
-
- streamer_printf(streamer, "%s",
- shell_module->commands[i].help->summary);
+ for (i = 0; NULL != (cmd = shell_mod_command(shell_module, i)); ++i) {
+ streamer_printf(streamer, "%-30s", cmd->sc_cmd);
+ if (cmd->help && cmd->help->summary) {
+ streamer_printf(streamer, "%s", cmd->help->summary);
}
streamer_printf(streamer, "\n");
}
@@ -295,18 +371,18 @@ static int
show_help(const struct shell_cmd *cmd, int argc, char *argv[],
struct streamer *streamer)
{
- int module;
+ const struct shell_mod *module;
/* help per command */
- if ((argc > 2) || ((default_module != -1) && (argc == 2))) {
+ if ((argc > 2) || ((default_module != NULL) && (argc == 2))) {
return show_cmd_help(&argv[1], streamer);
}
/* help per module */
- if ((argc == 2) || ((default_module != -1) && (argc == 1))) {
- if (default_module == -1) {
+ if ((argc == 2) || ((default_module != NULL) && (argc == 1))) {
+ if (default_module == NULL) {
module = get_destination_module(argv[1], -1);
- if (module == -1) {
+ if (module == NULL) {
streamer_printf(streamer, "Illegal module %s\n", argv[1]);
return 0;
}
@@ -325,17 +401,16 @@ show_help(const struct shell_cmd *cmd, int argc, char *argv[],
return 0;
}
-static const struct shell_cmd shell_cmd_help =
- SHELL_CMD_EXT("help", show_help, NULL);
+MAKE_SHELL_CMD(help, show_help, NULL)
static int
set_default_module(const char *name)
{
- int module;
+ const struct shell_mod *module;
module = get_destination_module(name, -1);
- if (module == -1) {
+ if (module == NULL) {
return -1;
}
@@ -349,7 +424,7 @@ select_module(const struct shell_cmd *cmd, int argc, char *argv[],
struct streamer *streamer)
{
if (argc == 1) {
- default_module = -1;
+ default_module = NULL;
} else {
set_default_module(argv[1]);
}
@@ -357,17 +432,16 @@ select_module(const struct shell_cmd *cmd, int argc, char *argv[],
return 0;
}
-static const struct shell_cmd shell_cmd_select_module =
- SHELL_CMD_EXT("select", select_module, NULL);
+MAKE_SHELL_CMD(select, select_module, NULL)
static const struct shell_cmd *
shell_find_cmd(int argc, char *argv[], struct streamer *streamer)
{
const char *first_string = argv[0];
- int module = -1;
- int def_module = default_module;
- const struct shell_module *shell_module;
+ const struct shell_mod *def_module = default_module;
+ const struct shell_mod *shell_module;
const char *command;
+ const struct shell_cmd *cmd;
int i;
if (!first_string || first_string[0] == '\0') {
@@ -377,7 +451,7 @@ shell_find_cmd(int argc, char *argv[], struct streamer *streamer)
if (first_string[0] == '/') {
first_string++;
- def_module = -1;
+ def_module = NULL;
}
if (!strcmp(first_string, "help")) {
@@ -385,23 +459,22 @@ shell_find_cmd(int argc, char *argv[], struct streamer *streamer)
}
if (!strcmp(first_string, "select")) {
- return &shell_cmd_select_module;
+ return &shell_cmd_select;
}
- if ((argc == 1) && (def_module == -1)) {
+ if ((argc == 1) && (def_module == NULL)) {
streamer_printf(streamer, "Missing parameter\n");
return NULL;
}
- command = get_command_and_module(argv, &module, streamer);
- if ((module == -1) || (command == NULL)) {
+ command = get_command_and_module(argv, &shell_module, streamer);
+ if ((shell_module == NULL) || (command == NULL)) {
return NULL;
}
- shell_module = &shell_modules[module];
- for (i = 0; shell_module->commands[i].sc_cmd; i++) {
- if (!strcmp(command, shell_module->commands[i].sc_cmd)) {
- return &shell_module->commands[i];
+ for (i = 0; NULL != (cmd = shell_mod_command(shell_module, i)); ++i) {
+ if (!strcmp(command, cmd->sc_cmd)) {
+ return cmd;
}
}
@@ -414,7 +487,7 @@ shell_exec(int argc, char **argv, struct streamer *streamer)
const struct shell_cmd *cmd;
size_t argc_offset = 0;
int rc;
- int def_module = default_module;
+ const struct shell_mod *def_module = default_module;
cmd = shell_find_cmd(argc, argv, streamer);
if (!cmd) {
@@ -430,13 +503,12 @@ shell_exec(int argc, char **argv, struct streamer *streamer)
}
if (argv[0][0] == '/') {
- def_module = -1;
+ def_module = NULL;
}
/* Allow invoking a cmd with module name as a prefix; a command should
* not know how it was invoked (with or without prefix)
*/
- if (def_module == -1 && cmd != &shell_cmd_select_module &&
- cmd != &shell_cmd_help) {
+ if (def_module == NULL && cmd != &shell_cmd_select && cmd != &shell_cmd_help) {
argc_offset = 1;
}
@@ -524,24 +596,23 @@ shell(struct os_event *ev)
}
#if MYNEWT_VAL(SHELL_COMPLETION)
-static int
-get_command_from_module(const char *command, int len, int module)
+const struct shell_cmd *
+get_command_from_module(const char *command, int len, const struct shell_mod *shell_module)
{
int i;
- const struct shell_module *shell_module;
+ const struct shell_cmd *cmd;
- shell_module = &shell_modules[module];
- for (i = 0; shell_module->commands[i].sc_cmd; i++) {
+ for (i = 0; NULL != (cmd = shell_mod_command(shell_module, i)); ++i) {
- if (strlen(shell_module->commands[i].sc_cmd) != len) {
+ if (strlen(cmd->sc_cmd) != len) {
continue;
}
- if (!strncmp(command, shell_module->commands[i].sc_cmd, len)) {
- return i;
+ if (strncmp(command, cmd->sc_cmd, len) == 0) {
+ return cmd;
}
}
- return -1;
+ return NULL;
}
static int
@@ -583,15 +654,11 @@ get_last_token(char **cur)
}
static void
-complete_param(char *line, const char *param_prefix,
- int param_len, int module_idx, int command_idx,
- console_append_char_cb append_char)
+complete_param(char *line, const char *param_prefix, int param_len,
+ const struct shell_cmd *command, console_append_char_cb append_char)
{
const char *first_match = NULL;
int i, j, common_chars = -1;
- const struct shell_cmd *command;
-
- command = &shell_modules[module_idx].commands[command_idx];
if (!(command->help && command->help->params)) {
return;
@@ -649,26 +716,25 @@ complete_param(char *line, const char *param_prefix,
}
static void
-complete_command(char *line, char *command_prefix,
- int command_len, int module_idx,
- console_append_char_cb append_char)
+complete_command(char *line, char *command_prefix, int command_len,
+ const struct shell_mod *module, console_append_char_cb append_char)
{
int first_match = -1;
int match_count = 0;
int i, j, common_chars = -1;
- const struct shell_cmd *commands;
-
- commands = shell_modules[module_idx].commands;
+ const struct shell_cmd *match = NULL;
+ const struct shell_cmd *command;
- for (i = 0; commands[i].sc_cmd; i++) {
- if (0 != strncmp(command_prefix, commands[i].sc_cmd, command_len)) {
+ for (i = 0; NULL != (command = shell_mod_command(module, i)); ++i) {
+ if (0 != strncmp(command_prefix, command->sc_cmd, command_len)) {
continue;
}
match_count++;
if (match_count == 1) {
first_match = i;
- common_chars = strlen(commands[i].sc_cmd);
+ match = command;
+ common_chars = strlen(command->sc_cmd);
continue;
}
@@ -681,7 +747,7 @@ complete_command(char *line, char *command_prefix,
}
/* Check how many additional chars are same as first command's */
for (j = command_len; j < common_chars; j++) {
- if (commands[first_match].sc_cmd[j] != commands[i].sc_cmd[j]) {
+ if (match->sc_cmd[j] != command->sc_cmd[j]) {
break;
}
}
@@ -696,7 +762,7 @@ complete_command(char *line, char *command_prefix,
if (common_chars > command_len) {
/* complete common part */
for (i = command_len; i < common_chars; i++) {
- if (!append_char(line, (uint8_t)commands[first_match].sc_cmd[i])) {
+ if (!append_char(line, (uint8_t)match->sc_cmd[i])) {
return;
}
}
@@ -716,10 +782,10 @@ complete_command(char *line, char *command_prefix,
* list all possible matches.
*/
console_out('\n');
- console_printf("%s\n", commands[first_match].sc_cmd);
- for (i = first_match + 1; commands[i].sc_cmd; i++) {
- if (0 == strncmp(command_prefix, commands[i].sc_cmd, command_len)) {
- console_printf("%s\n", commands[i].sc_cmd);
+ console_printf("%s\n", match->sc_cmd);
+ for (i = first_match + 1; NULL != (command = shell_mod_command(module, i)); ++i) {
+ if (0 == strncmp(command_prefix, command->sc_cmd, command_len)) {
+ console_printf("%s\n", command->sc_cmd);
}
}
/* restore prompt */
@@ -733,26 +799,25 @@ complete_module(char *line, char *module_prefix,
int i, j;
const char *first_match = NULL;
int common_chars = -1, space = 0;
+ shell_mod_t mod;
if (!module_len) {
console_out('\n');
- for (i = 0; i < num_of_shell_entities; i++) {
- console_printf("%s\n", shell_modules[i].name);
+ for (i = 0; NULL != (mod = shell_module_get(i)); ++i) {
+ console_printf("%s\n", mod->name);
}
print_prompt(line);
return;
}
- for (i = 0; i < num_of_shell_entities; i++) {
+ for (i = 0; NULL != (mod = shell_module_get(i)); ++i) {
- if (strncmp(module_prefix,
- shell_modules[i].name,
- module_len)) {
+ if (strncmp(module_prefix, mod->name, module_len)) {
continue;
}
if (!first_match) {
- first_match = shell_modules[i].name;
+ first_match = mod->name;
continue;
}
@@ -765,14 +830,14 @@ complete_module(char *line, char *module_prefix,
/* cut common part of matching names */
for (j = 0; j < common_chars; j++) {
- if (first_match[j] != shell_modules[i].name[j]) {
+ if (first_match[j] != mod->name[j]) {
break;
}
}
common_chars = j;
- console_printf("%s\n", shell_modules[i].name);
+ console_printf("%s\n", mod->name);
}
/* no match, do nothing */
@@ -826,9 +891,10 @@ completion(char *line, console_append_char_cb append_char)
{
char *cur;
int tok_len;
- int module, command;
+ const struct shell_cmd *command;
int null_terminated = 0;
- int def_module = default_module;
+ const struct shell_mod *def_module = default_module;
+ const struct shell_mod *module;
/*
* line to completion is not ended by '\0' as the line that gets from
@@ -841,7 +907,7 @@ completion(char *line, console_append_char_cb append_char)
cur = line;
tok_len = get_token(&cur, &null_terminated);
if (tok_len > 0 && cur[0] == '/') {
- def_module = -1;
+ def_module = NULL;
tok_len--;
cur++;
}
@@ -849,7 +915,7 @@ completion(char *line, console_append_char_cb append_char)
/* empty token - print options */
if (tok_len == 0) {
console_out('\n');
- if (def_module == -1) {
+ if (def_module == NULL) {
print_modules(streamer_console_get());
} else {
print_module_commands(def_module, streamer_console_get());
@@ -860,7 +926,7 @@ completion(char *line, console_append_char_cb append_char)
/* token can be completed */
if (null_terminated) {
- if (def_module == -1) {
+ if (def_module == NULL) {
complete_module(line, cur, tok_len, append_char);
return;
}
@@ -874,12 +940,12 @@ completion(char *line, console_append_char_cb append_char)
return;
}
- if (def_module != -1) {
+ if (def_module != NULL) {
module = def_module;
} else {
module = get_destination_module(cur, tok_len);
- if (module == -1) {
+ if (module == NULL) {
return;
}
@@ -901,7 +967,7 @@ completion(char *line, console_append_char_cb append_char)
}
command = get_command_from_module(cur, tok_len, module);
- if (command == -1) {
+ if (command == NULL) {
return;
}
@@ -909,12 +975,11 @@ completion(char *line, console_append_char_cb append_char)
tok_len = get_last_token(&cur);
if (tok_len == 0) {
console_out('\n');
- print_command_params(module, command, streamer_console_get());
+ print_command_params(command, streamer_console_get());
print_prompt(line);
return;
}
- complete_param(line, cur, tok_len,
- module, command, append_char);
+ complete_param(line, cur, tok_len, command, append_char);
return;
}
#endif /* MYNEWT_VAL(SHELL_COMPLETION) */
@@ -960,46 +1025,32 @@ shell_register(const char *module_name, const struct shell_cmd *commands)
if (num_of_shell_entities >= MYNEWT_VAL(SHELL_MAX_MODULES)) {
DFLT_LOG_ERROR("Max number of modules reached\n");
assert(0);
+ } else if (MYNEWT_VAL(SHELL_MAX_MODULES) > 0) {
+ registered_shell_modules[num_of_shell_entities].mod.name = module_name;
+ registered_shell_modules[num_of_shell_entities].mod.ops = &shell_mod_std_ops;
+ registered_shell_modules[num_of_shell_entities].commands = commands;
+ /* commands_end will point to empty command */
+ while (commands->sc_cmd) {
+ ++commands;
+ }
+ registered_shell_modules[num_of_shell_entities].commands_end = commands;
+ ++num_of_shell_entities;
}
- shell_modules[num_of_shell_entities].name = module_name;
- shell_modules[num_of_shell_entities].commands = commands;
- ++num_of_shell_entities;
-
return 0;
}
-#if MYNEWT_VAL(SHELL_COMPAT)
-#define SHELL_COMPAT_MODULE_NAME "compat"
-static struct shell_cmd compat_commands[MYNEWT_VAL(SHELL_MAX_COMPAT_COMMANDS) + 1];
-static int num_compat_commands;
-static int module_registered;
-
int
shell_cmd_register(const struct shell_cmd *sc)
{
- int rc;
-
if (num_compat_commands >= MYNEWT_VAL(SHELL_MAX_COMPAT_COMMANDS)) {
DFLT_LOG_ERROR(
"Max number of compat commands reached\n");
assert(0);
+ } else if (MYNEWT_VAL(SHELL_MAX_COMPAT_COMMANDS) > 0) {
+ registered_compat_commands[num_compat_commands] = *sc;
+ ++num_compat_commands;
}
-
- if (!module_registered) {
- shell_register(SHELL_COMPAT_MODULE_NAME, compat_commands);
- module_registered = 1;
-
- rc = set_default_module(SHELL_COMPAT_MODULE_NAME);
- if (rc != 0) {
- DFLT_LOG_ERROR(
- "Illegal module %s, default is not changed\n",
- SHELL_COMPAT_MODULE_NAME);
- }
- }
-
- compat_commands[num_compat_commands] = *sc;
- ++num_compat_commands;
return 0;
}
#endif
@@ -1027,12 +1078,6 @@ shell_init(void)
console_set_completion_cb(completion);
#endif
-#if MYNEWT_VAL(SHELL_OS_MODULE)
- shell_os_register();
-#endif
-#if MYNEWT_VAL(SHELL_PROMPT_MODULE)
- shell_prompt_register();
-#endif
#if MYNEWT_VAL(SHELL_BRIDGE)
shell_bridge_init();
#endif
(mynewt-core) 01/04: util: Fix link section attribute
Posted by je...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
jerzy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit eda1633709bf896b83d9a4220fbd82090d27bd41
Author: Jerzy Kasenberg <je...@codecoup.pl>
AuthorDate: Fri Jun 27 20:50:11 2025 +0200
util: Fix link section attribute
LINK_TABLE_ELEMENT_SECTION macro that defines attribute
for symbol did not have 'used' part that is needed
for link table to collect unreferenced symbols
Signed-off-by: Jerzy Kasenberg <je...@apache.org>
---
kernel/os/include/os/link_tables.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/os/include/os/link_tables.h b/kernel/os/include/os/link_tables.h
index 13c329611..2a738086b 100644
--- a/kernel/os/include/os/link_tables.h
+++ b/kernel/os/include/os/link_tables.h
@@ -95,7 +95,7 @@
__attribute__((section("." #table_name), used))
/* Macro to create attribute for table with name that may affect order of elements */
#define LINK_TABLE_ELEMENT_SECTION(table_name, elem) \
- __attribute__((section("." #table_name "." #elem)))
+ __attribute__((section("." #table_name "." #elem), used))
/* Macro to create element that goes to link table.
* It could be used like this:
* LINK_TABLE_ELEMENT(example1_table, foo5) = {
@@ -126,7 +126,7 @@
*/
#define LINK_TABLE_ELEMENT_REF(table_name, elem, var) \
LINK_TABLE_ELEMENT_TYPE(table_name) \
- const elem##_ptr LINK_TABLE_ELEMENT_SECTION(table_name, elem) = &var
+ const elem##_ptr LINK_TABLE_ELEMENT_SECTION(table_name, elem) = &var;
#define LINK_TABLE(element_type, table_name) \
typedef element_type table_name##_element_t; \
(mynewt-core) 04/04: sys/shell: Register prompt module statically
Posted by je...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
jerzy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit f0c90b9bb6365bcd0f715c2d90f9b7b6d9d5a253
Author: Jerzy Kasenberg <je...@codecoup.pl>
AuthorDate: Sat May 31 00:54:16 2025 +0200
sys/shell: Register prompt module statically
Module prompt is not linked statically.
No need for runtime registering.
Signed-off-by: Jerzy Kasenberg <je...@apache.org>
---
sys/shell/src/shell_priv.h | 2 --
sys/shell/src/shell_prompt.c | 14 +++++---------
2 files changed, 5 insertions(+), 11 deletions(-)
diff --git a/sys/shell/src/shell_priv.h b/sys/shell/src/shell_priv.h
index 6c85d1ac7..3603d2b01 100644
--- a/sys/shell/src/shell_priv.h
+++ b/sys/shell/src/shell_priv.h
@@ -49,8 +49,6 @@ void shell_nlip_init(void);
void shell_nlip_clear_pkt(void);
#endif
-void shell_prompt_register(void);
-
#if MYNEWT_VAL(SHELL_BRIDGE)
void shell_bridge_streamer_new(struct shell_bridge_streamer *sbs,
struct CborEncoder *str_encoder);
diff --git a/sys/shell/src/shell_prompt.c b/sys/shell/src/shell_prompt.c
index 00a1c1801..448d579bd 100644
--- a/sys/shell/src/shell_prompt.c
+++ b/sys/shell/src/shell_prompt.c
@@ -17,10 +17,10 @@
* under the License.
*/
-#include <stdio.h>
-#include <string.h>
-
#include "os/mynewt.h"
+
+#if MYNEWT_VAL(SHELL_PROMPT_MODULE)
+
#include "console/console.h"
#include "console/ticks.h"
@@ -73,12 +73,8 @@ static const struct shell_cmd prompt_commands[] = {
.help = &ticks_help,
#endif
},
- { 0 },
};
+SHELL_MODULE_WITH_TABLE(prompt, prompt_commands)
-void
-shell_prompt_register(void)
-{
- shell_register(SHELL_PROMPT, prompt_commands);
-}
+#endif