These are the notes I made on shell commands (attached). They should be
up to date with master.
K.
On 17/11/16 19:45, Christopher Collins wrote:
Hi David,
On Thu, Nov 17, 2016 at 01:32:17PM -0500, David G. Simmons wrote:
I'm thinking of writing up a Tutorial on how to enable the Console and Shell in
a Mynewt app -- especially since things have changed a bit with the Event Queue
and task management.
If I am understanding things correctly (and there's no guarantee that I am)
here's what needs to happen:
1) App needs to have an event Queue if it doesn't already
2) pkg.yml file needs to include
- sys/console/full
- sys/shell
3) syscfg.yml needs to set SHELL_TASK: 1
What else?
That looks correct to me. The only other step that might be missing is:
enable specific shell commands with the appropriate syscfg settings
(e.g., OS_CLI, STATS_CLI).
Chris
# Shell Command Handler
## 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"
```
In the `syscfg.vals` section of syscfg.yml (>= 0.10.0) add the following:
```
syscfg.vals:
# Enable the shell task.
SHELL_TASK: 1
```
## Adding a default system event queue
In your main.c file add the following code snippets:
```
#include "sysinit/sysinit.h"
#include "console/console.h"
#include "shell/shell.h"
/* System event queue task handler */
#define SYSEVQ_PRIO (10)
#define SYSEVQ_STACK_SIZE OS_STACK_ALIGN(512)
static struct os_task task_sysevq;
/* Event queue for events handled by the system (shell, etc.) */
static struct os_eventq sys_evq;
/**
* This task serves as a container for the shell and newtmgr packages. These
* packages enqueue timer events when they need this task to do work.
*/
static void
sysevq_handler(void *arg)
{
while (1) {
os_eventq_run(&sys_evq);
}
}
```
In the `init_tasks` function (or in main if you prefer) add:
```
/**
* init_tasks
*
* Called by main.c after sysinit(). This function performs initializations
* that are required before tasks are running.
*
* @return int 0 success; error otherwise.
*/
static void
init_tasks(void)
{
os_stack_t *pstack;
/* Initialize eventq and designate it as the default. Packages that need
* to schedule work items will piggyback on this eventq. Example packages
* which do this are sys/shell and mgmt/newtmgr.
*/
os_eventq_init(&sys_evq);
pstack = malloc(sizeof(os_stack_t)*SYSEVQ_STACK_SIZE);
assert(pstack);
os_task_init(&task_sysevq, "sysevq", sysevq_handler, NULL,
SYSEVQ_PRIO, OS_WAIT_FOREVER, pstack, SYSEVQ_STACK_SIZE);
/* Set the default eventq for packages that lack a dedicated task. */
os_eventq_dflt_set(&sys_evq);
}
```
Between `sysinit` and `os_start` in main add:
```
init_tasks();
```
## Adding a custom command handler
To add a new command handler use the following code snippets:
```
// 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 os_init to register the command
#if MYNEWT_VAL(SHELL_TASK)
shell_cmd_register(&shell_test_cmd_struct);
#endif
```