diff options
author | Daniel Friesel <derf@finalrewind.org> | 2017-12-08 15:07:52 +0100 |
---|---|---|
committer | Daniel Friesel <derf@finalrewind.org> | 2017-12-08 15:07:52 +0100 |
commit | dcf84169ae75b11c1656d45dbc6c626d93da6a10 (patch) | |
tree | d78ad84e6aba1f5f13037e40141013f3a3061d54 | |
parent | 56f2d90751f1c1b2db925da215a14721cf18d483 (diff) |
Add output support (broken on esp8266)
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | include/esp8266/driver/stdout.h | 20 | ||||
-rw-r--r-- | include/msp430fr5969lp/driver/stdout.h | 19 | ||||
-rw-r--r-- | include/object/outputstream.h | 65 | ||||
-rw-r--r-- | include/posix/driver/stdout.h | 20 | ||||
-rw-r--r-- | src/arch/esp8266/Makefile.inc | 5 | ||||
-rw-r--r-- | src/arch/esp8266/arch.cc | 5 | ||||
-rw-r--r-- | src/arch/esp8266/driver/stdout.cc | 25 | ||||
-rw-r--r-- | src/arch/msp430fr5969lp/Makefile.inc | 1 | ||||
-rw-r--r-- | src/arch/msp430fr5969lp/driver/stdout.cc | 33 | ||||
-rw-r--r-- | src/arch/posix/Makefile.inc | 1 | ||||
-rw-r--r-- | src/arch/posix/driver/stdout.cc | 14 | ||||
-rw-r--r-- | src/os/main.cc | 5 | ||||
-rw-r--r-- | src/os/object/cpp_helpers.cc | 4 | ||||
-rw-r--r-- | src/os/object/outputstream.cc | 191 |
15 files changed, 409 insertions, 3 deletions
@@ -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 ©); + + 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 ©); + + 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 ©); + + 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; +} |