From c4da3559760351467f421a234d4240ef6670f396 Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Sun, 26 Jan 2014 16:41:50 +0100 Subject: implement stdio and add mini shell --- Makefile | 1 + kernel/serial/include/serial/serial.h | 9 +++++++ kernel/serial/serial.c | 51 ++++++++++++++++++++++++----------- main.c | 19 +++++++------ shell.c | 41 ++++++++++++++++++++++++++++ shell.h | 8 ++++++ 6 files changed, 106 insertions(+), 23 deletions(-) create mode 100644 shell.c create mode 100644 shell.h 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 +#include + #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 +#include +#include #include #include