aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Odersky <jodersky@gmail.com>2014-01-26 16:41:50 +0100
committerJakob Odersky <jodersky@gmail.com>2014-01-26 16:41:50 +0100
commitc4da3559760351467f421a234d4240ef6670f396 (patch)
treed19f2fbb3891744f9741d044a65cf220221bc4a8
parent7dd00b2267d991a102f18eacf3e2afacb570a299 (diff)
downloadmux-c4da3559760351467f421a234d4240ef6670f396.tar.gz
mux-c4da3559760351467f421a234d4240ef6670f396.tar.bz2
mux-c4da3559760351467f421a234d4240ef6670f396.zip
implement stdio and add mini shell
-rw-r--r--Makefile1
-rw-r--r--kernel/serial/include/serial/serial.h9
-rw-r--r--kernel/serial/serial.c51
-rw-r--r--main.c19
-rw-r--r--shell.c41
-rw-r--r--shell.h8
6 files changed, 106 insertions, 23 deletions
diff --git a/Makefile b/Makefile
index 55c4b27..1d20a43 100644
--- a/Makefile
+++ b/Makefile
@@ -95,6 +95,7 @@ monitor:
cycle:
@make clean && \
make > /dev/null && \
+ make size && \
read -p "Press enter to proceed with upload..." nothing && \
make upload
diff --git a/kernel/serial/include/serial/serial.h b/kernel/serial/include/serial/serial.h
index f6fcfc5..49ac63c 100644
--- a/kernel/serial/include/serial/serial.h
+++ b/kernel/serial/include/serial/serial.h
@@ -2,6 +2,8 @@
#define SERIAL_H
#include <stddef.h>
+#include <stdio.h>
+
#include "collection/rbuffer.h"
#include "collection/list.h"
@@ -39,4 +41,11 @@ inline void serial_write_str(const char* const str) {
serial_write(str, length);
}
+int serial_getc();
+
+int serial_putc(char c);
+
+extern FILE serial_in;
+extern FILE serial_out;
+
#endif \ No newline at end of file
diff --git a/kernel/serial/serial.c b/kernel/serial/serial.c
index 6e88cd6..e7d52a7 100644
--- a/kernel/serial/serial.c
+++ b/kernel/serial/serial.c
@@ -3,6 +3,9 @@
#include "sched/sched.h"
#include "bug/debug.h"
+ FILE serial_out = FDEV_SETUP_STREAM(serial_putc, NULL, _FDEV_SETUP_WRITE);
+ FILE serial_in = FDEV_SETUP_STREAM(NULL, serial_getc, _FDEV_SETUP_READ);
+
static struct serial_device_t serial = SERIAL_DEVICE_INIT(serial);
void serial_init(unsigned long baud) {
@@ -14,25 +17,51 @@ void serial_init(unsigned long baud) {
UCSR0B &= ~(1 << UDRIE0);
}
-static inline int rbuffer_empty_safe(struct rbuffer_t* const rb) {
+size_t serial_read(char* const data, size_t size) {
+ while (rbuffer_empty(&serial.rx_buffer)) {
+ cli();
+ sleep_on(&serial.rx_q);
+ yield();
+ }
cli();
- int r = rbuffer_empty(rb);
+ size_t r = rbuffer_read(&serial.rx_buffer, data, size);
sei();
return r;
}
-size_t serial_read(char* const data, size_t size) {
- while (rbuffer_empty_safe(&serial.rx_buffer)) {
+size_t serial_write(const char* const data, size_t size) {
+ cli();
+ size_t r = rbuffer_write(&serial.tx_buffer, data, size);
+ sei();
+ UCSR0B |= (1 << UDRIE0);
+ return r;
+}
+
+int serial_getc() {
+ while (rbuffer_empty(&serial.rx_buffer)) {
cli();
sleep_on(&serial.rx_q);
yield();
}
cli();
- size_t r = rbuffer_read(&serial.rx_buffer, data, size);
+ char c = 0;
+ size_t r = rbuffer_read_char(&serial.rx_buffer, &c);
sei();
- return r;
+ if (r) return (int) c;
+ else return EOF;
}
+int serial_putc(char c) {
+ if (c == '\n') serial_putc('\r');
+ int r = 0;
+ do {
+ cli();
+ r = rbuffer_write_char(&serial.tx_buffer, c);
+ sei();
+ UCSR0B |= (1 << UDRIE0);
+ } while (r != 1);
+ return c;
+}
//called when byte is received
ISR(USART0_RX_vect, ISR_NAKED) {
@@ -44,15 +73,6 @@ ISR(USART0_RX_vect, ISR_NAKED) {
asm volatile ("reti");
}
-
-size_t serial_write(const char* const data, size_t size) {
- cli();
- size_t r = rbuffer_write(&serial.tx_buffer, data, size);
- sei();
- UCSR0B |= (1 << UDRIE0);
- return r;
-}
-
//called when data register is empty
ISR(USART0_UDRE_vect) {
char c;
@@ -62,6 +82,7 @@ ISR(USART0_UDRE_vect) {
UCSR0B &= ~(1 << UDRIE0); //buffer empty, disable interruot
}
}
+
/*
void serial_read() {
ENTER_CRITICAL();
diff --git a/main.c b/main.c
index da6f978..a2c8827 100644
--- a/main.c
+++ b/main.c
@@ -1,4 +1,6 @@
#include <stddef.h>
+#include <stdio.h>
+#include <avr/pgmspace.h>
#include <sched/sched.h>
#include <time/timer.h>
#include <bug/panic.h>
@@ -6,6 +8,7 @@
#include <tshield/tshield.h>
#include <collection/list.h>
#include <serial/serial.h>
+#include "shell.h"
#define WAIT_CYCLES(cycles) for (volatile unsigned long i = 0; i < cycles; ++i) {}
@@ -35,20 +38,20 @@ void wake() {
void blink( char id) {
while(1) {
debug_led(id,1);
- sleep(500);
+ sleep(id * 300);
debug_led(id,0);
- sleep(500);
+ sleep(id * 300);
}
}
-#define READ_BUFFER_SIZE 24
+
+
+#define READ_BUFFER_SIZE 64
void read(char id) {
serial_init(115200);
- char data[READ_BUFFER_SIZE];
- while(1) {
- size_t length = serial_read(data, READ_BUFFER_SIZE);
- serial_write(data, length);
- }
+ stdout = &serial_out;
+ stdin = &serial_in;
+ shell();
}
DECLARE_TASK(task1, STACK_SIZE, blink);
diff --git a/shell.c b/shell.c
new file mode 100644
index 0000000..dc8d10d
--- /dev/null
+++ b/shell.c
@@ -0,0 +1,41 @@
+#include "shell.h"
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+#include "tshield/tshield.h"
+
+#define MAX_ARGS 5
+#define IN_LENGTH 80
+
+static int process_command(int argc, char **argv);
+
+void shell() {
+ char in[IN_LENGTH];
+ int argc;
+ char *argv[MAX_ARGS];
+
+ while(1) {
+ printf ("root@arduino$ ");
+
+ fgets(in, IN_LENGTH, stdin);
+
+ argc = 0;
+ char *p = strtok (in," \n\r");
+ while (p != NULL && argc < MAX_ARGS) {
+ argv[argc] = p;
+ argc += 1;
+ p = strtok(NULL, " \n\r");
+ }
+ printf("%d\n", process_command(argc, argv));
+ }
+}
+
+static int process_command(int argc, char **argv) {
+ if (argc < 1) return -1;
+
+ if (strcmp(argv[0], "led") == 0) {
+ return 0;
+ }
+
+ return -1;
+} \ No newline at end of file
diff --git a/shell.h b/shell.h
new file mode 100644
index 0000000..346beae
--- /dev/null
+++ b/shell.h
@@ -0,0 +1,8 @@
+#ifndef COMMAND_H
+#define COMMAND_H
+
+#define SHELL_BAUD 115200
+
+void shell();
+
+#endif \ No newline at end of file