aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTarek El-Sherbiny <tarek.el-sherbiny@arm.com>2020-01-31 14:19:47 +0000
committerjimqui01 <54316584+jimqui01@users.noreply.github.com>2020-03-23 14:22:21 +0000
commitaa5531fdf98cfede4ccac436959c0a235ad661ed (patch)
tree6cc3b965915115bc3bb568949d1ce86fcf00db52
parent1789c05abe0d205b1104062d0c7d2ae95fc24297 (diff)
dbg: Convert the cli commands array to a linked list
This patch gives the ability to add new cli commands at run time. Any new command can be added by calling the cli_dbg_register_command function after filling the command struct members accordingly. The new command will be added to the commands linked list. At startup, only the common cli commands will be available to the user. Any additional command must be register to be available in the cli. Change-Id: Ib81a70f4f7737050d0ea02692b0ef34773e25c8b Signed-off-by: Tarek El-Sherbiny <tarek.el-sherbiny@arm.com>
-rw-r--r--debugger/include/cli.h10
-rw-r--r--debugger/src/cli/cli.c104
2 files changed, 88 insertions, 26 deletions
diff --git a/debugger/include/cli.h b/debugger/include/cli.h
index 74e89fed..f169bbcd 100644
--- a/debugger/include/cli.h
+++ b/debugger/include/cli.h
@@ -272,4 +272,14 @@ uint32_t cli_getline(
*/
int32_t cli_strncmp(const char *s1, const char *s2, uint32_t limit);
+/*!
+ * \brief Register a new CLI command at run time
+ *
+ * \param new_cmd The new command to register.
+ *
+ * \retval CLI_SUCCESS Operation succeeded.
+ * \retval CLI_ERR_MEM Not enough memory.
+ */
+int cli_command_register(cli_command_st new_cmd);
+
#endif /* _CLI_H_ */
diff --git a/debugger/src/cli/cli.c b/debugger/src/cli/cli.c
index b3610195..393a2c25 100644
--- a/debugger/src/cli/cli.c
+++ b/debugger/src/cli/cli.c
@@ -5,10 +5,13 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <cli_platform.h>
+#include <fwk_list.h>
+#include <fwk_mm.h>
+
#include <cli.h>
#include <cli_config.h>
#include <cli_fifo.h>
+#include <cli_platform.h>
#include <stdarg.h>
#include <stdbool.h>
@@ -57,6 +60,45 @@ size_t maxlen;
return n;
}
+struct command_ctx {
+ cli_command_st cmd;
+ struct fwk_slist_node list_node;
+};
+
+/* A linked list used for extend the existing command at run time */
+static struct fwk_slist cli_commands_list;
+
+/* This array holds the common command available for all platforms */
+extern cli_command_st cli_commands[];
+
+int cli_command_register(cli_command_st new_cmd)
+{
+ struct command_ctx *c = fwk_mm_calloc(1, sizeof(struct command_ctx));
+ if (c == NULL)
+ return FWK_E_NOMEM;
+
+ c->cmd = new_cmd;
+ fwk_list_push_tail(&cli_commands_list, &c->list_node);
+
+ return FWK_SUCCESS;
+}
+
+int cli_command_init(void)
+{
+ uint32_t index;
+ int status;
+
+ fwk_list_init(&cli_commands_list);
+
+ /* Add the common commands to the commands linked list */
+ for (index = 0; cli_commands[index].command != 0; index++) {
+ status = cli_command_register(cli_commands[index]);
+ if (status != FWK_SUCCESS)
+ return status;
+ }
+ return FWK_SUCCESS;
+}
+
/*
* TBA: Replace calls to strncmp with calls to cli_strncmp.
* For some reason calls to strncmp crash for seemingly no reason on the
@@ -206,13 +248,11 @@ static uint32_t cli_split(
* char **args
* Pointer to an array of strings containing the arguments received from
* the terminal.
- * cli_command_st *cmd
- * Pointer to the array containing command structures.
* Return
* uint32_t: FWK_SUCCESS if it works, something else if it
* doesn't.
*/
-static uint32_t cli_command_dispatch(char **args, cli_command_st *cmd);
+static uint32_t cli_command_dispatch(char **args);
/*
* cli_debug_output
@@ -313,6 +353,10 @@ uint32_t cli_init(void)
if (status != FWK_SUCCESS)
return status;
+ status = cli_command_init();
+ if (status != FWK_SUCCESS)
+ return status;
+
/* Setting state to CLI_READY. */
cli_state = CLI_READY;
@@ -687,7 +731,7 @@ static void cli_main(void const *argument)
continue;
/* Dispatching command for processing. */
- status = cli_command_dispatch(cli_args, cli_commands);
+ status = cli_command_dispatch(cli_args);
if (status != FWK_SUCCESS)
cli_error_handler(status);
}
@@ -902,7 +946,7 @@ static uint32_t cli_get_command(
/* If we received a Ctrl+d press, exit cli. */
if (c == '\x04') {
*exit = true;
- return CLI_SUCCESS;
+ return FWK_SUCCESS;
}
/* Ignoring non-printing characters except for a few we care about. */
@@ -1142,24 +1186,28 @@ static uint32_t cli_split(
return FWK_SUCCESS;
}
-static uint32_t cli_command_dispatch(char **args, cli_command_st *cmd)
+static uint32_t cli_command_dispatch(char **args)
{
- uint32_t cmd_index = 0;
uint32_t index = 0;
uint32_t num_args = 0;
uint32_t status = FWK_SUCCESS;
+ struct fwk_slist *node = NULL;
+ struct command_ctx *cc = NULL;
+ bool command_found;
- /* Checking pointers. */
- if (args == 0 || cmd == 0)
+ /* Checking pointer. */
+ if (args == 0)
return FWK_E_PARAM;
/* Special case command: help. */
if (cli_strncmp(args[0], "help", 5) == 0) {
- for (index = 0; cli_commands[index].command != 0; index++) {
- cli_printf(NONE, "%s\n", cli_commands[index].command);
- cli_print(cli_commands[index].help);
- cli_print("\n");
+ FWK_LIST_FOR_EACH(&cli_commands_list, node,
+ struct command_ctx, list_node, cc) {
+ cli_printf(NONE, "%s\n", cc->cmd.command);
+ cli_print(cc->cmd.help);
+ cli_print("\n");
}
+
cli_printf(NONE, "help\n");
cli_print(" Displays this information.\n");
cli_printf(NONE, "Ctrl+C\n");
@@ -1184,25 +1232,29 @@ static uint32_t cli_command_dispatch(char **args, cli_command_st *cmd)
/* Searching for command handler. */
/* Using strcmp here because each entry in args is guaranteed to be null
* terminated by cli_split. */
- for (cmd_index = 0; cmd[cmd_index].command != 0 &&
- strcmp(args[0], cmd[cmd_index].command) != 0;
- cmd_index++)
- ;
- if (cmd[cmd_index].command == 0)
+ command_found = false;
+ FWK_LIST_FOR_EACH(&cli_commands_list, node,
+ struct command_ctx, list_node, cc) {
+ if (strcmp(args[0], cc->cmd.command) == 0) {
+ command_found = true;
+ break;
+ }
+ }
+ if (!command_found)
return FWK_E_SUPPORT;
-
/* Handler found, if -h or --help is given just print it's help string and
* return. */
- if (cmd[cmd_index].ignore_help_flag == false) {
+ if (cc->cmd.ignore_help_flag == false) {
for (index = 1;
(args[index] != 0) && (cli_strncmp(args[index], "-h", 3) != 0) &&
(cli_strncmp(args[index], "--help", 7) != 0);
index++)
;
- if ((args[index] != 0 || cmd[cmd_index].handler == 0) &&
- cmd[cmd_index].help != 0) {
- status = cli_print(cmd[cmd_index].help);
+
+ if ((args[index] != 0 || cc->cmd.handler == 0) &&
+ cc->cmd.help != 0) {
+ status = cli_print(cc->cmd.help);
if (status != FWK_SUCCESS)
return status;
@@ -1220,8 +1272,8 @@ static uint32_t cli_command_dispatch(char **args, cli_command_st *cmd)
/* Calling command handler. */
/* args is incremented so the command just gets the arguments and not the
* name of itself. */
- if (cmd[cmd_index].handler != 0)
- return cmd[cmd_index].handler(num_args, args);
+ if (cc->cmd.handler != 0)
+ return cc->cmd.handler(num_args, args);
else
return FWK_E_PARAM;
}