/* * shell.c * * Created on: Aug 1, 2016 * Author: tkl */ #include #include #include #include "stack.h" #include "queue.h" #include "driver.h" #include "kernel.h" #include "list.h" #include "shell_data.h" #include "shell.h" #include "shell_commands.h" #define TH_STACK_SIZE 256 stack_t th_stack[TH_STACK_SIZE]; struct thread_context th_ctx; static void parse(const char *buffer, unsigned int len) { if(NULL == buffer) return; struct list_node *it = shell_object.command_list.front; while(it != NULL) { struct command *cmd = (struct command *)it->data; if(strstr(buffer, cmd->command)) { cmd->command_callback(buffer); return; } it = it->next; } } static void rx_func(void *arg) { char buffer[81]; unsigned int index = 0; int ret = 0; drv_open(shell_object.shell_device); while(1) { ret = drv_read(shell_object.shell_device, &buffer[index], sizeof(buffer) / sizeof(buffer[0]) - index - 1); if(ret) { if(shell_object.echo_on) { if((buffer[index + ret - 1] == '\n') && (buffer[index + ret -2] != '\r')) { drv_write(shell_object.shell_device, "\r\n", 2); } else if((buffer[index + ret - 1] == '\r') && (buffer[index + ret -2] != '\n')) { drv_write(shell_object.shell_device, "\r\n", 2); } else { drv_write(shell_object.shell_device, &buffer[index], ret); // echo } } if((buffer[index + ret - 1] == '\n') || (buffer[index + ret - 1] == '\r')) { buffer[index + ret - 1] = '\n'; parse(buffer, index + ret); buffer[index + ret] = '\0'; index = 0; } else index += ret; } } } int shell_init(const struct driver *shell_device) { if(NULL == shell_device) return -1; list_init(&shell_object.command_list); shell_object.shell_device = shell_device; shell_object.echo_on = true; shell_add_command(&cmd_kosmos_version); shell_add_command(&cmd_list_all_commands); shell_add_command(&cmd_echo_on); shell_add_command(&cmd_echo_off); thread_create(&th_ctx, th_stack, TH_STACK_SIZE, rx_func, NULL, THREAD_PRIO_LOW); return 0; } int shell_add_command(struct command *command) { if(NULL == command) return -1; command->item.data = (unsigned int) command; list_add(&shell_object.command_list, &command->item); return 1; }