kosmos/source/firmware/kernel/shell.c
2016-09-16 20:58:31 +02:00

106 lines
2.4 KiB
C

/*
* shell.c
*
* Created on: Aug 1, 2016
* Author: tkl
*/
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#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(0 == strncmp(buffer, cmd->command, strlen(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;
}
int shell_write(const char *buffer, unsigned int len)
{
if((NULL == buffer) || (NULL == shell_object.shell_device))
return -1;
return drv_write(shell_object.shell_device, buffer, len);
}