summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2017-12-08 15:07:52 +0100
committerDaniel Friesel <derf@finalrewind.org>2017-12-08 15:07:52 +0100
commitdcf84169ae75b11c1656d45dbc6c626d93da6a10 (patch)
treed78ad84e6aba1f5f13037e40141013f3a3061d54
parent56f2d90751f1c1b2db925da215a14721cf18d483 (diff)
Add output support (broken on esp8266)
-rw-r--r--Makefile4
-rw-r--r--include/esp8266/driver/stdout.h20
-rw-r--r--include/msp430fr5969lp/driver/stdout.h19
-rw-r--r--include/object/outputstream.h65
-rw-r--r--include/posix/driver/stdout.h20
-rw-r--r--src/arch/esp8266/Makefile.inc5
-rw-r--r--src/arch/esp8266/arch.cc5
-rw-r--r--src/arch/esp8266/driver/stdout.cc25
-rw-r--r--src/arch/msp430fr5969lp/Makefile.inc1
-rw-r--r--src/arch/msp430fr5969lp/driver/stdout.cc33
-rw-r--r--src/arch/posix/Makefile.inc1
-rw-r--r--src/arch/posix/driver/stdout.cc14
-rw-r--r--src/os/main.cc5
-rw-r--r--src/os/object/cpp_helpers.cc4
-rw-r--r--src/os/object/outputstream.cc191
15 files changed, 409 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index 656686a..849411d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,11 @@
default: build/system.elf
INCLUDES = -Iinclude
-COMMON_FLAGS = -g -Os -Wall -Wextra -unused
+COMMON_FLAGS = -g -Os -Wall -Wextra -unused -fno-rtti
CFLAGS = -std=c99
CXXFLAGS = -std=c++14
-TARGETS = src/os/main.cc
+TARGETS = src/os/main.cc src/os/object/cpp_helpers.cc src/os/object/outputstream.cc
ifeq (${arduino}, 1)
COMMON_FLAGS += -DWITH_LOOP
diff --git a/include/esp8266/driver/stdout.h b/include/esp8266/driver/stdout.h
new file mode 100644
index 0000000..9114501
--- /dev/null
+++ b/include/esp8266/driver/stdout.h
@@ -0,0 +1,20 @@
+#ifndef STANDARDOUTPUT_H
+#define STANDANDOUTPUT_H
+
+#include "object/outputstream.h"
+
+class StandardOutput : public OutputStream {
+ private:
+ StandardOutput(const StandardOutput &copy);
+
+ public:
+ StandardOutput () {}
+ void setup();
+
+ virtual void put(char c) override;
+ virtual void write(const char *s) override;
+};
+
+extern StandardOutput kout;
+
+#endif
diff --git a/include/msp430fr5969lp/driver/stdout.h b/include/msp430fr5969lp/driver/stdout.h
new file mode 100644
index 0000000..d6cb2b0
--- /dev/null
+++ b/include/msp430fr5969lp/driver/stdout.h
@@ -0,0 +1,19 @@
+#ifndef STANDARDOUTPUT_H
+#define STANDANDOUTPUT_H
+
+#include "object/outputstream.h"
+
+class StandardOutput : public OutputStream {
+ private:
+ StandardOutput(const StandardOutput &copy);
+
+ public:
+ StandardOutput () {}
+ void setup();
+
+ virtual void put(char c) override;
+};
+
+extern StandardOutput kout;
+
+#endif
diff --git a/include/object/outputstream.h b/include/object/outputstream.h
new file mode 100644
index 0000000..43e61f3
--- /dev/null
+++ b/include/object/outputstream.h
@@ -0,0 +1,65 @@
+#ifndef OUTPUTSTREAM_H
+#define OUTPUTSTREAM_H
+
+#include <stdint.h>
+
+class OutputStream {
+ private:
+ OutputStream(const OutputStream& copy);
+
+ char digit_buffer[sizeof(long long) * 8];
+ uint8_t base;
+
+ public:
+ OutputStream();
+
+ virtual void put(char c) = 0;
+
+ virtual void write(const char *s) {
+ while (*s) {
+ put(*s++);
+ }
+ }
+
+ virtual void flush() {}
+
+ OutputStream & operator<<(char c);
+ OutputStream & operator<<(unsigned char c);
+ OutputStream & operator<<(unsigned short number);
+ OutputStream & operator<<(short number);
+ OutputStream & operator<<(unsigned int number);
+ OutputStream & operator<<(int number);
+ OutputStream & operator<<(unsigned long number);
+ OutputStream & operator<<(long number);
+ OutputStream & operator<<(unsigned long long number);
+ OutputStream & operator<<(long long number);
+ OutputStream & operator<<(void *pointer);
+ OutputStream & operator<<(const char *text);
+ OutputStream & operator<<(OutputStream & (*fun) (OutputStream &));
+
+ void setBase(uint8_t b);
+};
+
+
+// ENDL: new line character (and flush)
+OutputStream & endl(OutputStream & os);
+
+// BIN: print numbers in binary form.
+OutputStream & bin(OutputStream & os);
+
+// OCT: print numbers in octal form.
+OutputStream & oct(OutputStream & os);
+
+// DEC: print numbers in decimal form.
+OutputStream & dec(OutputStream & os);
+
+// HEX: print numbers in hexadecimal form.
+OutputStream & hex(OutputStream & os);
+
+// FLUSH: flush OutputStream buffer
+OutputStream & flush(OutputStream & os);
+
+// TERM: zero-termination
+OutputStream & term(OutputStream & os);
+
+#endif //OUTPUTSTREAM_H
diff --git a/include/posix/driver/stdout.h b/include/posix/driver/stdout.h
new file mode 100644
index 0000000..cf8d881
--- /dev/null
+++ b/include/posix/driver/stdout.h
@@ -0,0 +1,20 @@
+#ifndef STANDARDOUTPUT_H
+#define STANDANDOUTPUT_H
+
+#include "object/outputstream.h"
+
+class StandardOutput : public OutputStream {
+ private:
+ StandardOutput(const StandardOutput &copy);
+
+ public:
+ StandardOutput () {}
+ void setup() {}
+
+ virtual void put(char c) override;
+ virtual void flush() override;
+};
+
+extern StandardOutput kout;
+
+#endif
diff --git a/src/arch/esp8266/Makefile.inc b/src/arch/esp8266/Makefile.inc
index b0fc4ce..9a08678 100644
--- a/src/arch/esp8266/Makefile.inc
+++ b/src/arch/esp8266/Makefile.inc
@@ -9,6 +9,7 @@ CC = ${TOOLCHAIN_BASE}/xtensa-lx106-elf-gcc
CXX = ${TOOLCHAIN_BASE}/xtensa-lx106-elf-g++
AR = ${TOOLCHAIN_BASE}/xtensa-lx106-elf-ar
LD = ${TOOLCHAIN_BASE}/xtensa-lx106-elf-gcc
+OBJCOPY = ${TOOLCHAIN_BASE}/xtensa-lx106-elf-objcopy
INCLUDES += -Iinclude/esp8266 -I${SDK_BASE}/include
COMMON_FLAGS += -nostdlib -mlongcalls -D__ets__ -DICACHE_FLASH
@@ -16,17 +17,19 @@ CXXFLAGS = -std=c++11
LDFLAGS += -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static
TARGETS += src/arch/esp8266/arch.cc src/arch/esp8266/driver/gpio.cc
+TARGETS += src/arch/esp8266/driver/stdout.cc
OBJECTS = ${TARGETS:.cc=.o}
.cc.o:
${CXX} ${INCLUDES} ${COMMON_FLAGS} ${CXXFLAGS} -c -o $@ ${@:.o=.cc}
+ ${OBJCOPY} --rename-section .text=.irom0.text --rename-section .literal=.irom0.literal $@
build/system.ar: ${OBJECTS}
${AR} cru $@ ${OBJECTS}
build/system.elf: build/system.ar
- ${CC} -L${SDK_BASE}/lib -T${SDK_BASE}/lib/eagle.app.v6.ld ${LDFLAGS} \
+ ${CC} -L${SDK_BASE}/lib -T${SDK_BASE}/lib/eagle.app.v6-derf.ld ${LDFLAGS} \
-Wl,--start-group -lc -lgcc -lhal -lpp -lphy -lnet80211 -llwip -lwpa \
-lmain $< -Wl,--end-group -o $@
diff --git a/src/arch/esp8266/arch.cc b/src/arch/esp8266/arch.cc
index 0e11f2d..f5d1c91 100644
--- a/src/arch/esp8266/arch.cc
+++ b/src/arch/esp8266/arch.cc
@@ -10,6 +10,8 @@ extern "C" {
void ets_timer_arm_new(os_timer_t *ptimer, uint32_t milliseconds, bool repeat_flag, bool us_flag);
void ets_timer_disarm(os_timer_t *ptimer);
void ets_timer_setfn(os_timer_t *ptimer, os_timer_func_t *pfunction, void *parg);
+extern void (*__init_array_start)();
+extern void (*__init_array_end)();
}
#define user_procTaskPrio 0
@@ -30,6 +32,9 @@ extern int main(void);
void ICACHE_FLASH_ATTR jump_to_main(void)
{
+ for (void (**p)() = &__init_array_start; p != &__init_array_start; p++) {
+ (*p)();
+ }
#ifdef WITH_LOOP
os_timer_disarm(&loop_timer);
os_timer_setfn(&loop_timer, (os_timer_func_t *)jump_to_loop, (void *)0);
diff --git a/src/arch/esp8266/driver/stdout.cc b/src/arch/esp8266/driver/stdout.cc
new file mode 100644
index 0000000..b35275b
--- /dev/null
+++ b/src/arch/esp8266/driver/stdout.cc
@@ -0,0 +1,25 @@
+#include "driver/stdout.h"
+extern "C" {
+#include "osapi.h"
+#include "user_interface.h"
+#include "gpio.h"
+void uart_div_modify(uint8_t uart_no, uint32 DivLatchValue);
+void os_printf_plus(const char *s, ...);
+}
+
+void StandardOutput::setup()
+{
+ uart_div_modify(0, UART_CLK_FREQ / 115200);
+}
+
+void StandardOutput::put(char c)
+{
+ os_printf("%c", c);
+}
+
+void StandardOutput::write(const char *s)
+{
+ os_printf("%s", s);
+}
+
+StandardOutput kout;
diff --git a/src/arch/msp430fr5969lp/Makefile.inc b/src/arch/msp430fr5969lp/Makefile.inc
index 04069ae..f4b96fe 100644
--- a/src/arch/msp430fr5969lp/Makefile.inc
+++ b/src/arch/msp430fr5969lp/Makefile.inc
@@ -11,6 +11,7 @@ CXX = /opt/msp430/ti/gcc/bin/msp430-elf-g++
OBJCOPY = /opt/msp430/ti/gcc/bin/msp430-elf-objcopy
TARGETS += src/arch/msp430fr5969lp/arch.cc src/arch/msp430fr5969lp/driver/gpio.cc
+TARGETS += src/arch/msp430fr5969lp/driver/stdout.cc
OBJECTS = ${TARGETS:.cc=.o}
diff --git a/src/arch/msp430fr5969lp/driver/stdout.cc b/src/arch/msp430fr5969lp/driver/stdout.cc
new file mode 100644
index 0000000..321785b
--- /dev/null
+++ b/src/arch/msp430fr5969lp/driver/stdout.cc
@@ -0,0 +1,33 @@
+#include "driver/stdout.h"
+#include <msp430.h>
+
+void StandardOutput::setup()
+{
+ UCA0CTLW0 |= UCSWRST;
+ UCA0CTLW0 = UCSWRST | UCSSEL__SMCLK;
+ UCA0MCTLW = UCOS16 | (10<<5) | 0xF700;
+ UCA0BR0 = 8;
+
+ UCA0IRCTL = 0;
+ UCA0ABCTL = 0;
+
+ P2SEL0 &= ~(BIT0 | BIT1);
+ P2SEL1 |= BIT0 | BIT1;
+ P2DIR |= BIT0;
+
+ UCA0CTLW0 &= ~UCSWRST;
+
+ //UCA0IE |= UCRXIE;
+}
+
+void StandardOutput::put(char c)
+{
+ while (!(UCA0IFG & UCTXIFG));
+ UCA0TXBUF = c;
+
+ if (c == '\n') {
+ put('\r');
+ }
+}
+
+StandardOutput kout;
diff --git a/src/arch/posix/Makefile.inc b/src/arch/posix/Makefile.inc
index caf16a7..9dd723d 100644
--- a/src/arch/posix/Makefile.inc
+++ b/src/arch/posix/Makefile.inc
@@ -5,6 +5,7 @@ CXX = g++
INCLUDES += -Iinclude/posix
TARGETS += src/arch/posix/arch.cc src/arch/posix/driver/gpio.cc
+TARGETS += src/arch/posix/driver/stdout.cc
OBJECTS = ${TARGETS:.cc=.o}
diff --git a/src/arch/posix/driver/stdout.cc b/src/arch/posix/driver/stdout.cc
new file mode 100644
index 0000000..e409389
--- /dev/null
+++ b/src/arch/posix/driver/stdout.cc
@@ -0,0 +1,14 @@
+#include "driver/stdout.h"
+#include <stdio.h>
+
+void StandardOutput::put(char c)
+{
+ fputc(c, stdout);
+}
+
+void StandardOutput::flush()
+{
+ fflush(stdout);
+}
+
+StandardOutput kout;
diff --git a/src/os/main.cc b/src/os/main.cc
index b080185..3e48053 100644
--- a/src/os/main.cc
+++ b/src/os/main.cc
@@ -1,5 +1,6 @@
#include "arch.h"
#include "driver/gpio.h"
+#include "driver/stdout.h"
/*
void check_command(unsigned char argc, char** argv)
@@ -93,7 +94,11 @@ int main(void)
{
arch.setup();
gpio.setup();
+ kout.setup();
+
gpio.led_on(0);
+ kout << "Hello, World!" << endl;
+
arch.idle_loop();
//uart_setup();
diff --git a/src/os/object/cpp_helpers.cc b/src/os/object/cpp_helpers.cc
new file mode 100644
index 0000000..aad8020
--- /dev/null
+++ b/src/os/object/cpp_helpers.cc
@@ -0,0 +1,4 @@
+extern "C" void __cxa_pure_virtual()
+{
+ //while (1);
+}
diff --git a/src/os/object/outputstream.cc b/src/os/object/outputstream.cc
new file mode 100644
index 0000000..f308b56
--- /dev/null
+++ b/src/os/object/outputstream.cc
@@ -0,0 +1,191 @@
+#include "object/outputstream.h"
+
+OutputStream & OutputStream::operator<<(unsigned char c)
+{
+ put(c);
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(char c)
+{
+ put(c);
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(unsigned short number)
+{
+ *this << (unsigned long long)number;
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(short number)
+{
+ *this << (long long)number;
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(unsigned int number)
+{
+ *this << (unsigned long long)number;
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(int number)
+{
+ *this << (long long)number;
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(unsigned long number)
+{
+ *this << (unsigned long long)number;
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(long number)
+{
+ *this << (long long)number;
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(unsigned long long number)
+{
+ switch (base) {
+ case 2:
+ put('0');
+ put('b');
+ break;
+ case 8:
+ put('0');
+ break;
+ case 16:
+ put('0');
+ put('x');
+ break;
+ }
+
+ if (number == 0) {
+ put('0');
+ return *this;
+ }
+
+ signed int i = 0;
+ while (number > 0) {
+ if (base == 16 && number % base > 9) {
+ digit_buffer[i] = 'a' + (number % base) - 10;
+ } else {
+ digit_buffer[i] = '0' + (number % base);
+ }
+ number /= base;
+ i++;
+ }
+ i--;
+ for (; i >= 0; i--) {
+ put(digit_buffer[i]);
+ }
+ return *this;
+
+}
+
+OutputStream & OutputStream::operator<<(long long number)
+{
+ if (number < 0) {
+ put('-');
+ number *= -1;
+ }
+ *this << (unsigned long long)number;
+
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(void *pointer)
+{
+ unsigned short temp_base = base;
+ *this << hex << (long)pointer;
+ switch (temp_base) {
+ case 2:
+ *this << bin; break;
+ case 8:
+ *this << oct; break;
+ case 10:
+ *this << dec; break;
+ }
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(const char *text)
+{
+ int i = 0;
+ while (text[i] != '\0') {
+ put(text[i++]);
+ }
+ return *this;
+}
+
+OutputStream & OutputStream::operator<<(OutputStream & (*fkt) (OutputStream &))
+{
+ return fkt(*this);
+}
+
+void OutputStream::setBase(uint8_t b)
+{
+ if (b == 2 || b == 8 || b == 10 || b == 16) {
+ base = b;
+ }
+}
+
+// FLUSH
+OutputStream & flush(OutputStream & os)
+{
+ os.flush();
+ return os;
+}
+
+// ENDL: fuegt einen Zeilenumbruch in die Ausgabe ein.
+OutputStream & endl(OutputStream & os)
+{
+ os.put('\n');
+ os.flush();
+ return os;
+}
+
+// BIN: print numbers in binary form
+OutputStream & bin(OutputStream & os)
+{
+ os.setBase(2);
+ return os;
+}
+
+// OCT: print numbers in octal form.
+OutputStream & oct(OutputStream & os)
+{
+ os.setBase(8);
+ return os;
+}
+
+// DEC: print numbers in decimal form.
+OutputStream & dec(OutputStream & os)
+{
+ os.setBase(10);
+ return os;
+}
+
+// HEX: print numbers in hexadecimal form.
+OutputStream & hex(OutputStream & os)
+{
+ os.setBase(16);
+ return os;
+}
+
+// TERM: null-termination
+OutputStream & term(OutputStream & os)
+{
+ os.put('\0');
+ os.flush();
+ return os;
+}
+
+OutputStream::OutputStream()
+{
+ base = 10;
+}