From ee4540c46c2a1c9bead87862dd7bcaee9a7efa20 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 21 Nov 2023 17:22:40 +0100 Subject: [PATCH] llext: remove llext list scanning from shell.c The llext list should be internal to llext.c, remove its scanning from shell.c, export a function for that instead. Signed-off-by: Guennadi Liakhovetski --- include/zephyr/llext/llext.h | 13 ++++++++ subsys/llext/llext.c | 20 ++++++++++++ subsys/llext/shell.c | 60 +++++++++++++++++++++--------------- 3 files changed, 69 insertions(+), 24 deletions(-) diff --git a/include/zephyr/llext/llext.h b/include/zephyr/llext/llext.h index c097ec2b329..b3897bd5e05 100644 --- a/include/zephyr/llext/llext.h +++ b/include/zephyr/llext/llext.h @@ -91,6 +91,19 @@ sys_slist_t *llext_list(void); */ struct llext *llext_by_name(const char *name); +/** + * @brief Iterate overall registered llext instances + * + * Calls a provided callback function for each registered extension or until the + * callback function returns a non-0 value. + * + * @param[in] fn callback function + * @param[in] arg a private argument to be provided to the callback function + * @retval 0 if no extensions are registered + * @retval value returned by the most recent callback invocation + */ +int llext_iterate(int (*fn)(struct llext *ext, void *arg), void *arg); + /** * @brief llext loader parameters * diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index 15436bb43ab..3d711af957d 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -72,6 +72,26 @@ struct llext *llext_by_name(const char *name) return NULL; } +int llext_iterate(int (*fn)(struct llext *ext, void *arg), void *arg) +{ + sys_snode_t *node; + unsigned int i; + int ret = 0; + + for (node = sys_slist_peek_head(&_llext_list), i = 0; + node; + node = sys_slist_peek_next(node), i++) { + struct llext *ext = CONTAINER_OF(node, struct llext, _llext_list); + + ret = fn(ext, arg); + if (ret) { + break; + } + } + + return ret; +} + const void * const llext_find_sym(const struct llext_symtable *sym_table, const char *sym_name) { if (sym_table == NULL) { diff --git a/subsys/llext/shell.c b/subsys/llext/shell.c index 0e3448d6637..57f5b1d131b 100644 --- a/subsys/llext/shell.c +++ b/subsys/llext/shell.c @@ -52,45 +52,57 @@ static int cmd_llext_list_symbols(const struct shell *sh, size_t argc, char *arg return 0; } -static void llext_name_get(size_t idx, struct shell_static_entry *entry) +struct llext_shell_cmd { + unsigned int tgt; + unsigned int idx; + struct llext *ext; +}; + +static int llext_shell_name_cb(struct llext *ext, void *arg) { - sys_slist_t *ext_list = llext_list(); - sys_snode_t *node = sys_slist_peek_head(ext_list); + struct llext_shell_cmd *cmd = arg; - entry->syntax = NULL; - - for (int i = 0; i < idx; i++) { - node = sys_slist_peek_next(node); - - if (node == NULL) { - goto out; - } + if (cmd->tgt == cmd->idx) { + cmd->ext = ext; + return 1; } - struct llext *ext = CONTAINER_OF(node, struct llext, _llext_list); + cmd->idx++; - entry->syntax = ext->name; -out: - entry->syntax = NULL; + return 0; +} + +static void llext_name_get(size_t idx, struct shell_static_entry *entry) +{ + struct llext_shell_cmd cmd = {.tgt = idx}; + + llext_iterate(llext_shell_name_cb, &cmd); + + entry->syntax = cmd.ext ? cmd.ext->name : NULL; entry->help = NULL; entry->subcmd = NULL; - } SHELL_DYNAMIC_CMD_CREATE(msub_llext_name, llext_name_get); +struct llext_shell_list { + const struct shell *sh; +}; + +static int llext_shell_list_cb(struct llext *ext, void *arg) +{ + struct llext_shell_list *sl = arg; + + shell_print(sl->sh, "| %16s | %12d |", ext->name, ext->mem_size); + return 0; +} + static int cmd_llext_list(const struct shell *sh, size_t argc, char *argv[]) { - sys_snode_t *node; - struct llext *ext; + struct llext_shell_list sl = {.sh = sh}; shell_print(sh, "| Name | Size |"); - SYS_SLIST_FOR_EACH_NODE(llext_list(), node) { - ext = CONTAINER_OF(node, struct llext, _llext_list); - shell_print(sh, "| %16s | %12d |", ext->name, ext->mem_size); - } - - return 0; + return llext_iterate(llext_shell_list_cb, &sl); } static uint8_t llext_buf[CONFIG_LLEXT_SHELL_MAX_SIZE];