aboutsummaryrefslogtreecommitdiff
path: root/kernel
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 /kernel
parent7dd00b2267d991a102f18eacf3e2afacb570a299 (diff)
downloadmux-c4da3559760351467f421a234d4240ef6670f396.tar.gz
mux-c4da3559760351467f421a234d4240ef6670f396.tar.bz2
mux-c4da3559760351467f421a234d4240ef6670f396.zip
implement stdio and add mini shell
Diffstat (limited to 'kernel')
-rw-r--r--kernel/serial/include/serial/serial.h9
-rw-r--r--kernel/serial/serial.c51
2 files changed, 45 insertions, 15 deletions
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();