shell: support standalone commands
This will allow us to register commands directly without a need for a module. Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
parent
8d1931504a
commit
d7777d3bd5
3 changed files with 85 additions and 14 deletions
|
@ -102,7 +102,10 @@
|
||||||
#define SHELL_INIT_SECTIONS() \
|
#define SHELL_INIT_SECTIONS() \
|
||||||
__shell_module_start = .; \
|
__shell_module_start = .; \
|
||||||
KEEP(*(".shell_module_*")); \
|
KEEP(*(".shell_module_*")); \
|
||||||
__shell_module_end = .;
|
__shell_module_end = .; \
|
||||||
|
__shell_cmd_start = .; \
|
||||||
|
KEEP(*(".shell_cmd_*")); \
|
||||||
|
__shell_cmd_end = .; \
|
||||||
|
|
||||||
#ifdef CONFIG_APPLICATION_MEMORY
|
#ifdef CONFIG_APPLICATION_MEMORY
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,21 @@ struct shell_module {
|
||||||
* Shell array entries must be packed to calculate array size correctly.
|
* Shell array entries must be packed to calculate array size correctly.
|
||||||
* @param _prompt Optional prompt handler to be set when module is selected.
|
* @param _prompt Optional prompt handler to be set when module is selected.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def SHELL_REGISTER_COMMAND
|
||||||
|
*
|
||||||
|
* @brief Create a standalone command and set it up for boot time
|
||||||
|
* initialization.
|
||||||
|
*
|
||||||
|
* @details This macro define a shell_cmd object hat is automatically
|
||||||
|
* configured by the kernel during system initialization.
|
||||||
|
*
|
||||||
|
* The command will be available in he default module, so it will be available
|
||||||
|
* immediatly when.
|
||||||
|
*
|
||||||
|
*/
|
||||||
#ifdef CONFIG_CONSOLE_SHELL
|
#ifdef CONFIG_CONSOLE_SHELL
|
||||||
#define SHELL_REGISTER(_name, _commands) \
|
#define SHELL_REGISTER(_name, _commands) \
|
||||||
SHELL_REGISTER_WITH_PROMPT(_name, _commands, NULL)
|
SHELL_REGISTER_WITH_PROMPT(_name, _commands, NULL)
|
||||||
|
@ -91,9 +106,19 @@ struct shell_module {
|
||||||
.commands = _commands, \
|
.commands = _commands, \
|
||||||
.prompt = _prompt \
|
.prompt = _prompt \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SHELL_REGISTER_COMMAND(name, callback, _help) \
|
||||||
|
\
|
||||||
|
const struct shell_cmd (__shell__##name) __used \
|
||||||
|
__attribute__((__section__(".shell_cmd_"))) = { \
|
||||||
|
.cmd_name = name, \
|
||||||
|
.cb = callback, \
|
||||||
|
.help = _help \
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#define SHELL_REGISTER(_name, _commands)
|
#define SHELL_REGISTER(_name, _commands)
|
||||||
#define SHELL_REGISTER_WITH_PROMPT(_name, _commands, _prompt)
|
#define SHELL_REGISTER_WITH_PROMPT(_name, _commands, _prompt)
|
||||||
|
#define SHELL_REGISTER_COMMAND(_name, _callback, _help)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** @brief Initialize shell with optional prompt, NULL in case no prompt is
|
/** @brief Initialize shell with optional prompt, NULL in case no prompt is
|
||||||
|
|
|
@ -38,7 +38,12 @@
|
||||||
/* command table is located in the dedicated memory segment (.shell_) */
|
/* command table is located in the dedicated memory segment (.shell_) */
|
||||||
extern struct shell_module __shell_module_start[];
|
extern struct shell_module __shell_module_start[];
|
||||||
extern struct shell_module __shell_module_end[];
|
extern struct shell_module __shell_module_end[];
|
||||||
|
|
||||||
|
extern struct shell_cmd __shell_cmd_start[];
|
||||||
|
extern struct shell_cmd __shell_cmd_end[];
|
||||||
|
|
||||||
#define NUM_OF_SHELL_ENTITIES (__shell_module_end - __shell_module_start)
|
#define NUM_OF_SHELL_ENTITIES (__shell_module_end - __shell_module_start)
|
||||||
|
#define NUM_OF_SHELL_CMDS (__shell_cmd_end - __shell_cmd_start)
|
||||||
|
|
||||||
static const char *prompt;
|
static const char *prompt;
|
||||||
static char default_module_prompt[PROMPT_MAX_LEN];
|
static char default_module_prompt[PROMPT_MAX_LEN];
|
||||||
|
@ -196,6 +201,22 @@ static const struct shell_cmd *get_mod_cmd(struct shell_module *module,
|
||||||
return get_cmd(module->commands, cmd_str);
|
return get_cmd(module->commands, cmd_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct shell_cmd *get_standalone(const char *command)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_OF_SHELL_CMDS; i++) {
|
||||||
|
if (!strcmp(command, __shell_cmd_start[i].cmd_name)) {
|
||||||
|
return &__shell_cmd_start[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle internal 'help' command
|
||||||
|
*/
|
||||||
static int cmd_help(int argc, char *argv[])
|
static int cmd_help(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct shell_module *module = default_module;
|
struct shell_module *module = default_module;
|
||||||
|
@ -218,16 +239,21 @@ static int cmd_help(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!module) {
|
if (!module) {
|
||||||
printk("No help found for '%s'\n", cmd_str);
|
cmd = get_standalone(cmd_str);
|
||||||
return -EINVAL;
|
if (cmd) {
|
||||||
}
|
return show_cmd_help(cmd, true);
|
||||||
|
} else {
|
||||||
cmd = get_mod_cmd(module, cmd_str);
|
printk("No help found for '%s'\n", cmd_str);
|
||||||
if (cmd) {
|
return -EINVAL;
|
||||||
return show_cmd_help(cmd, true);
|
}
|
||||||
} else {
|
} else {
|
||||||
printk("Unknown command '%s'\n", cmd_str);
|
cmd = get_mod_cmd(module, cmd_str);
|
||||||
return -EINVAL;
|
if (cmd) {
|
||||||
|
return show_cmd_help(cmd, true);
|
||||||
|
} else {
|
||||||
|
printk("Unknown command '%s'\n", cmd_str);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,15 +265,26 @@ module_help:
|
||||||
} else { /* help for all entities */
|
} else { /* help for all entities */
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
printk("[Modules]\n");
|
||||||
|
|
||||||
if (NUM_OF_SHELL_ENTITIES == 0) {
|
if (NUM_OF_SHELL_ENTITIES == 0) {
|
||||||
printk("No registered modules.\n");
|
printk("No registered modules.\n");
|
||||||
} else {
|
|
||||||
printk("Available modules:\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < NUM_OF_SHELL_ENTITIES; i++) {
|
for (i = 0; i < NUM_OF_SHELL_ENTITIES; i++) {
|
||||||
printk("%s\n", __shell_module_start[i].module_name);
|
printk("%s\n", __shell_module_start[i].module_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printk("\n[Commands]\n");
|
||||||
|
|
||||||
|
if (NUM_OF_SHELL_CMDS == 0) {
|
||||||
|
printk("No registered commands.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_OF_SHELL_CMDS; i++) {
|
||||||
|
printk("%s\n", __shell_cmd_start[i].cmd_name);
|
||||||
|
}
|
||||||
|
|
||||||
printk("\nTo select a module, enter 'select <module name>'.\n");
|
printk("\nTo select a module, enter 'select <module name>'.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +297,7 @@ static int set_default_module(const char *name)
|
||||||
|
|
||||||
if (strlen(name) > MODULE_NAME_MAX_LEN) {
|
if (strlen(name) > MODULE_NAME_MAX_LEN) {
|
||||||
printk("Module name %s is too long, default is not changed\n",
|
printk("Module name %s is too long, default is not changed\n",
|
||||||
name);
|
name);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,6 +347,7 @@ static const struct shell_cmd *get_internal(const char *command)
|
||||||
return get_cmd(internal_commands, command);
|
return get_cmd(internal_commands, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int shell_exec(char *line)
|
int shell_exec(char *line)
|
||||||
{
|
{
|
||||||
char *argv[ARGC_MAX + 1], **argv_start = argv;
|
char *argv[ARGC_MAX + 1], **argv_start = argv;
|
||||||
|
@ -326,7 +364,12 @@ int shell_exec(char *line)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc == 1 && !default_module) {
|
cmd = get_standalone(argv[0]);
|
||||||
|
if (cmd) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc == 1 && !default_module && NUM_OF_SHELL_CMDS == 0) {
|
||||||
printk("No module selected. Use 'select' or 'help'.\n");
|
printk("No module selected. Use 'select' or 'help'.\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue