diff --git a/.cproject b/.cproject
index e426cac..0642420 100755
--- a/.cproject
+++ b/.cproject
@@ -23,22 +23,22 @@
@@ -70,22 +70,22 @@
@@ -117,21 +117,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -343,4 +328,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Makefile b/Makefile
index 1f44a67..eb25766 100755
--- a/Makefile
+++ b/Makefile
@@ -17,8 +17,6 @@ BIN_FILE = $(EXE_DIR)/$(TEST_APP)$(BIN_EXT)
HEX_FILE = $(EXE_DIR)/$(TEST_APP)$(HEX_EXT)
SIZE_FILE = $(SIZE_DIR)/$(TEST_APP)$(SIZE_EXT)
-INCLUDES += $(SRC_DIR)
-
SUB_FOLDER :=
CHECK_FOLDER :=
SOURCES := $(wildcard $(SRC_DIR)/*.c)
diff --git a/config/make/rules.mk b/config/make/rules.mk
index 5e9a8ec..e8a64f6 100755
--- a/config/make/rules.mk
+++ b/config/make/rules.mk
@@ -9,6 +9,11 @@ endif
OS_LIB = kosmos-$(ARCH)-$(BOARD)$(DBG_EXT)
LIBS += $(OS_LIB)
+INCLUDES += \
+ $(SRC_DIR) \
+ $(SRC_DIR)/firmware
+
+
CFLAGS += \
-Wno-unused-function \
-O$(OPTIM) \
diff --git a/source/firmware/kernel/include/shell_commands.h b/source/firmware/kernel/include/shell_commands.h
new file mode 100644
index 0000000..d1b3e75
--- /dev/null
+++ b/source/firmware/kernel/include/shell_commands.h
@@ -0,0 +1,17 @@
+/*
+ * shell_commands.h
+ *
+ * Created on: Aug 11, 2016
+ * Author: tkl
+ */
+
+#ifndef SOURCE_FIRMWARE_KERNEL_INCLUDE_SHELL_COMMANDS_H_
+#define SOURCE_FIRMWARE_KERNEL_INCLUDE_SHELL_COMMANDS_H_
+
+struct command cmd_kosmos_version;
+struct command cmd_list_all_commands;
+struct command cmd_echo_on;
+struct command cmd_echo_off;
+
+
+#endif /* SOURCE_FIRMWARE_KERNEL_INCLUDE_SHELL_COMMANDS_H_ */
diff --git a/source/firmware/kernel/include/shell_data.h b/source/firmware/kernel/include/shell_data.h
new file mode 100644
index 0000000..e8d86a4
--- /dev/null
+++ b/source/firmware/kernel/include/shell_data.h
@@ -0,0 +1,19 @@
+/*
+ * shell_data.h
+ *
+ * Created on: Aug 11, 2016
+ * Author: tkl
+ */
+
+#ifndef SOURCE_FIRMWARE_KERNEL_INCLUDE_SHELL_DATA_H_
+#define SOURCE_FIRMWARE_KERNEL_INCLUDE_SHELL_DATA_H_
+
+struct shell_object {
+ struct list command_list;
+ const struct driver *shell_device;
+ bool echo_on;
+};
+
+struct shell_object shell_object;
+
+#endif /* SOURCE_FIRMWARE_KERNEL_INCLUDE_SHELL_DATA_H_ */
diff --git a/source/firmware/kernel/interface/list.h b/source/firmware/kernel/interface/list.h
index b87e3be..f26b4fe 100644
--- a/source/firmware/kernel/interface/list.h
+++ b/source/firmware/kernel/interface/list.h
@@ -20,5 +20,6 @@ struct list {
int list_init(struct list *head);
int list_add(struct list *head, struct list_node *node);
+int list_get_len(struct list *head);
#endif /* SOURCE_FIRMWARE_KERNEL_LIST_H_ */
diff --git a/source/firmware/kernel/interface/shell.h b/source/firmware/kernel/interface/shell.h
index 81fd032..c242e8d 100644
--- a/source/firmware/kernel/interface/shell.h
+++ b/source/firmware/kernel/interface/shell.h
@@ -12,6 +12,7 @@ typedef void *(*command_callback)(const char*);
struct command {
const char *command;
+ const char *description;
const command_callback command_callback;
struct list_node item;
};
diff --git a/source/firmware/kernel/list.c b/source/firmware/kernel/list.c
index 7e25b4e..8013f35 100644
--- a/source/firmware/kernel/list.c
+++ b/source/firmware/kernel/list.c
@@ -34,3 +34,16 @@ int list_add(struct list *head, struct list_node *node)
}
return 1;
}
+
+int list_get_len(struct list *head)
+{
+ int ret = 0;
+ if(NULL == head)
+ return -1;
+ struct list_node *it = head->front;
+ while(NULL != it) {
+ ret++;
+ it = it->next;
+ }
+ return ret;
+}
diff --git a/source/firmware/kernel/shell.c b/source/firmware/kernel/shell.c
index 3a832da..ba8957c 100644
--- a/source/firmware/kernel/shell.c
+++ b/source/firmware/kernel/shell.c
@@ -14,14 +14,10 @@
#include "driver.h"
#include "kernel.h"
#include "list.h"
+#include "shell_data.h"
#include "shell.h"
+#include "shell_commands.h"
-struct shell_object {
- struct list command_list;
- const struct driver *shell_device;
-};
-
-struct shell_object shell_object;
#define TH_STACK_SIZE 256
stack_t th_stack[TH_STACK_SIZE];
@@ -52,7 +48,17 @@ static void rx_func(void *arg)
ret = read(shell_object.shell_device, &buffer[index],
sizeof(buffer) / sizeof(buffer[0]) - index - 1);
if(ret) {
- write(shell_object.shell_device, &buffer[index], ret); // echo
+ 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
+ }
+ }
if((buffer[index + ret - 1] == '\n') || (buffer[index + ret - 1] == '\r')) {
buffer[index + ret - 1] = '\n';
parse(buffer, index + ret);
@@ -71,6 +77,13 @@ int shell_init(const struct driver *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;
}
diff --git a/source/firmware/kernel/shell_commands.c b/source/firmware/kernel/shell_commands.c
new file mode 100644
index 0000000..4c7683e
--- /dev/null
+++ b/source/firmware/kernel/shell_commands.c
@@ -0,0 +1,91 @@
+/*
+ * shell_commands.c
+ *
+ * Created on: Aug 11, 2016
+ * Author: tkl
+ */
+#include
+#include
+#include
+
+#include "list.h"
+#include "driver.h"
+#include "shell_data.h"
+#include "shell.h"
+#include "version.h"
+#include "shell_commands.h"
+
+static void *cmd_kosmos_version_cb(const char *cmd);
+static void *cmd_list_all_commands_cb(const char *cmd);
+static void *cmd_echo_on_cb(const char *cmd);
+static void *cmd_echo_off_cb(const char *cmd);
+
+struct command cmd_kosmos_version = {
+ .command = "uname",
+ .description = "Print current kosmos version.",
+ .command_callback = cmd_kosmos_version_cb
+};
+
+struct command cmd_list_all_commands = {
+ .command = "ls",
+ .description = "List all installed commands.",
+ .command_callback = cmd_list_all_commands_cb
+};
+
+struct command cmd_echo_on = {
+ .command = "echo on",
+ .description = "Switch echo on.",
+ .command_callback = cmd_echo_on_cb
+};
+
+struct command cmd_echo_off = {
+ .command = "echo off",
+ .description = "Switch echo off.",
+ .command_callback = cmd_echo_off_cb
+};
+
+
+static void *cmd_kosmos_version_cb(const char *cmd)
+{
+ char *greeter = "Kosmos Version: ";
+
+ write(shell_object.shell_device, greeter, strlen(greeter));
+ write(shell_object.shell_device, KERNEL_VERSION, strlen(KERNEL_VERSION));
+ write(shell_object.shell_device, ".", 1);
+ write(shell_object.shell_device, MAJOR_VERSION, strlen(MAJOR_VERSION));
+ write(shell_object.shell_device, ".", 1);
+ write(shell_object.shell_device, MINOR_VERSION, strlen(MINOR_VERSION));
+ return NULL;
+}
+
+static void *cmd_list_all_commands_cb(const char *cmd)
+{
+ char *greeter = "Command list: \r\n";
+ struct list_node *it = shell_object.command_list.front;
+ int i, len = list_get_len(&shell_object.command_list);
+
+ write(shell_object.shell_device, greeter, strlen(greeter));
+ for(i = 0; i < (len - 1); i++) {
+ if(NULL != it) {
+ struct command *cmd = (struct command *)it->data;
+ write(shell_object.shell_device, cmd->command, strlen(cmd->command));
+ write(shell_object.shell_device, " - ", 3);
+ write(shell_object.shell_device, cmd->description, strlen(cmd->description));
+ write(shell_object.shell_device, "\r\n", 2);
+ it = it->next;
+ }
+ }
+
+ return NULL;
+}
+
+static void *cmd_echo_on_cb(const char *cmd)
+{
+ shell_object.echo_on = true;
+ return NULL;
+}
+static void *cmd_echo_off_cb(const char *cmd)
+{
+ shell_object.echo_on = false;
+ return NULL;
+}