TEN MBED OS Course shell utility

Revision:
0:1e8461adc480
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shell.cpp	Sun Jan 29 20:57:17 2017 +0000
@@ -0,0 +1,185 @@
+/**
+ * @brief our first hello world threaded program with MBED OS
+ */
+#include "mbed.h"
+#include "rtos.h"
+#include "shell.h"
+
+/* declare a thread reserved only for shell command handler */
+const size_t shell_stk_size = 8192;
+uint8_t shell_stk[shell_stk_size];
+Thread shell_thread(osPriorityNormal, shell_stk_size, &shell_stk[0]);
+
+/* reserve the debbuger uart to shell interface */
+Serial pc_serial(SHELL_TXD,SHELL_RXD);
+
+static shell_callback_t shell_handler = NULL;
+static shell_usage_t shell_usage;
+static int argc = 0;
+static char *argv[16];    
+
+/**
+ * @brief show help menu 
+ */
+static void print_usage(void) 
+{
+    pc_serial.printf("## use with the syntax below:         \n\r");
+    pc_serial.printf("## command <arg1> <arg2> ... <arg16>  \n\r");
+    pc_serial.printf("## Available commands:                \n\r");
+    if(shell_usage != NULL) {
+        shell_usage((void *)&pc_serial);
+    }
+}
+
+ 
+/**
+ * @brief parse the command received via comport
+ */
+static void shell_parser (char *cmd, int size)
+{
+    int cmd_ptr = 0;
+    int arg_ptr = 0;
+    int cmd_size = 0;
+    char command_buffer[256];
+    
+    
+    /* copy to the root command */
+    memset(&command_buffer, 0, sizeof(command_buffer)); 
+    
+    /* find the root command terminator (space) */
+    while(cmd_ptr < size) {
+        if(cmd[cmd_ptr] == ' ') break;
+        cmd_ptr++;
+    }
+    cmd_size = size - cmd_ptr;
+    
+    
+    /* extract command arguments */
+    strncpy(&command_buffer[0], &cmd[cmd_ptr + 1], (size - cmd_ptr));    
+    
+    /* terminates the root command */
+    cmd[cmd_ptr] = 0;
+    arg_ptr = 0;
+    
+    //pc_serial.printf("## command: %s \n\r", cmd);
+    //pc_serial.printf("## arguments: %s \n\r", command_buffer);
+
+  
+    /* extract the further arguments */
+    while(arg_ptr < (cmd_size)) {
+ 
+        argc++;
+        *(argv + (argc- 1)) = &command_buffer[arg_ptr];
+ 
+        /* find terminator */
+        while(command_buffer[arg_ptr] != ' ') {
+            arg_ptr++;
+        }
+        
+        /* adds to argument list */
+        command_buffer[arg_ptr] = 0;
+        arg_ptr++;       
+       // pc_serial.printf("## argument no: %d : %s \n\r", argc, argv[argc-1]);
+    }
+
+
+
+    /* finds and execute the command table */
+    if(shell_handler != NULL){
+        
+        int ret = shell_handler(cmd, argc, argv, (void *)&pc_serial);
+        if(ret < 0) {
+            print_usage();        
+        }
+    }else {
+        print_usage();
+    }
+}
+
+
+
+
+/**
+ * @brief shell commands processing thread 
+ */
+static void shell_task(void)
+{
+    char serial_buffer[1024] = {0};
+    int read_ptr = 0;
+ 
+    /* setup the serial as 115200 bps */
+    pc_serial.baud(115200);
+       
+    /* prints a welcome message */
+     
+    pc_serial.printf("******************************************************************\n\r");    
+    pc_serial.printf("***         Welcome to MbedOS  Simple Shell application      ****\n\r");
+    pc_serial.printf("*** Type some commands or just Enter key to see the available ****\n\r");
+    pc_serial.printf("******************************************************************\n\r");            
+    pc_serial.printf(">>");
+    
+    for(;;Thread::wait(50)) {        
+        /* check if we have character available */
+        if(pc_serial.readable()) {
+            bool new_cmd = false;
+            
+            /* get the incoming character */
+            char c = pc_serial.getc();
+                       
+            if( (c == '\n') || (c == '\r')) {
+                /* handle enter key */
+                new_cmd = true;
+                pc_serial.printf("\n\r");
+                
+            }else if( (c == 0x7F) || (c == 0x08)){
+                /* handle backspace and del keys */
+                pc_serial.printf("\033[1D");
+                pc_serial.putc(' ');
+                pc_serial.printf("\033[1D");
+                
+                read_ptr--;
+                if(read_ptr < 0) read_ptr = 1023;
+                serial_buffer[read_ptr] = ' ';
+
+                
+            } else {
+                /* loopback the pressed key */
+                pc_serial.putc(c);
+                
+                /* store the incoming character on command circular buffer */
+                serial_buffer[read_ptr] = c;
+                read_ptr = (read_ptr + 1) % 1024;
+            }
+            
+            
+            
+            if(new_cmd != false) {
+                /* command arrived, has other characters? */
+                if(read_ptr != 0) {
+                    shell_parser(&serial_buffer[0], read_ptr);
+                } else {
+                    print_usage();
+                }
+                /* reset the buffer command */
+                memset(&serial_buffer, 0, sizeof(serial_buffer));
+                read_ptr = 0;
+                pc_serial.printf(">>");
+            } 
+
+        }        
+    }
+}
+
+void shell_set_command_handler(shell_callback_t sh)
+{
+    shell_handler = sh;
+}
+void shell_set_cmd_list(shell_usage_t sh)
+{
+    shell_usage = sh;
+}
+void shell_start(void)
+{
+    shell_thread.start(shell_task);
+}    
+    
\ No newline at end of file