Merge pull request #16061 from kaspar030/xfa_shell

sys/shell: add XFA support
This commit is contained in:
Kaspar Schleiser 2021-03-09 14:47:43 +01:00 committed by GitHub
commit 010ba56174
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 105 additions and 12 deletions

View File

@ -24,6 +24,7 @@
#include "periph/pm.h" #include "periph/pm.h"
#include "kernel_defines.h" #include "kernel_defines.h"
#include "xfa.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -196,6 +197,37 @@ static inline void shell_run(const shell_command_t *commands,
shell_run_forever(commands, line_buf, len); shell_run_forever(commands, line_buf, len);
} }
/**
* @brief Define shell command
*
* This macro is a helper for defining a shell command and adding it to the
* shell commands XFA (cross file array).
*
* Shell commands added using this macros will be sorted *after* builtins and
* commands passed via parameter to `shell_run_once()`. If a command with the
* same name exists in any of those, they will make a command added via this
* macro inaccassible.
*
* Commands added with this macro will be sorted alphanumerically by `name`.
*
* @experimental This should be considered experimental API, subject to change
* without notice!
*
* Example:
*
* ```.c
* #include "shell.h"
* static int _my_command(int argc, char **argv) {
* // ...
* }
* SHELL_COMMAND(my_command, "my command help text", _my_command);
* ```
*/
#define SHELL_COMMAND(name, help, func) \
XFA_USE_CONST(shell_command_t*, shell_commands_xfa); \
static const shell_command_t _xfa_ ## name ## _cmd = { #name, help, &func }; \
XFA_ADD_PTR(shell_commands_xfa, name, name, &_xfa_ ## name ## _cmd)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -36,9 +36,13 @@
#include <errno.h> #include <errno.h>
#include "kernel_defines.h" #include "kernel_defines.h"
#include "xfa.h"
#include "shell.h" #include "shell.h"
#include "shell_commands.h" #include "shell_commands.h"
/* define shell command cross file array */
XFA_INIT_CONST(shell_command_t*, shell_commands_xfa);
#define ETX '\x03' /** ASCII "End-of-Text", or Ctrl-C */ #define ETX '\x03' /** ASCII "End-of-Text", or Ctrl-C */
#define EOT '\x04' /** ASCII "End-of-Transmission", or Ctrl-D */ #define EOT '\x04' /** ASCII "End-of-Transmission", or Ctrl-D */
#define BS '\x08' /** ASCII "Backspace" */ #define BS '\x08' /** ASCII "Backspace" */
@ -92,6 +96,19 @@ static shell_command_handler_t search_commands(const shell_command_t *entry,
return NULL; return NULL;
} }
static shell_command_handler_t search_commands_xfa(char *command)
{
unsigned n = XFA_LEN(shell_command_t*, shell_commands_xfa);
for (unsigned i = 0; i < n; i++) {
const volatile shell_command_t *entry = shell_commands_xfa[i];
if (strcmp(entry->name, command) == 0) {
return entry->handler;
}
}
return NULL;
}
static shell_command_handler_t find_handler( static shell_command_handler_t find_handler(
const shell_command_t *command_list, char *command) const shell_command_t *command_list, char *command)
{ {
@ -104,6 +121,10 @@ static shell_command_handler_t find_handler(
handler = search_commands(_builtin_cmds, command); handler = search_commands(_builtin_cmds, command);
} }
if (handler == NULL) {
handler = search_commands_xfa(command);
}
return handler; return handler;
} }
@ -114,6 +135,15 @@ static void print_commands(const shell_command_t *entry)
} }
} }
static void print_commands_xfa(void)
{
unsigned n = XFA_LEN(shell_command_t*, shell_commands_xfa);
for (unsigned i = 0; i < n; i++) {
const volatile shell_command_t *entry = shell_commands_xfa[i];
printf("%-20s %s\n", entry->name, entry->desc);
}
}
static void print_help(const shell_command_t *command_list) static void print_help(const shell_command_t *command_list)
{ {
puts("Command Description" puts("Command Description"
@ -125,6 +155,8 @@ static void print_help(const shell_command_t *command_list)
if (_builtin_cmds != NULL) { if (_builtin_cmds != NULL) {
print_commands(_builtin_cmds); print_commands(_builtin_cmds);
} }
print_commands_xfa();
} }
/** /**

View File

@ -2,4 +2,5 @@
# this test. # this test.
include ../periph_spi/Makefile.ci include ../periph_spi/Makefile.ci
BOARD_INSUFFICIENT_MEMORY += \ BOARD_INSUFFICIENT_MEMORY += \
samd10-xmini \
# #

View File

@ -103,6 +103,30 @@ static const shell_command_t shell_commands[] = {
{ NULL, NULL, NULL } { NULL, NULL, NULL }
}; };
static int _xfa_test1(int argc, char **argv)
{
(void)argc;
(void)argv;
printf("[XFA TEST 1 OK]\n");
return 0;
}
static int _xfa_test2(int argc, char **argv)
{
(void)argc;
(void)argv;
printf("[XFA TEST 2 OK]\n");
return 0;
}
/* Add above commands to the shell commands XFA using helper macro.
* Intentionally reversed order to test linker script based alphanumeric
* ordering. */
SHELL_COMMAND(xfa_test2, "xfa test command 2", _xfa_test2);
SHELL_COMMAND(xfa_test1, "xfa test command 1", _xfa_test1);
int main(void) int main(void)
{ {
printf("test_shell.\n"); printf("test_shell.\n");
@ -120,9 +144,7 @@ int main(void)
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE); shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
/* or use only system shell commands */ /* or use only system shell commands */
/* /* shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE); */
shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE);
*/
return 0; return 0;
} }

View File

@ -19,7 +19,9 @@ EXPECTED_HELP = (
'echo prints the input command', 'echo prints the input command',
'reboot Reboot the node', 'reboot Reboot the node',
'ps Prints information about running threads.', 'ps Prints information about running threads.',
'app_metadata Returns application metadata' 'app_metadata Returns application metadata',
'xfa_test1 xfa test command 1',
'xfa_test2 xfa test command 2'
) )
EXPECTED_PS = ( EXPECTED_PS = (
@ -96,6 +98,10 @@ CMDS = (
('ps', EXPECTED_PS), ('ps', EXPECTED_PS),
('help', EXPECTED_HELP), ('help', EXPECTED_HELP),
# test commands added to shell_commands_xfa
('xfa_test1', '[XFA TEST 1 OK]'),
('xfa_test2', '[XFA TEST 2 OK]'),
# test reboot # test reboot
('reboot', 'test_shell.'), ('reboot', 'test_shell.'),