Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
shell.cpp
- Committer:
- uLipe
- Date:
- 2017-01-29
- Revision:
- 0:1e8461adc480
File content as of revision 0:1e8461adc480:
/**
* @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);
}