sys/shell: shell improvements

This patch brings improved shell functionality.

* Modules that group shell commands into subshells. A default module
can be selected to avoid typing the module prefix with each command.

* Per command help messages, per command parameter lists
and per parameter help messages. The help messages can be
conditionally compiled out to save flash.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/1151ca8a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/1151ca8a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/1151ca8a

Branch: refs/heads/master
Commit: 1151ca8a9a76d63e880dc78e8af42f8b29027ce8
Parents: a819c9b
Author: Michał Narajowski <michal.narajow...@codecoup.pl>
Authored: Wed May 3 11:05:27 2017 +0200
Committer: Michał Narajowski <michal.narajow...@codecoup.pl>
Committed: Wed May 3 11:37:52 2017 +0200

----------------------------------------------------------------------
 sys/shell/include/shell/shell.h        |  86 +++-
 sys/shell/include/shell/shell_prompt.h |  33 --
 sys/shell/include/shell/shell_tick.h   |  33 --
 sys/shell/pkg.yml                      |   2 -
 sys/shell/src/shell.c                  | 761 +++++++++++-----------------
 sys/shell/src/shell_os.c               | 159 ------
 sys/shell/src/shell_priv.h             |  35 --
 sys/shell/src/shell_prompt.c           |  75 ---
 sys/shell/src/shell_tick.c             |  62 ---
 sys/shell/syscfg.yml                   |  19 +-
 10 files changed, 389 insertions(+), 876 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1151ca8a/sys/shell/include/shell/shell.h
----------------------------------------------------------------------
diff --git a/sys/shell/include/shell/shell.h b/sys/shell/include/shell/shell.h
index d5473c2..d056e65 100644
--- a/sys/shell/include/shell/shell.h
+++ b/sys/shell/include/shell/shell.h
@@ -16,40 +16,90 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 #ifndef __SHELL_H__
 #define __SHELL_H__
 
-#include <os/os.h>
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-struct os_eventq;
+/** @brief Callback called when command is entered.
+ *
+ *  @param argc Number of parameters passed.
+ *  @param argv Array of option strings. First option is always command name.
+ *
+ * @return 0 in case of success or negative value in case of error.
+ */
+typedef int (*shell_cmd_func_t)(int argc, char *argv[]);
+
+struct shell_param {
+    const char *param_name;
+    const char *help;
+};
+
+struct shell_cmd_help {
+    const char *summary;
+    const char *usage;
+    const struct shell_param *params;
+};
 
-typedef int (*shell_cmd_func_t)(int argc, char **argv);
 struct shell_cmd {
-    char *sc_cmd;
+    const char *sc_cmd;
     shell_cmd_func_t sc_cmd_func;
-    STAILQ_ENTRY(shell_cmd) sc_next;
+    const struct shell_cmd_help *help;
+};
+
+struct shell_module {
+    const char *module_name;
+    const struct shell_cmd *commands;
 };
 
-int shell_cmd_register(struct shell_cmd *sc);
+/** @brief Callback called when registering module
+ *
+ *  @param module_name Name of the module
+ *  @param commands Array of shell_cmd structs
+ *
+ * @return 0 in case of success or negative value in case of error.
+ */
+typedef int (*shell_register_function_t)(const char *module_name,
+                                         const struct shell_cmd *commands);
+
+/** @brief Register a shell_module object
+ *
+ *  @param shell_name Module name to be entered in shell console.
+ *
+ *  @param shell_commands Array of commands to register.
+ *  The array should be terminated with an empty element.
+ */
+int shell_register(const char *shell_name,
+                   const struct shell_cmd *shell_commands);
 
-#define SHELL_NLIP_PKT_START1 (6)
-#define SHELL_NLIP_PKT_START2 (9)
-#define SHELL_NLIP_DATA_START1 (4)
-#define SHELL_NLIP_DATA_START2 (20)
+/** @brief Optionally register an app default cmd handler.
+ *
+ *  @param handler To be called if no cmd found in cmds registered with
+ *  shell_init.
+ */
+void shell_register_app_cmd_handler(shell_cmd_func_t handler);
 
-typedef int (*shell_nlip_input_func_t)(struct os_mbuf *, void *arg);
-int shell_nlip_input_register(shell_nlip_input_func_t nf, void *arg);
-int shell_nlip_output(struct os_mbuf *m);
+/** @brief Callback to get the current prompt.
+ *
+ *  @returns Current prompt string.
+ */
+typedef const char *(*shell_prompt_function_t)(void);
 
-void shell_evq_set(struct os_eventq *evq);
-void shell_init(void);
+/** @brief Optionally register a custom prompt callback.
+ *
+ *  @param handler To be called to get the current prompt.
+ */
+void shell_register_prompt_handler(shell_prompt_function_t handler);
 
-int shell_cmd_list_lock(void);
-int shell_cmd_list_unlock(void);
+/** @brief Optionally register a default module, to avoid typing it in
+ *  shell console.
+ *
+ *  @param name Module name.
+ */
+void shell_register_default_module(const char *name);
 
 #ifdef __cplusplus
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1151ca8a/sys/shell/include/shell/shell_prompt.h
----------------------------------------------------------------------
diff --git a/sys/shell/include/shell/shell_prompt.h 
b/sys/shell/include/shell/shell_prompt.h
deleted file mode 100644
index 9f42b54..0000000
--- a/sys/shell/include/shell/shell_prompt.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#ifndef H_SHELL_PROMPT_
-#define H_SHELL_PROMPT_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int shell_prompt_cmd(int argc, char **argv);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1151ca8a/sys/shell/include/shell/shell_tick.h
----------------------------------------------------------------------
diff --git a/sys/shell/include/shell/shell_tick.h 
b/sys/shell/include/shell/shell_tick.h
deleted file mode 100644
index 0d0b2e6..0000000
--- a/sys/shell/include/shell/shell_tick.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#ifndef H_SHELL_TICKS_
-#define H_SHELL_TICKS_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int shell_ticks_cmd(int argc, char **argv);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1151ca8a/sys/shell/pkg.yml
----------------------------------------------------------------------
diff --git a/sys/shell/pkg.yml b/sys/shell/pkg.yml
index 39d46b1..1f38a8d 100644
--- a/sys/shell/pkg.yml
+++ b/sys/shell/pkg.yml
@@ -25,9 +25,7 @@ pkg.keywords:
 
 pkg.deps:
     - kernel/os
-    - encoding/base64 
     - time/datetime
-    - util/crc
 pkg.req_apis:
     - console
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1151ca8a/sys/shell/src/shell.c
----------------------------------------------------------------------
diff --git a/sys/shell/src/shell.c b/sys/shell/src/shell.c
index 02cb3a1..c91dd42 100644
--- a/sys/shell/src/shell.c
+++ b/sys/shell/src/shell.c
@@ -21,543 +21,432 @@
 #include <string.h>
 #include <assert.h>
 
-#include "sysinit/sysinit.h"
 #include "syscfg/syscfg.h"
-#include "defs/error.h"
-#include "console/console.h"
-#include "console/prompt.h"
-#include "console/ticks.h"
 #include "os/os.h"
-#include "os/endian.h"
-#include "base64/base64.h"
-#include "crc/crc16.h"
+#include "console/console.h"
+#include "sysinit/sysinit.h"
 #include "shell/shell.h"
-#include "shell_priv.h"
-
-static shell_nlip_input_func_t g_shell_nlip_in_func;
-static void *g_shell_nlip_in_arg;
-
-static struct os_mqueue g_shell_nlip_mq;
-
-#define SHELL_HELP_PER_LINE     6
-#define SHELL_MAX_ARGS          20
-
-static int shell_echo_cmd(int argc, char **argv);
-static int shell_help_cmd(int argc, char **argv);
-int shell_prompt_cmd(int argc, char **argv);
-int shell_ticks_cmd(int argc, char **argv);
-
-
-static void shell_event_console_rdy(struct os_event *ev);
-
-/* Shared queue that the shell uses for work items. */
-static struct os_eventq *shell_evq;
-
-static struct shell_cmd g_shell_echo_cmd = {
-    .sc_cmd = "echo",
-    .sc_cmd_func = shell_echo_cmd
-};
-static struct shell_cmd g_shell_help_cmd = {
-    .sc_cmd = "?",
-    .sc_cmd_func = shell_help_cmd
-};
-static struct shell_cmd g_shell_prompt_cmd = {
-   .sc_cmd = "prompt",
-   .sc_cmd_func = shell_prompt_cmd
-}; 
-static struct shell_cmd g_shell_ticks_cmd = {
-   .sc_cmd = "ticks",
-   .sc_cmd_func = shell_ticks_cmd
-};
-static struct shell_cmd g_shell_os_tasks_display_cmd = {
-    .sc_cmd = "tasks",
-    .sc_cmd_func = shell_os_tasks_display_cmd
-};
-static struct shell_cmd g_shell_os_mpool_display_cmd = {
-    .sc_cmd = "mempools",
-    .sc_cmd_func = shell_os_mpool_display_cmd
-};
-static struct shell_cmd g_shell_os_date_cmd = {
-    .sc_cmd = "date",
-    .sc_cmd_func = shell_os_date_cmd
-};
-
-static struct os_event shell_console_rdy_ev = {
-    .ev_cb = shell_event_console_rdy,
-};
-
-static struct os_mutex g_shell_cmd_list_lock;
-
-static char *shell_line;
-static int shell_line_len;
-static char *argv[SHELL_MAX_ARGS];
-
-static STAILQ_HEAD(, shell_cmd) g_shell_cmd_list =
-    STAILQ_HEAD_INITIALIZER(g_shell_cmd_list);
-
-static struct os_mbuf *g_nlip_mbuf;
-static uint16_t g_nlip_expected_len;
-
-static struct os_eventq *
-shell_evq_get(void)
-{
-    return shell_evq;
-}
 
-void
-shell_evq_set(struct os_eventq *evq)
-{
-    os_eventq_designate(&shell_evq, evq, NULL);
-}
+#define SHELL_PROMPT "shell> "
 
-int
-shell_cmd_list_lock(void)
+#define MODULE_NAME_MAX_LEN     20
+
+/* additional chars are "> " (include '\0' )*/
+#define PROMPT_SUFFIX 3
+#define PROMPT_MAX_LEN (MODULE_NAME_MAX_LEN + PROMPT_SUFFIX)
+
+static struct shell_module shell_modules[MYNEWT_VAL(SHELL_MAX_MODULES)];
+static size_t num_of_shell_entities;
+
+static const char *prompt;
+static char default_module_prompt[PROMPT_MAX_LEN];
+static int default_module = -1;
+
+static shell_cmd_func_t app_cmd_handler;
+static shell_prompt_function_t app_prompt_handler;
+
+static struct console_input buf[MYNEWT_VAL(SHELL_MAX_CMD_QUEUED)];
+
+static struct os_eventq avail_queue;
+static struct os_event shell_console_ev[MYNEWT_VAL(SHELL_MAX_CMD_QUEUED)];
+
+static const char *
+get_prompt(void)
 {
-    int rc;
+    if (app_prompt_handler) {
+        const char *str;
 
-    if (!os_started()) {
-        return (0);
+        str = app_prompt_handler();
+        if (str) {
+            return str;
+        }
     }
 
-    rc = os_mutex_pend(&g_shell_cmd_list_lock, OS_WAIT_FOREVER);
-    if (rc != 0) {
-        goto err;
+    if (default_module != -1) {
+        return default_module_prompt;
     }
-    return (0);
-err:
-    return (rc);
+
+    return prompt;
 }
 
-int
-shell_cmd_list_unlock(void)
+static size_t
+line2argv(char *str, char *argv[], size_t size)
 {
-    int rc;
+    size_t argc = 0;
+
+    if (!strlen(str)) {
+        return 0;
+    }
 
-    if (!os_started()) {
-        return (0);
+    while (*str && *str == ' ') {
+        str++;
     }
 
-    rc = os_mutex_release(&g_shell_cmd_list_lock);
-    if (rc != 0) {
-        goto err;
+    if (!*str) {
+        return 0;
     }
-    return (0);
-err:
-    return (rc);
-}
 
-static int
-shell_cmd_find(char *cmd_name, struct shell_cmd **out_cmd)
-{
-    struct shell_cmd *sc;
-    int rc;
+    argv[argc++] = str;
 
-    rc = shell_cmd_list_lock();
-    if (rc != 0) {
-        return rc;
-    }
+    while ((str = strchr(str, ' '))) {
+        *str++ = '\0';
+
+        while (*str && *str == ' ') {
+            str++;
+        }
 
-    STAILQ_FOREACH(sc, &g_shell_cmd_list, sc_next) {
-        if (!strcmp(sc->sc_cmd, cmd_name)) {
+        if (!*str) {
             break;
         }
-    }
 
-    rc = shell_cmd_list_unlock();
-    if (rc != 0) {
-        return rc;
-    }
+        argv[argc++] = str;
 
-    if (out_cmd != NULL) {
-        *out_cmd = sc;
+        if (argc == size) {
+            console_printf("Too many parameters (max %zu)\n", size - 1);
+            return 0;
+        }
     }
 
-    if (sc == NULL) {
-        return SYS_ENOENT;
-    }
+    /* keep it POSIX style where argv[argc] is required to be NULL */
+    argv[argc] = NULL;
 
-    return 0;
+    return argc;
 }
 
-int
-shell_cmd_register(struct shell_cmd *sc)
+static int
+get_destination_module(const char *module_str, uint8_t len)
 {
-    int rc;
+    int i;
 
-#if MYNEWT_VAL(SHELL_DEBUG)
-    /* Ensure command not already registered. */
-    assert(shell_cmd_find(sc->sc_cmd, NULL) == SYS_ENOENT);
-#endif
+    for (i = 0; i < num_of_shell_entities; i++) {
+        if (!strncmp(module_str,
+                     shell_modules[i].module_name, len)) {
+            return i;
+        }
+    }
 
-    /* Add the command that is being registered. */
-    rc = shell_cmd_list_lock();
-    if (rc != 0) {
-        goto err;
+    return -1;
+}
+
+/* For a specific command: argv[0] = module name, argv[1] = command name
+ * If a default module was selected: argv[0] = command name
+ */
+static const char *
+get_command_and_module(char *argv[], int *module)
+{
+    *module = -1;
+
+    if (!argv[0]) {
+        console_printf("Unrecognized command\n");
+        return NULL;
     }
 
-    STAILQ_INSERT_TAIL(&g_shell_cmd_list, sc, sc_next);
+    if (default_module == -1) {
+        if (!argv[1] || argv[1][0] == '\0') {
+            console_printf("Unrecognized command: %s\n", argv[0]);
+            return NULL;
+        }
 
-    rc = shell_cmd_list_unlock();
-    if (rc != 0) {
-        goto err;
+        *module = get_destination_module(argv[0], MODULE_NAME_MAX_LEN);
+        if (*module == -1) {
+            console_printf("Illegal module %s\n", argv[0]);
+            return NULL;
+        }
+
+        return argv[1];
     }
 
-    return (0);
-err:
-    return (rc);
+    *module = default_module;
+    return argv[0];
 }
 
 static int
-shell_cmd(char *cmd, char **argv, int argc)
+show_cmd_help(char *argv[])
 {
-    struct shell_cmd *sc = NULL;
-    int rc;
+    const char *command = NULL;
+    int module = -1;
+    const struct shell_module *shell_module = NULL;
+    int i;
 
-    rc = shell_cmd_find(cmd, &sc);
-    switch (rc) {
-    case 0:
-        sc->sc_cmd_func(argc, argv);
+    command = get_command_and_module(argv, &module);
+    if ((module == -1) || (command == NULL)) {
         return 0;
+    }
 
-    case SYS_ENOENT:
-        console_printf("Unknown command %s\n", cmd);
-        return 0;
+    shell_module = &shell_modules[module];
+    for (i = 0; shell_module->commands[i].sc_cmd; i++) {
+        if (!strcmp(command, shell_module->commands[i].sc_cmd)) {
+            console_printf("%s:\n", shell_module->commands[i].sc_cmd);
 
-    default:
-        return rc;
+            if (!shell_module->commands[i].help) {
+                console_printf("\n");
+                return 0;
+            }
+            if (shell_module->commands[i].help->usage) {
+                console_printf("%s\n", shell_module->commands[i].help->usage);
+            } else if (shell_module->commands[i].help->summary) {
+                console_printf("%s\n", 
shell_module->commands[i].help->summary);
+            } else {
+                console_printf("\n");
+            }
+
+            return 0;
+        }
     }
+
+    console_printf("Unrecognized command: %s\n", argv[0]);
+    return 0;
 }
 
-static int
-shell_process_command(char *line, int len)
+static void
+print_modules(void)
 {
-    char *tok;
-    char *tok_ptr;
-    int argc;
-
-    tok_ptr = NULL;
-    tok = strtok_r(line, " ", &tok_ptr);
-    argc = 0;
-    while (argc < SHELL_MAX_ARGS - 1 && tok != NULL) {
-        argv[argc++] = tok;
+    int module;
 
-        tok = strtok_r(NULL, " ", &tok_ptr);
+    for (module = 0; module < num_of_shell_entities; module++) {
+        console_printf("%s\n", shell_modules[module].module_name);
     }
+}
 
-    /* Terminate the argument list with a null pointer. */
-    argv[argc] = NULL;
+static void
+print_module_commands(const int module)
+{
+    const struct shell_module *shell_module = &shell_modules[module];
+    int i;
 
-    if (argc) {
-        (void) shell_cmd(argv[0], argv, argc);
-    }
-    else {
+    console_printf("help\n");
+
+    for (i = 0; shell_module->commands[i].sc_cmd; i++) {
+        console_printf("%-30s", shell_module->commands[i].sc_cmd);
+        if (shell_module->commands[i].help &&
+            shell_module->commands[i].help->summary) {
+        console_printf("%s", shell_module->commands[i].help->summary);
+        }
         console_printf("\n");
     }
-    console_print_prompt();
-    return (0);
 }
 
 static int
-shell_nlip_process(char *data, int len)
+show_help(int argc, char *argv[])
 {
-    uint16_t copy_len;
-    int rc;
-    struct os_mbuf *m;
-    uint16_t crc;
+    int module;
 
-    rc = base64_decode(data, data);
-    if (rc < 0) {
-        goto err;
+    /* help per command */
+    if ((argc > 2) || ((default_module != -1) && (argc == 2))) {
+        return show_cmd_help(&argv[1]);
     }
-    len = rc;
-
-    if (g_nlip_mbuf == NULL) {
-        if (len < 2) {
-            rc = -1;
-            goto err;
-        }
 
-        g_nlip_expected_len = ntohs(*(uint16_t *) data);
-        g_nlip_mbuf = os_msys_get_pkthdr(g_nlip_expected_len, 0);
-        if (!g_nlip_mbuf) {
-            rc = -1;
-            goto err;
+    /* help per module */
+    if ((argc == 2) || ((default_module != -1) && (argc == 1))) {
+        if (default_module == -1) {
+            module = get_destination_module(argv[1], MODULE_NAME_MAX_LEN);
+            if (module == -1) {
+                console_printf("Illegal module %s\n", argv[1]);
+                return 0;
+            }
+        } else {
+            module = default_module;
         }
 
-        data += sizeof(uint16_t);
-        len -= sizeof(uint16_t);
+        print_module_commands(module);
+    } else { /* help for all entities */
+        console_printf("Available modules:\n");
+        print_modules();
+        console_printf("To select a module, enter 'select <module name>'.\n");
     }
 
-    copy_len = min(g_nlip_expected_len - OS_MBUF_PKTHDR(g_nlip_mbuf)->omp_len,
-            len);
+    return 0;
+}
+
+static int
+set_default_module(const char *name)
+{
+    int module;
 
-    rc = os_mbuf_copyinto(g_nlip_mbuf, OS_MBUF_PKTHDR(g_nlip_mbuf)->omp_len,
-            data, copy_len);
-    if (rc != 0) {
-        goto err;
+    if (strlen(name) > MODULE_NAME_MAX_LEN) {
+        console_printf("Module name %s is too long, default is not changed\n",
+                       name);
+        return -1;
     }
 
-    if (OS_MBUF_PKTHDR(g_nlip_mbuf)->omp_len == g_nlip_expected_len) {
-        if (g_shell_nlip_in_func) {
-            crc = CRC16_INITIAL_CRC;
-            for (m = g_nlip_mbuf; m; m = SLIST_NEXT(m, om_next)) {
-                crc = crc16_ccitt(crc, m->om_data, m->om_len);
-            }
-            if (crc == 0 && g_nlip_expected_len >= sizeof(crc)) {
-                os_mbuf_adj(g_nlip_mbuf, -sizeof(crc));
-                g_shell_nlip_in_func(g_nlip_mbuf, g_shell_nlip_in_arg);
-            } else {
-                os_mbuf_free_chain(g_nlip_mbuf);
-            }
-        } else {
-            os_mbuf_free_chain(g_nlip_mbuf);
-        }
-        g_nlip_mbuf = NULL;
-        g_nlip_expected_len = 0;
+    module = get_destination_module(name, MODULE_NAME_MAX_LEN);
+
+    if (module == -1) {
+        console_printf("Illegal module %s, default is not changed\n", name);
+        return -1;
     }
 
-    return (0);
-err:
-    return (rc);
+    default_module = module;
+
+    strncpy(default_module_prompt, name, MODULE_NAME_MAX_LEN);
+    strcat(default_module_prompt, "> ");
+
+    return 0;
 }
 
 static int
-shell_nlip_mtx(struct os_mbuf *m)
+select_module(int argc, char *argv[])
 {
-#define SHELL_NLIP_MTX_BUF_SIZE (12)
-    uint8_t readbuf[SHELL_NLIP_MTX_BUF_SIZE];
-    char encodebuf[BASE64_ENCODE_SIZE(SHELL_NLIP_MTX_BUF_SIZE)];
-    char pkt_seq[3] = { '\n', SHELL_NLIP_PKT_START1, SHELL_NLIP_PKT_START2 };
-    char esc_seq[2] = { SHELL_NLIP_DATA_START1, SHELL_NLIP_DATA_START2 };
-    uint16_t totlen;
-    uint16_t dlen;
-    uint16_t off;
-    uint16_t crc;
-    int rb_off;
-    int elen;
-    uint16_t nwritten;
-    uint16_t linelen;
-    int rc;
-    struct os_mbuf *tmp;
-    void *ptr;
-
-    /* Convert the mbuf into a packet.
-     *
-     * starts with 06 09
-     * base64 encode:
-     *  - total packet length (uint16_t)
-     *  - data
-     *  - crc
-     * base64 encoded data must be less than 122 bytes per line to
-     * avoid overflows and adhere to convention.
-     *
-     * continuation packets are preceded by 04 20 until the entire
-     * buffer has been sent.
-     */
-    crc = CRC16_INITIAL_CRC;
-    for (tmp = m; tmp; tmp = SLIST_NEXT(tmp, om_next)) {
-        crc = crc16_ccitt(crc, tmp->om_data, tmp->om_len);
+    if (argc == 1) {
+        default_module = -1;
+    } else {
+        set_default_module(argv[1]);
     }
-    crc = htons(crc);
-    ptr = os_mbuf_extend(m, sizeof(crc));
-    if (!ptr) {
-        rc = -1;
-        goto err;
-    }
-    memcpy(ptr, &crc, sizeof(crc));
-
-    totlen = OS_MBUF_PKTHDR(m)->omp_len;
-    nwritten = 0;
-    off = 0;
 
-    /* Start a packet */
-    console_write(pkt_seq, sizeof(pkt_seq));
-
-    linelen = 0;
+    return 0;
+}
 
-    rb_off = 2;
-    dlen = htons(totlen);
-    memcpy(readbuf, &dlen, sizeof(dlen));
+static shell_cmd_func_t
+get_cb(int argc, char *argv[])
+{
+    const char *first_string = argv[0];
+    int module = -1;
+    const struct shell_module *shell_module;
+    const char *command;
+    int i;
 
-    while (totlen > 0) {
-        dlen = min(SHELL_NLIP_MTX_BUF_SIZE - rb_off, totlen);
+    if (!first_string || first_string[0] == '\0') {
+        console_printf("Illegal parameter\n");
+        return NULL;
+    }
 
-        rc = os_mbuf_copydata(m, off, dlen, readbuf + rb_off);
-        if (rc != 0) {
-            goto err;
-        }
-        off += dlen;
-
-        /* If the next packet will overwhelm the line length, truncate
-         * this line.
-         */
-        if (linelen +
-                BASE64_ENCODE_SIZE(min(SHELL_NLIP_MTX_BUF_SIZE - rb_off,
-                        totlen - dlen)) >= 120) {
-            elen = base64_encode(readbuf, dlen + rb_off, encodebuf, 1);
-            console_write(encodebuf, elen);
-            console_write("\n", 1);
-            console_write(esc_seq, sizeof(esc_seq));
-            linelen = 0;
-        } else {
-            elen = base64_encode(readbuf, dlen + rb_off, encodebuf, 0);
-            console_write(encodebuf, elen);
-            linelen += elen;
-        }
+    if (!strcmp(first_string, "help")) {
+        return show_help;
+    }
 
-        rb_off = 0;
+    if (!strcmp(first_string, "select")) {
+        return select_module;
+    }
 
-        nwritten += elen;
-        totlen -= dlen;
+    if ((argc == 1) && (default_module == -1)) {
+        console_printf("Missing parameter\n");
+        return NULL;
     }
 
-    elen = base64_pad(encodebuf, linelen);
-    console_write(encodebuf, elen);
+    command = get_command_and_module(argv, &module);
+    if ((module == -1) || (command == NULL)) {
+        return NULL;
+    }
 
-    console_write("\n", 1);
+    shell_module = &shell_modules[module];
+    console_printf("module: %d, command: %s\n", module, command);
+    for (i = 0; shell_module->commands[i].sc_cmd; i++) {
+        if (!strcmp(command, shell_module->commands[i].sc_cmd)) {
+            return shell_module->commands[i].sc_cmd_func;
+        }
+    }
 
-    return (0);
-err:
-    return (rc);
+    return NULL;
 }
 
-int
-shell_nlip_input_register(shell_nlip_input_func_t nf, void *arg)
+static void
+shell_process_command(char *line)
 {
-    g_shell_nlip_in_func = nf;
-    g_shell_nlip_in_arg = arg;
+    char *argv[MYNEWT_VAL(SHELL_CMD_ARGC_MAX) + 1];
+    shell_cmd_func_t sc_cmd_func;
+    size_t argc_offset = 0;
+    size_t argc;
+
+    argc = line2argv(line, argv, MYNEWT_VAL(SHELL_CMD_ARGC_MAX) + 1);
+    if (!argc) {
+        console_printf("%s", get_prompt());
+        return;
+    }
 
-    return (0);
-}
+    sc_cmd_func = get_cb(argc, argv);
+    if (!sc_cmd_func) {
+        if (app_cmd_handler != NULL) {
+            sc_cmd_func = app_cmd_handler;
+        } else {
+            console_printf("Unrecognized command: %s\n", argv[0]);
+            console_printf("Type 'help' for list of available commands\n");
+            console_printf("%s", get_prompt());
+            return;
+        }
+    }
 
-int
-shell_nlip_output(struct os_mbuf *m)
-{
-    int rc;
+    /* Allow invoking a cmd with module name as a prefix; a command should
+     * not know how it was invoked (with or without prefix)
+     */
+    if (default_module == -1 && sc_cmd_func != select_module && sc_cmd_func != 
show_help) {
+        argc_offset = 1;
+    }
 
-    rc = os_mqueue_put(&g_shell_nlip_mq, shell_evq_get(), m);
-    if (rc != 0) {
-        goto err;
+    /* Execute callback with arguments */
+    if (sc_cmd_func(argc - argc_offset, &argv[argc_offset]) < 0) {
+        show_cmd_help(argv);
     }
 
-    return (0);
-err:
-    return (rc);
+    console_printf("%s", get_prompt());
 }
 
 static void
-shell_read_console(void)
+shell(struct os_event *ev)
 {
-    int rc;
-    int full_line;
+    struct console_input *cmd;
 
-    while (1) {
-        rc = console_read(shell_line + shell_line_len,
-          MYNEWT_VAL(SHELL_MAX_INPUT_LEN) - shell_line_len, &full_line);
-        if (rc <= 0 && !full_line) {
-            break;
-        }
-        shell_line_len += rc;
-        if (full_line) {
-            if (shell_line_len > 2) {
-                if (shell_line[0] == SHELL_NLIP_PKT_START1 &&
-                        shell_line[1] == SHELL_NLIP_PKT_START2) {
-                    if (g_nlip_mbuf) {
-                        os_mbuf_free_chain(g_nlip_mbuf);
-                        g_nlip_mbuf = NULL;
-                    }
-                    g_nlip_expected_len = 0;
-
-                    rc = shell_nlip_process(&shell_line[2], shell_line_len - 
2);
-                } else if (shell_line[0] == SHELL_NLIP_DATA_START1 &&
-                        shell_line[1] == SHELL_NLIP_DATA_START2) {
-                    rc = shell_nlip_process(&shell_line[2], shell_line_len - 
2);
-                } else {
-                    shell_process_command(shell_line, shell_line_len);
-                }
-            } else {
-                shell_process_command(shell_line, shell_line_len);
-            }
-            shell_line_len = 0;
-        }
+    if (!ev) {
+        console_printf("%s", get_prompt());
+        return;
     }
+
+    cmd = ev->ev_arg;
+    if (!cmd) {
+        console_printf("%s", get_prompt());
+        return;
+    }
+
+    shell_process_command(cmd->line);
+    os_eventq_put(&avail_queue, ev);
 }
 
-static void
-shell_event_console_rdy(struct os_event *ev)
+void
+shell_register_app_cmd_handler(shell_cmd_func_t handler)
 {
-    shell_read_console();
+    app_cmd_handler = handler;
 }
 
-static void
-shell_event_data_in(struct os_event *ev)
+void
+shell_register_prompt_handler(shell_prompt_function_t handler)
 {
-    struct os_mbuf *m;
-
-    /* Copy data out of the mbuf 12 bytes at a time and write it to
-     * the console.
-     */
-    while (1) {
-        m = os_mqueue_get(&g_shell_nlip_mq);
-        if (!m) {
-            break;
-        }
+    app_prompt_handler = handler;
+}
 
-        (void) shell_nlip_mtx(m);
+void
+shell_register_default_module(const char *name)
+{
+    int result = set_default_module(name);
 
-        os_mbuf_free_chain(m);
+    if (result != -1) {
+        console_printf("\n");
+        console_printf("%s", default_module_prompt);
     }
 }
 
-/**
- * This function is called from the console APIs when data is available
- * to be read.  This is either a full line, or when the
- * console buffer (default = 128) is full.
- */
 static void
-shell_console_rx_cb(void)
-{
-    os_eventq_put(shell_evq_get(), &shell_console_rdy_ev);
-}
-
-static int
-shell_echo_cmd(int argc, char **argv)
+line_queue_init(void)
 {
     int i;
 
-    for (i = 1; i < argc; i++) {
-        console_write(argv[i], strlen(argv[i]));
-        console_write(" ", sizeof(" ")-1);
+    for (i = 0; i < MYNEWT_VAL(SHELL_MAX_CMD_QUEUED); i++) {
+        shell_console_ev[i].ev_cb = shell;
+        shell_console_ev[i].ev_arg = &buf[i];
+        os_eventq_put(&avail_queue, &shell_console_ev[i]);
     }
-    console_write("\n", sizeof("\n")-1);
-
-    return (0);
 }
 
-static int
-shell_help_cmd(int argc, char **argv)
+int
+shell_register(const char *module_name, const struct shell_cmd *commands)
 {
-    int rc;
-    int i = 0;
-    struct shell_cmd *sc;
-
-    rc = shell_cmd_list_lock();
-    if (rc != 0) {
+    if (num_of_shell_entities >= MYNEWT_VAL(SHELL_MAX_MODULES)) {
         return -1;
     }
-    console_printf("Commands:\n");
-    STAILQ_FOREACH(sc, &g_shell_cmd_list, sc_next) {
-        console_printf("%9s ", sc->sc_cmd);
-        if (i++ % SHELL_HELP_PER_LINE == SHELL_HELP_PER_LINE - 1) {
-            console_printf("\n");
-        }
-    }
-    if (i % SHELL_HELP_PER_LINE) {
-        console_printf("\n");
-    }
-    shell_cmd_list_unlock();
 
-    return (0);
+    shell_modules[num_of_shell_entities].module_name = module_name;
+    shell_modules[num_of_shell_entities].commands = commands;
+    ++num_of_shell_entities;
+
+    return 0;
 }
 
 void
@@ -570,42 +459,8 @@ shell_init(void)
     return;
 #endif
 
-    int rc;
-
-    free(shell_line);
-    shell_line = NULL;
-
-#if MYNEWT_VAL(SHELL_MAX_INPUT_LEN) > 0
-    shell_line = malloc(MYNEWT_VAL(SHELL_MAX_INPUT_LEN));
-    SYSINIT_PANIC_ASSERT(shell_line != NULL);
-#endif
-
-    rc = os_mutex_init(&g_shell_cmd_list_lock);
-    SYSINIT_PANIC_ASSERT(rc == 0);
-
-    rc = shell_cmd_register(&g_shell_echo_cmd);
-    SYSINIT_PANIC_ASSERT(rc == 0);
-
-    rc = shell_cmd_register(&g_shell_help_cmd);
-    SYSINIT_PANIC_ASSERT(rc == 0);
-
-    rc = shell_cmd_register(&g_shell_prompt_cmd);
-    SYSINIT_PANIC_ASSERT(rc == 0);
-    
-    rc = shell_cmd_register(&g_shell_ticks_cmd);
-    SYSINIT_PANIC_ASSERT(rc == 0);
-
-    rc = shell_cmd_register(&g_shell_os_tasks_display_cmd);
-    SYSINIT_PANIC_ASSERT(rc == 0);
-
-    rc = shell_cmd_register(&g_shell_os_mpool_display_cmd);
-    SYSINIT_PANIC_ASSERT(rc == 0);
-
-    rc = shell_cmd_register(&g_shell_os_date_cmd);
-    SYSINIT_PANIC_ASSERT(rc == 0);
-
-    os_mqueue_init(&g_shell_nlip_mq, shell_event_data_in, NULL);
-    console_init(shell_console_rx_cb);
-
-    shell_evq_set(os_eventq_dflt_get());
+    os_eventq_init(&avail_queue);
+    line_queue_init();
+    prompt = SHELL_PROMPT;
+    console_set_queues(&avail_queue, os_eventq_dflt_get());
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1151ca8a/sys/shell/src/shell_os.c
----------------------------------------------------------------------
diff --git a/sys/shell/src/shell_os.c b/sys/shell/src/shell_os.c
deleted file mode 100644
index 48a3b3d..0000000
--- a/sys/shell/src/shell_os.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include "os/os.h"
-
-#include "os/queue.h"
-#include "os/os_time.h"
-
-#include "console/console.h"
-#include "shell/shell.h"
-#include "shell_priv.h"
-
-#include <assert.h>
-#include <string.h>
-#include <datetime/datetime.h>
-
-int
-shell_os_tasks_display_cmd(int argc, char **argv)
-{
-    struct os_task *prev_task;
-    struct os_task_info oti;
-    char *name;
-    int found;
-
-    name = NULL;
-    found = 0;
-
-    if (argc > 1 && strcmp(argv[1], "")) {
-        name = argv[1];
-    }
-
-    console_printf("Tasks: \n");
-    prev_task = NULL;
-    console_printf("%8s %3s %3s %8s %8s %8s %8s %8s %8s %3s\n",
-      "task", "pri", "tid", "runtime", "csw", "stksz", "stkuse",
-      "lcheck", "ncheck", "flg");
-    while (1) {
-        prev_task = os_task_info_get_next(prev_task, &oti);
-        if (prev_task == NULL) {
-            break;
-        }
-
-        if (name) {
-            if (strcmp(name, oti.oti_name)) {
-                continue;
-            } else {
-                found = 1;
-            }
-        }
-
-        console_printf("%8s %3u %3u %8lu %8lu %8u %8u %8lu %8lu %3x\n",
-                oti.oti_name, oti.oti_prio, oti.oti_taskid,
-                (unsigned long)oti.oti_runtime, (unsigned long)oti.oti_cswcnt,
-                oti.oti_stksize, oti.oti_stkusage,
-                (unsigned long)oti.oti_last_checkin,
-                (unsigned long)oti.oti_next_checkin, oti.oti_flags);
-
-    }
-
-    if (name && !found) {
-        console_printf("Couldn't find task with name %s\n", name);
-    }
-
-    return (0);
-}
-
-int
-shell_os_mpool_display_cmd(int argc, char **argv)
-{
-    struct os_mempool *mp;
-    struct os_mempool_info omi;
-    char *name;
-    int found;
-
-    name = NULL;
-    found = 0;
-
-    if (argc > 1 && strcmp(argv[1], "")) {
-        name = argv[1];
-    }
-
-    console_printf("Mempools: \n");
-    mp = NULL;
-    console_printf("%32s %5s %4s %4s %4s\n", "name", "blksz", "cnt", "free",
-                   "min");
-    while (1) {
-        mp = os_mempool_info_get_next(mp, &omi);
-        if (mp == NULL) {
-            break;
-        }
-
-        if (name) {
-            if (strcmp(name, omi.omi_name)) {
-                continue;
-            } else {
-                found = 1;
-            }
-        }
-
-        console_printf("%32s %5d %4d %4d %4d\n", omi.omi_name,
-                       omi.omi_block_size, omi.omi_num_blocks,
-                       omi.omi_num_free, omi.omi_min_free);
-    }
-
-    if (name && !found) {
-        console_printf("Couldn't find a memory pool with name %s\n",
-                name);
-    }
-
-    return (0);
-}
-
-int
-shell_os_date_cmd(int argc, char **argv)
-{
-    struct os_timeval tv;
-    struct os_timezone tz;
-    char buf[DATETIME_BUFSIZE];
-    int rc;
-
-    argc--; argv++;     /* skip command name */
-
-    if (argc == 0) {
-        /* Display the current datetime */
-        rc = os_gettimeofday(&tv, &tz);
-        assert(rc == 0);
-        rc = datetime_format(&tv, &tz, buf, sizeof(buf));
-        assert(rc == 0);
-        console_printf("%s\n", buf);
-    } else if (argc == 1) {
-        /* Set the current datetime */
-        rc = datetime_parse(*argv, &tv, &tz);
-        if (rc == 0) {
-            rc = os_settimeofday(&tv, &tz);
-        } else {
-            console_printf("Invalid datetime\n");
-        }
-    } else {
-        rc = -1;
-    }
-
-    return (rc);
-}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1151ca8a/sys/shell/src/shell_priv.h
----------------------------------------------------------------------
diff --git a/sys/shell/src/shell_priv.h b/sys/shell/src/shell_priv.h
deleted file mode 100644
index e79d56e..0000000
--- a/sys/shell/src/shell_priv.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#ifndef __SHELL_PRIV_H_
-#define __SHELL_PRIV_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int shell_os_tasks_display_cmd(int argc, char **argv);
-int shell_os_mpool_display_cmd(int argc, char **argv);
-int shell_os_date_cmd(int argc, char **argv);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __SHELL_PRIV_H_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1151ca8a/sys/shell/src/shell_prompt.c
----------------------------------------------------------------------
diff --git a/sys/shell/src/shell_prompt.c b/sys/shell/src/shell_prompt.c
deleted file mode 100644
index 801d7ca..0000000
--- a/sys/shell/src/shell_prompt.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include <string.h>
-#include "shell/shell.h"
-#include <console/console.h>
-#include <console/prompt.h>
-static char shell_prompt = '>';
-
-void console_set_prompt(char p);
-
-/**
- * Handles the 'prompt' command
- * with set argument, sets the prompt to the provided char
- * with the show argument, echos the current prompt
- * otherwise echos the prompt and the usage message
- */
-int
-shell_prompt_cmd(int argc, char **argv)
-{
-    int rc;
-
-    rc = shell_cmd_list_lock();
-    if (rc != 0) {
-        return -1;
-    }
-    if (argc > 1) {
-        if (!strcmp(argv[1], "show")) {
-            console_printf(" Prompt character: %c\n", shell_prompt);
-        }   
-        else if (!strcmp(argv[1],"set")) {
-            shell_prompt = argv[2][0];
-            console_printf(" Prompt set to: %c\n", argv[2][0]);
-            console_set_prompt(argv[2][0]);
-        }
-        else if (!strcmp(argv[1], "on")) {
-            console_yes_prompt();
-            console_printf(" Prompt now on.\n");
-        }   
-        else if (!strcmp(argv[1], "off")) {
-            console_no_prompt();
-            console_printf(" Prompt now off.\n");
-        }
-        else {
-            goto usage;
-        }
-    } 
-    else {
-        goto usage;
-    }
-    shell_cmd_list_unlock();
-    return 0;
-usage:
-    console_printf("Usage: prompt [on|off]|[set|show] [prompt_char]\n");
-    shell_cmd_list_unlock();
-    return 0;
-  
-}
- 
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1151ca8a/sys/shell/src/shell_tick.c
----------------------------------------------------------------------
diff --git a/sys/shell/src/shell_tick.c b/sys/shell/src/shell_tick.c
deleted file mode 100644
index ec2fdff..0000000
--- a/sys/shell/src/shell_tick.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include <string.h>
-#include "shell/shell.h"
-#include <console/console.h>
-#include <console/ticks.h>
-#include "syscfg/syscfg.h"
-
-/**
- * Handles the 'ticks' command
- */
-int
-shell_ticks_cmd(int argc, char **argv)
-{
-    int rc;
-
-    rc = shell_cmd_list_lock();
-    if (rc != 0) {
-        return -1;
-    }
-    if (argc > 1) {
-        if (!strcmp(argv[1], "on")) {
-            console_yes_ticks();
-            console_printf(" Console Ticks on\n");
-        }   
-        else if (!strcmp(argv[1],"off")) {
-            console_printf(" Console Ticks off\n");
-            console_no_ticks();
-        }
-        else {
-            goto usage;
-        }
-    } 
-    else {
-        goto usage;
-    }
-    shell_cmd_list_unlock();
-    return 0;
-usage:
-    console_printf(" Usage: ticks [on|off]\n");
-    shell_cmd_list_unlock();
-    return 0;
-  
-}
- 
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1151ca8a/sys/shell/syscfg.yml
----------------------------------------------------------------------
diff --git a/sys/shell/syscfg.yml b/sys/shell/syscfg.yml
index af7ad77..8a53bff 100644
--- a/sys/shell/syscfg.yml
+++ b/sys/shell/syscfg.yml
@@ -22,9 +22,16 @@ syscfg.defs:
     SHELL_TASK:
         description: 'Controls whether shell is enabled or not.'
         value: 0
-    SHELL_MAX_INPUT_LEN:
-        description: 'Maximum input line length'
-        value: 256
-    SHELL_DEBUG:
-        description: Enables additional error checking in the shell package.
-        value: 0
+
+    SHELL_CMD_ARGC_MAX:
+        description: 'Max number of command line arguments'
+        value: 12
+    SHELL_CMD_HELP:
+        description: 'Include help information for shell commands'
+        value: 1
+    SHELL_MAX_MODULES:
+        description: 'Max number of modules'
+        value: 3
+    SHELL_MAX_CMD_QUEUED:
+        description: 'Max number of command lines queued'
+        value: 1


Reply via email to