Mynewt includes a 'Shell' library that allows you to add an extensible command-line style interface to your applications. You can implement custom commands that users can execute over a simple serial connection, and display formatted text back to the end users.
Adding shell support
To add shell support to your app, make sure the following pkg.deps
are defined in your pkg.yml
file:
pkg.deps: - "@apache-mynewt-core/sys/console/full" - "@apache-mynewt-core/sys/shell" - "@apache-mynewt-core/sys/sysinit"
And in the syscfg.vals
section of syscfg.yml
add the following:
syscfg.vals: # Enable the shell task. SHELL_TASK: 1
Adding a custom command handler
To add a new command handler use the following code snippets, placing the different sections at an appropriate place in your code:
#include "console/console.h" #include "shell/shell.h" ... // Command handler prototype declaration static int shell_test_cmd(int argc, char **argv); // Shell command struct static struct shell_cmd shell_test_cmd_struct = { .sc_cmd = "test", .sc_cmd_func = shell_test_cmd }; ... // Implement your command handler static int shell_test_cmd(int argc, char **argv) { console_printf("Test!\n"); return 0; } ... // Call this before sysinit to register the command #if MYNEWT_VAL(SHELL_TASK) shell_cmd_register(&shell_test_cmd_struct); #endif
Example: Updating apps/first/src/main.c
You can update apps/first
with a custom shell command using the following code in main.c:
#include <assert.h> #include <string.h> #include "os/os.h" #include "bsp/bsp.h" #include "hal/hal_gpio.h" #include "sysinit/sysinit.h" #include "console/console.h" #include "shell/shell.h" /* Define task stack and task object */ #define LED_TASK_PRIO (100) /* 1 = highest, 255 = lowest */ #define LED_STACK_SIZE OS_STACK_ALIGN(64) struct os_task led_task; os_stack_t led_task_stack[LED_STACK_SIZE]; /* LED task handler prototype declaration */ static void led_task_func(void *arg); /* Command handler prototype declaration */ static int shell_test_cmd(int argc, char **argv); /* Shell command struct */ static struct shell_cmd shell_test_cmd_struct = { .sc_cmd = "test", .sc_cmd_func = shell_test_cmd }; int main(int argc, char **argv) { int rc; /* Initialize the task */ os_task_init(&led_task, "blinky", led_task_func, NULL, LED_TASK_PRIO, OS_WAIT_FOREVER, led_task_stack, LED_STACK_SIZE); /* Call this before sysinit to register the command */ #if MYNEWT_VAL(SHELL_TASK) shell_cmd_register(&shell_test_cmd_struct); #endif /* Initialize the OS */ sysinit(); while (1) { /* Run the event queue to process background events */ os_eventq_run(os_eventq_dflt_get()); } return rc; } /* Implement the 'test' command handler */ static int shell_test_cmd(int argc, char **argv) { console_printf("Test!\n"); return 0; } static void led_task_func(void *arg) { /* Configure the LED GPIO as an output and HIGH (On) */ hal_gpio_init_out(LED_BLINK_PIN, 1); while (1) { /* Wait one second */ os_time_delay(OS_TICKS_PER_SEC * 1); /* Toggle the LED */ hal_gpio_toggle(LED_BLINK_PIN); } }
$ minicom -D /dev/tty.SLAB_USBtoUART
Once connected you can send the 'help
' command to get a list of valid shell commands, and then then 'test'
command which should display 'Test!
' in the shell:
Text editor powered by tinymce.