2016-08-01 14:53:06 +00:00
|
|
|
/*
|
|
|
|
* shell.c
|
|
|
|
*
|
|
|
|
* Created on: Aug 1, 2016
|
|
|
|
* Author: tkl
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdbool.h>
|
2016-08-02 09:41:47 +00:00
|
|
|
#include <string.h>
|
2016-08-01 14:53:06 +00:00
|
|
|
|
|
|
|
#include "stack.h"
|
|
|
|
#include "queue.h"
|
|
|
|
#include "driver.h"
|
|
|
|
#include "kernel.h"
|
2016-08-02 09:41:47 +00:00
|
|
|
#include "list.h"
|
2016-08-11 09:04:54 +00:00
|
|
|
#include "shell_data.h"
|
2016-08-02 09:41:47 +00:00
|
|
|
#include "shell.h"
|
2016-08-11 09:04:54 +00:00
|
|
|
#include "shell_commands.h"
|
2016-08-02 09:41:47 +00:00
|
|
|
|
2016-08-01 14:53:06 +00:00
|
|
|
|
2016-08-08 09:19:08 +00:00
|
|
|
#define TH_STACK_SIZE 256
|
|
|
|
stack_t th_stack[TH_STACK_SIZE];
|
|
|
|
struct thread_context th_ctx;
|
2016-08-01 14:53:06 +00:00
|
|
|
|
2016-08-02 09:41:47 +00:00
|
|
|
static void parse(const char *buffer, unsigned int len)
|
2016-08-01 14:53:06 +00:00
|
|
|
{
|
2016-08-02 09:41:47 +00:00
|
|
|
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;
|
|
|
|
}
|
2016-08-01 14:53:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-02 09:41:47 +00:00
|
|
|
static void rx_func(void *arg)
|
|
|
|
{
|
2016-08-02 12:23:59 +00:00
|
|
|
char buffer[81];
|
2016-08-02 09:41:47 +00:00
|
|
|
unsigned int index = 0;
|
|
|
|
int ret = 0;
|
|
|
|
open(shell_object.shell_device);
|
|
|
|
while(1) {
|
|
|
|
ret = read(shell_object.shell_device, &buffer[index],
|
2016-08-02 12:23:59 +00:00
|
|
|
sizeof(buffer) / sizeof(buffer[0]) - index - 1);
|
2016-08-02 09:41:47 +00:00
|
|
|
if(ret) {
|
2016-08-11 09:04:54 +00:00
|
|
|
if(shell_object.echo_on) {
|
|
|
|
if((buffer[index + ret - 1] == '\n') && (buffer[index + ret -2] != '\r')) {
|
|
|
|
write(shell_object.shell_device, "\r\n", 2);
|
|
|
|
}
|
|
|
|
else if((buffer[index + ret - 1] == '\r') && (buffer[index + ret -2] != '\n')) {
|
|
|
|
write(shell_object.shell_device, "\r\n", 2);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
write(shell_object.shell_device, &buffer[index], ret); // echo
|
|
|
|
}
|
|
|
|
}
|
2016-08-02 12:10:11 +00:00
|
|
|
if((buffer[index + ret - 1] == '\n') || (buffer[index + ret - 1] == '\r')) {
|
|
|
|
buffer[index + ret - 1] = '\n';
|
2016-08-02 09:41:47 +00:00
|
|
|
parse(buffer, index + ret);
|
2016-08-02 12:23:59 +00:00
|
|
|
buffer[index + ret] = '\0';
|
2016-08-02 09:41:47 +00:00
|
|
|
index = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
index += ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-08-01 14:53:06 +00:00
|
|
|
|
|
|
|
int shell_init(const struct driver *shell_device)
|
|
|
|
{
|
2016-08-02 09:41:47 +00:00
|
|
|
if(NULL == shell_device)
|
|
|
|
return -1;
|
|
|
|
list_init(&shell_object.command_list);
|
|
|
|
shell_object.shell_device = shell_device;
|
2016-08-11 09:04:54 +00:00
|
|
|
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);
|
|
|
|
|
2016-08-08 09:19:08 +00:00
|
|
|
thread_create(&th_ctx, th_stack, TH_STACK_SIZE, rx_func, NULL, THREAD_PRIO_LOW);
|
2016-08-02 09:41:47 +00:00
|
|
|
return 0;
|
2016-08-01 14:53:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-02 09:41:47 +00:00
|
|
|
int shell_add_command(struct command *command)
|
2016-08-01 14:53:06 +00:00
|
|
|
{
|
2016-08-02 09:41:47 +00:00
|
|
|
if(NULL == command)
|
|
|
|
return -1;
|
|
|
|
command->item.data = (unsigned int) command;
|
|
|
|
list_add(&shell_object.command_list, &command->item);
|
|
|
|
return 1;
|
2016-08-01 14:53:06 +00:00
|
|
|
}
|