TEN MBED OS Course shell utility

Committer:
uLipe
Date:
Sun Jan 29 20:57:17 2017 +0000
Revision:
0:1e8461adc480
first;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
uLipe 0:1e8461adc480 1 /**
uLipe 0:1e8461adc480 2 * @brief our first hello world threaded program with MBED OS
uLipe 0:1e8461adc480 3 */
uLipe 0:1e8461adc480 4 #include "mbed.h"
uLipe 0:1e8461adc480 5 #include "rtos.h"
uLipe 0:1e8461adc480 6 #include "shell.h"
uLipe 0:1e8461adc480 7
uLipe 0:1e8461adc480 8 /* declare a thread reserved only for shell command handler */
uLipe 0:1e8461adc480 9 const size_t shell_stk_size = 8192;
uLipe 0:1e8461adc480 10 uint8_t shell_stk[shell_stk_size];
uLipe 0:1e8461adc480 11 Thread shell_thread(osPriorityNormal, shell_stk_size, &shell_stk[0]);
uLipe 0:1e8461adc480 12
uLipe 0:1e8461adc480 13 /* reserve the debbuger uart to shell interface */
uLipe 0:1e8461adc480 14 Serial pc_serial(SHELL_TXD,SHELL_RXD);
uLipe 0:1e8461adc480 15
uLipe 0:1e8461adc480 16 static shell_callback_t shell_handler = NULL;
uLipe 0:1e8461adc480 17 static shell_usage_t shell_usage;
uLipe 0:1e8461adc480 18 static int argc = 0;
uLipe 0:1e8461adc480 19 static char *argv[16];
uLipe 0:1e8461adc480 20
uLipe 0:1e8461adc480 21 /**
uLipe 0:1e8461adc480 22 * @brief show help menu
uLipe 0:1e8461adc480 23 */
uLipe 0:1e8461adc480 24 static void print_usage(void)
uLipe 0:1e8461adc480 25 {
uLipe 0:1e8461adc480 26 pc_serial.printf("## use with the syntax below: \n\r");
uLipe 0:1e8461adc480 27 pc_serial.printf("## command <arg1> <arg2> ... <arg16> \n\r");
uLipe 0:1e8461adc480 28 pc_serial.printf("## Available commands: \n\r");
uLipe 0:1e8461adc480 29 if(shell_usage != NULL) {
uLipe 0:1e8461adc480 30 shell_usage((void *)&pc_serial);
uLipe 0:1e8461adc480 31 }
uLipe 0:1e8461adc480 32 }
uLipe 0:1e8461adc480 33
uLipe 0:1e8461adc480 34
uLipe 0:1e8461adc480 35 /**
uLipe 0:1e8461adc480 36 * @brief parse the command received via comport
uLipe 0:1e8461adc480 37 */
uLipe 0:1e8461adc480 38 static void shell_parser (char *cmd, int size)
uLipe 0:1e8461adc480 39 {
uLipe 0:1e8461adc480 40 int cmd_ptr = 0;
uLipe 0:1e8461adc480 41 int arg_ptr = 0;
uLipe 0:1e8461adc480 42 int cmd_size = 0;
uLipe 0:1e8461adc480 43 char command_buffer[256];
uLipe 0:1e8461adc480 44
uLipe 0:1e8461adc480 45
uLipe 0:1e8461adc480 46 /* copy to the root command */
uLipe 0:1e8461adc480 47 memset(&command_buffer, 0, sizeof(command_buffer));
uLipe 0:1e8461adc480 48
uLipe 0:1e8461adc480 49 /* find the root command terminator (space) */
uLipe 0:1e8461adc480 50 while(cmd_ptr < size) {
uLipe 0:1e8461adc480 51 if(cmd[cmd_ptr] == ' ') break;
uLipe 0:1e8461adc480 52 cmd_ptr++;
uLipe 0:1e8461adc480 53 }
uLipe 0:1e8461adc480 54 cmd_size = size - cmd_ptr;
uLipe 0:1e8461adc480 55
uLipe 0:1e8461adc480 56
uLipe 0:1e8461adc480 57 /* extract command arguments */
uLipe 0:1e8461adc480 58 strncpy(&command_buffer[0], &cmd[cmd_ptr + 1], (size - cmd_ptr));
uLipe 0:1e8461adc480 59
uLipe 0:1e8461adc480 60 /* terminates the root command */
uLipe 0:1e8461adc480 61 cmd[cmd_ptr] = 0;
uLipe 0:1e8461adc480 62 arg_ptr = 0;
uLipe 0:1e8461adc480 63
uLipe 0:1e8461adc480 64 //pc_serial.printf("## command: %s \n\r", cmd);
uLipe 0:1e8461adc480 65 //pc_serial.printf("## arguments: %s \n\r", command_buffer);
uLipe 0:1e8461adc480 66
uLipe 0:1e8461adc480 67
uLipe 0:1e8461adc480 68 /* extract the further arguments */
uLipe 0:1e8461adc480 69 while(arg_ptr < (cmd_size)) {
uLipe 0:1e8461adc480 70
uLipe 0:1e8461adc480 71 argc++;
uLipe 0:1e8461adc480 72 *(argv + (argc- 1)) = &command_buffer[arg_ptr];
uLipe 0:1e8461adc480 73
uLipe 0:1e8461adc480 74 /* find terminator */
uLipe 0:1e8461adc480 75 while(command_buffer[arg_ptr] != ' ') {
uLipe 0:1e8461adc480 76 arg_ptr++;
uLipe 0:1e8461adc480 77 }
uLipe 0:1e8461adc480 78
uLipe 0:1e8461adc480 79 /* adds to argument list */
uLipe 0:1e8461adc480 80 command_buffer[arg_ptr] = 0;
uLipe 0:1e8461adc480 81 arg_ptr++;
uLipe 0:1e8461adc480 82 // pc_serial.printf("## argument no: %d : %s \n\r", argc, argv[argc-1]);
uLipe 0:1e8461adc480 83 }
uLipe 0:1e8461adc480 84
uLipe 0:1e8461adc480 85
uLipe 0:1e8461adc480 86
uLipe 0:1e8461adc480 87 /* finds and execute the command table */
uLipe 0:1e8461adc480 88 if(shell_handler != NULL){
uLipe 0:1e8461adc480 89
uLipe 0:1e8461adc480 90 int ret = shell_handler(cmd, argc, argv, (void *)&pc_serial);
uLipe 0:1e8461adc480 91 if(ret < 0) {
uLipe 0:1e8461adc480 92 print_usage();
uLipe 0:1e8461adc480 93 }
uLipe 0:1e8461adc480 94 }else {
uLipe 0:1e8461adc480 95 print_usage();
uLipe 0:1e8461adc480 96 }
uLipe 0:1e8461adc480 97 }
uLipe 0:1e8461adc480 98
uLipe 0:1e8461adc480 99
uLipe 0:1e8461adc480 100
uLipe 0:1e8461adc480 101
uLipe 0:1e8461adc480 102 /**
uLipe 0:1e8461adc480 103 * @brief shell commands processing thread
uLipe 0:1e8461adc480 104 */
uLipe 0:1e8461adc480 105 static void shell_task(void)
uLipe 0:1e8461adc480 106 {
uLipe 0:1e8461adc480 107 char serial_buffer[1024] = {0};
uLipe 0:1e8461adc480 108 int read_ptr = 0;
uLipe 0:1e8461adc480 109
uLipe 0:1e8461adc480 110 /* setup the serial as 115200 bps */
uLipe 0:1e8461adc480 111 pc_serial.baud(115200);
uLipe 0:1e8461adc480 112
uLipe 0:1e8461adc480 113 /* prints a welcome message */
uLipe 0:1e8461adc480 114
uLipe 0:1e8461adc480 115 pc_serial.printf("******************************************************************\n\r");
uLipe 0:1e8461adc480 116 pc_serial.printf("*** Welcome to MbedOS Simple Shell application ****\n\r");
uLipe 0:1e8461adc480 117 pc_serial.printf("*** Type some commands or just Enter key to see the available ****\n\r");
uLipe 0:1e8461adc480 118 pc_serial.printf("******************************************************************\n\r");
uLipe 0:1e8461adc480 119 pc_serial.printf(">>");
uLipe 0:1e8461adc480 120
uLipe 0:1e8461adc480 121 for(;;Thread::wait(50)) {
uLipe 0:1e8461adc480 122 /* check if we have character available */
uLipe 0:1e8461adc480 123 if(pc_serial.readable()) {
uLipe 0:1e8461adc480 124 bool new_cmd = false;
uLipe 0:1e8461adc480 125
uLipe 0:1e8461adc480 126 /* get the incoming character */
uLipe 0:1e8461adc480 127 char c = pc_serial.getc();
uLipe 0:1e8461adc480 128
uLipe 0:1e8461adc480 129 if( (c == '\n') || (c == '\r')) {
uLipe 0:1e8461adc480 130 /* handle enter key */
uLipe 0:1e8461adc480 131 new_cmd = true;
uLipe 0:1e8461adc480 132 pc_serial.printf("\n\r");
uLipe 0:1e8461adc480 133
uLipe 0:1e8461adc480 134 }else if( (c == 0x7F) || (c == 0x08)){
uLipe 0:1e8461adc480 135 /* handle backspace and del keys */
uLipe 0:1e8461adc480 136 pc_serial.printf("\033[1D");
uLipe 0:1e8461adc480 137 pc_serial.putc(' ');
uLipe 0:1e8461adc480 138 pc_serial.printf("\033[1D");
uLipe 0:1e8461adc480 139
uLipe 0:1e8461adc480 140 read_ptr--;
uLipe 0:1e8461adc480 141 if(read_ptr < 0) read_ptr = 1023;
uLipe 0:1e8461adc480 142 serial_buffer[read_ptr] = ' ';
uLipe 0:1e8461adc480 143
uLipe 0:1e8461adc480 144
uLipe 0:1e8461adc480 145 } else {
uLipe 0:1e8461adc480 146 /* loopback the pressed key */
uLipe 0:1e8461adc480 147 pc_serial.putc(c);
uLipe 0:1e8461adc480 148
uLipe 0:1e8461adc480 149 /* store the incoming character on command circular buffer */
uLipe 0:1e8461adc480 150 serial_buffer[read_ptr] = c;
uLipe 0:1e8461adc480 151 read_ptr = (read_ptr + 1) % 1024;
uLipe 0:1e8461adc480 152 }
uLipe 0:1e8461adc480 153
uLipe 0:1e8461adc480 154
uLipe 0:1e8461adc480 155
uLipe 0:1e8461adc480 156 if(new_cmd != false) {
uLipe 0:1e8461adc480 157 /* command arrived, has other characters? */
uLipe 0:1e8461adc480 158 if(read_ptr != 0) {
uLipe 0:1e8461adc480 159 shell_parser(&serial_buffer[0], read_ptr);
uLipe 0:1e8461adc480 160 } else {
uLipe 0:1e8461adc480 161 print_usage();
uLipe 0:1e8461adc480 162 }
uLipe 0:1e8461adc480 163 /* reset the buffer command */
uLipe 0:1e8461adc480 164 memset(&serial_buffer, 0, sizeof(serial_buffer));
uLipe 0:1e8461adc480 165 read_ptr = 0;
uLipe 0:1e8461adc480 166 pc_serial.printf(">>");
uLipe 0:1e8461adc480 167 }
uLipe 0:1e8461adc480 168
uLipe 0:1e8461adc480 169 }
uLipe 0:1e8461adc480 170 }
uLipe 0:1e8461adc480 171 }
uLipe 0:1e8461adc480 172
uLipe 0:1e8461adc480 173 void shell_set_command_handler(shell_callback_t sh)
uLipe 0:1e8461adc480 174 {
uLipe 0:1e8461adc480 175 shell_handler = sh;
uLipe 0:1e8461adc480 176 }
uLipe 0:1e8461adc480 177 void shell_set_cmd_list(shell_usage_t sh)
uLipe 0:1e8461adc480 178 {
uLipe 0:1e8461adc480 179 shell_usage = sh;
uLipe 0:1e8461adc480 180 }
uLipe 0:1e8461adc480 181 void shell_start(void)
uLipe 0:1e8461adc480 182 {
uLipe 0:1e8461adc480 183 shell_thread.start(shell_task);
uLipe 0:1e8461adc480 184 }
uLipe 0:1e8461adc480 185