From 0cda8ec7ade90434d2d6402a4d5c591190f39078 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Wed, 14 Oct 2020 22:03:57 +0200 Subject: [PATCH] all: add -output= flag for setting print/panic output This flag allows setting the standard output to a few different values: -output=none: do not produce output. This is useful for some systems that lack a native output (e.g. Digispark) or for WebAssembly where the additional wasi output dependency may be a problem. -output=native: use native output for the target, for example stdout on an OS or the native output of QEMU under emulation. -output=uart: use UART output, the default for most microcontrollers. -output=custom: allow setting a custom output with runtime.SetOutput. This provides flexibility for those who need it. --- Makefile | 9 ++++-- compileopts/config.go | 14 +++++++- compileopts/options.go | 11 +++++++ compileopts/target.go | 2 ++ main.go | 2 ++ src/machine/machine_atmega.go | 6 ++++ src/machine/machine_attiny.go | 17 ---------- src/machine/machine_avr.go | 6 ---- src/machine/uart.go | 2 +- src/machine/uart_nxpmk66f18.go | 43 +++---------------------- src/runtime/output_custom.go | 24 ++++++++++++++ src/runtime/output_native.go | 13 ++++++++ src/runtime/output_none.go | 13 ++++++++ src/runtime/output_uart.go | 16 +++++++++ src/runtime/runtime_arm7tdmi.go | 4 --- src/runtime/runtime_atsamd21.go | 9 ++---- src/runtime/runtime_atsamd51.go | 9 ++---- src/runtime/runtime_avr.go | 14 +------- src/runtime/runtime_cortexm_qemu.go | 2 +- src/runtime/runtime_esp32.go | 8 +---- src/runtime/runtime_esp8266.go | 7 +--- src/runtime/runtime_fe310.go | 7 +--- src/runtime/runtime_k210.go | 7 +--- src/runtime/runtime_nintendoswitch.go | 2 +- src/runtime/runtime_nrf.go | 6 +--- src/runtime/runtime_nxpmk66f18.go | 5 +-- src/runtime/runtime_stm32f103xx.go | 6 +--- src/runtime/runtime_stm32f405.go | 19 +++-------- src/runtime/runtime_stm32f407.go | 7 +--- src/runtime/runtime_tinygoriscv_qemu.go | 2 +- src/runtime/runtime_unix.go | 2 +- src/runtime/runtime_wasm.go | 2 +- targets/cortex-m-qemu.json | 1 + targets/digispark.json | 1 + targets/gameboy-advance.json | 1 + targets/nintendoswitch.json | 1 + targets/riscv-qemu.json | 1 + targets/wasi.json | 1 + targets/wasm.json | 1 + 39 files changed, 142 insertions(+), 161 deletions(-) create mode 100644 src/runtime/output_custom.go create mode 100644 src/runtime/output_native.go create mode 100644 src/runtime/output_none.go create mode 100644 src/runtime/output_uart.go diff --git a/Makefile b/Makefile index 49b39ff2c3..d3cd660cb9 100644 --- a/Makefile +++ b/Makefile @@ -337,6 +337,10 @@ smoketest: @$(MD5SUM) test.hex $(TINYGO) build -size short -o test.hex -target=itsybitsy-nrf52840 examples/blinky1 @$(MD5SUM) test.hex + $(TINYGO) build -size short -o test.hex -target=teensy36 examples/blinky1 + @$(MD5SUM) test.hex + $(TINYGO) build -o test.nro -target=nintendoswitch examples/serial + @$(MD5SUM) test.nro # test pwm $(TINYGO) build -size short -o test.hex -target=itsybitsy-m0 examples/pwm @$(MD5SUM) test.hex @@ -379,8 +383,9 @@ endif @$(MD5SUM) test.hex $(TINYGO) build -size short -o test.hex -target=pca10040 -opt=1 examples/blinky1 @$(MD5SUM) test.hex - $(TINYGO) build -o test.nro -target=nintendoswitch examples/serial - @$(MD5SUM) test.nro + $(TINYGO) build -o test.wasm -target=wasm -output=none examples/serial + $(TINYGO) build -size short -o test.hex -target=pca10040 -output=none examples/serial + @$(MD5SUM) test.hex wasmtest: $(GO) test ./tests/wasm diff --git a/compileopts/config.go b/compileopts/config.go index 25b3ad1da8..c0f3618f44 100644 --- a/compileopts/config.go +++ b/compileopts/config.go @@ -79,7 +79,7 @@ func (c *Config) GOARCH() string { // BuildTags returns the complete list of build tags used during this build. func (c *Config) BuildTags() []string { - tags := append(c.Target.BuildTags, []string{"tinygo", "gc." + c.GC(), "scheduler." + c.Scheduler()}...) + tags := append(c.Target.BuildTags, []string{"tinygo", "gc." + c.GC(), "scheduler." + c.Scheduler(), "output." + c.Output()}...) for i := 1; i <= c.GoMinorVersion; i++ { tags = append(tags, fmt.Sprintf("go1.%d", i)) } @@ -142,6 +142,18 @@ func (c *Config) Scheduler() string { return "coroutines" } +// Output returns the selected output for logging from the runtime, such as for +// println and panic. +func (c *Config) Output() string { + if c.Options.Output != "" { + return c.Options.Output + } + if c.Target.Output != "" { + return c.Target.Output + } + return "uart" +} + // FuncImplementation picks an appropriate func value implementation for the // target. func (c *Config) FuncImplementation() FuncValueImplementation { diff --git a/compileopts/options.go b/compileopts/options.go index 7948b71c6d..f7dfcf95ff 100644 --- a/compileopts/options.go +++ b/compileopts/options.go @@ -8,6 +8,7 @@ import ( var ( validGCOptions = []string{"none", "leaking", "extalloc", "conservative"} validSchedulerOptions = []string{"none", "tasks", "coroutines"} + validOutputOptions = []string{"none", "native", "uart", "custom"} validPrintSizeOptions = []string{"none", "short", "full"} validPanicStrategyOptions = []string{"print", "trap"} ) @@ -20,6 +21,7 @@ type Options struct { GC string PanicStrategy string Scheduler string + Output string PrintIR bool DumpSSA bool VerifyIR bool @@ -55,6 +57,15 @@ func (o *Options) Verify() error { } } + if o.Output != "" { + valid := isInArray(validOutputOptions, o.Output) + if !valid { + return fmt.Errorf(`invalid output option '%s': valid values are %s`, + o.Output, + strings.Join(validOutputOptions, ", ")) + } + } + if o.PrintSizes != "" { valid := isInArray(validPrintSizeOptions, o.PrintSizes) if !valid { diff --git a/compileopts/target.go b/compileopts/target.go index 8b3c68fc5f..9d586fc72f 100644 --- a/compileopts/target.go +++ b/compileopts/target.go @@ -30,6 +30,7 @@ type TargetSpec struct { BuildTags []string `json:"build-tags"` GC string `json:"gc"` Scheduler string `json:"scheduler"` + Output string `json:"output"` // output for println etc Compiler string `json:"compiler"` Linker string `json:"linker"` RTLib string `json:"rtlib"` // compiler runtime library (libgcc, compiler-rt) @@ -236,6 +237,7 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { GOOS: goos, GOARCH: goarch, BuildTags: []string{goos, goarch}, + Output: "native", Compiler: "clang", Linker: "cc", CFlags: []string{"--target=" + triple}, diff --git a/main.go b/main.go index 30e8ee6bcb..52d5c80df6 100644 --- a/main.go +++ b/main.go @@ -815,6 +815,7 @@ func main() { gc := flag.String("gc", "", "garbage collector to use (none, leaking, extalloc, conservative)") panicStrategy := flag.String("panic", "print", "panic strategy (print, trap)") scheduler := flag.String("scheduler", "", "which scheduler to use (none, coroutines, tasks)") + output := flag.String("output", "", "which output to use for panic and print functions") printIR := flag.Bool("printir", false, "print LLVM IR") dumpSSA := flag.Bool("dumpssa", false, "dump internal Go SSA") verifyIR := flag.Bool("verifyir", false, "run extra verification steps on LLVM IR") @@ -864,6 +865,7 @@ func main() { GC: *gc, PanicStrategy: *panicStrategy, Scheduler: *scheduler, + Output: *output, PrintIR: *printIR, DumpSSA: *dumpSSA, VerifyIR: *verifyIR, diff --git a/src/machine/machine_atmega.go b/src/machine/machine_atmega.go index 6e6307d56f..24b2fb7ff9 100644 --- a/src/machine/machine_atmega.go +++ b/src/machine/machine_atmega.go @@ -115,6 +115,12 @@ type UART struct { Buffer *RingBuffer } +// UART +var ( + // UART0 is the hardware serial port on the AVR. + UART0 = UART{Buffer: NewRingBuffer()} +) + // Configure the UART on the AVR. Defaults to 9600 baud on Arduino. func (uart UART) Configure(config UARTConfig) { if config.BaudRate == 0 { diff --git a/src/machine/machine_attiny.go b/src/machine/machine_attiny.go index ecafae878d..402b4e31cd 100644 --- a/src/machine/machine_attiny.go +++ b/src/machine/machine_attiny.go @@ -2,23 +2,6 @@ package machine -// UART on the AVR is a dummy implementation. UART has not been implemented for ATtiny -// devices. -type UART struct { - Buffer *RingBuffer -} - -// Configure is a dummy implementation. UART has not been implemented for ATtiny -// devices. -func (uart UART) Configure(config UARTConfig) { -} - -// WriteByte is a dummy implementation. UART has not been implemented for ATtiny -// devices. -func (uart UART) WriteByte(c byte) error { - return nil -} - // Tx is a dummy implementation. I2C has not been implemented for ATtiny // devices. func (i2c I2C) Tx(addr uint16, w, r []byte) error { diff --git a/src/machine/machine_avr.go b/src/machine/machine_avr.go index f1dbf89d10..fe500335e2 100644 --- a/src/machine/machine_avr.go +++ b/src/machine/machine_avr.go @@ -148,9 +148,3 @@ type I2C struct { // I2C0 is the only I2C interface on most AVRs. var I2C0 = I2C{} - -// UART -var ( - // UART0 is the hardware serial port on the AVR. - UART0 = UART{Buffer: NewRingBuffer()} -) diff --git a/src/machine/uart.go b/src/machine/uart.go index 40d2d99c1c..971ff23ecc 100644 --- a/src/machine/uart.go +++ b/src/machine/uart.go @@ -1,4 +1,4 @@ -// +build avr esp nrf sam sifive stm32 k210 nxp +// +build atmega esp nrf sam sifive stm32 k210 nxp package machine diff --git a/src/machine/uart_nxpmk66f18.go b/src/machine/uart_nxpmk66f18.go index 3fb4d9496a..18d6120869 100644 --- a/src/machine/uart_nxpmk66f18.go +++ b/src/machine/uart_nxpmk66f18.go @@ -59,24 +59,6 @@ var ( ErrNotConfigured = errors.New("device has not been configured") ) -//go:linkname gosched runtime.Gosched -func gosched() - -// PutcharUART writes a byte to the UART synchronously, without using interrupts -// or calling the scheduler -func PutcharUART(u UART, c byte) { - // ensure the UART has been configured - if !u.SCGC.HasBits(u.SCGCMask) { - u.configure(UARTConfig{}, false) - } - - for u.TCFIFO.Get() > 0 { - // busy wait - } - u.D.Set(c) - u.C2.Set(uartC2TXActive) -} - // PollUART manually checks a UART status and calls the ISR. This should only be // called by runtime.abort. func PollUART(u UART) { @@ -119,10 +101,6 @@ func init() { // Configure the UART. func (u UART) Configure(config UARTConfig) { - u.configure(config, true) -} - -func (u UART) configure(config UARTConfig, canSched bool) { // from: serial_begin if !u.Configured { @@ -150,13 +128,7 @@ func (u UART) configure(config UARTConfig, canSched bool) { if u.Configured { // don't change baud rate mid transmit - if canSched { - u.Flush() - } else { - for u.Transmitting.Get() != 0 { - // busy wait flush - } - } + u.Flush() } // set the divisor @@ -208,7 +180,6 @@ func (u UART) Disable() { func (u UART) Flush() { for u.Transmitting.Get() != 0 { - gosched() } } @@ -291,15 +262,11 @@ func (u UART) handleStatusInterrupt(interrupt.Interrupt) { // WriteByte writes a byte of data to the UART. func (u UART) WriteByte(c byte) error { - if !u.Configured { - return ErrNotConfigured - } - - for !u.TXBuffer.Put(c) { - gosched() + // ensure the UART has been configured + for u.TCFIFO.Get() > 0 { + // busy wait } - - u.Transmitting.Set(1) + u.D.Set(c) u.C2.Set(uartC2TXActive) return nil } diff --git a/src/runtime/output_custom.go b/src/runtime/output_custom.go new file mode 100644 index 0000000000..5e6cf49a0d --- /dev/null +++ b/src/runtime/output_custom.go @@ -0,0 +1,24 @@ +// +build output.custom + +package runtime + +// The "custom" output allows setting a custom function for putchar, for full +// control over where output goes. + +var outputFunc func(c byte) + +func initOutput() { +} + +func putchar(c byte) { + if outputFunc != nil { + outputFunc(c) + } +} + +// SetOutput sets a custom function that may be used as an output. This may be +// anything, for example it can be used to redirect output to ARM semihosting if +// needed while debugging. +func SetOutput(output func(byte)) { + outputFunc = output +} diff --git a/src/runtime/output_native.go b/src/runtime/output_native.go new file mode 100644 index 0000000000..7e617b226b --- /dev/null +++ b/src/runtime/output_native.go @@ -0,0 +1,13 @@ +// +build output.native + +package runtime + +// The "native" output is useful on devices with a native stdout, usually real +// operating systems (Linux, etc). + +func initOutput() { +} + +func putchar(c byte) { + nativePutchar(c) +} diff --git a/src/runtime/output_none.go b/src/runtime/output_none.go new file mode 100644 index 0000000000..cfe3d72b5d --- /dev/null +++ b/src/runtime/output_none.go @@ -0,0 +1,13 @@ +// +build output.none + +package runtime + +// The "none" output drops all logging output (println, panic, ...). This may be +// useful on targets that do not need output logging (for code size, battery +// consumption, or other reasons) or do not have an output at all. + +func initOutput() { +} + +func putchar(c byte) { +} diff --git a/src/runtime/output_uart.go b/src/runtime/output_uart.go new file mode 100644 index 0000000000..89e7510503 --- /dev/null +++ b/src/runtime/output_uart.go @@ -0,0 +1,16 @@ +// +build output.uart + +package runtime + +import "machine" + +// The "uart" output writes all output over a serial (UART) or USB-CDC +// connection. Most, but not all, microcontrollers have an UART available. + +func initOutput() { + machine.UART0.Configure(machine.UARTConfig{}) +} + +func putchar(c byte) { + machine.UART0.WriteByte(c) +} diff --git a/src/runtime/runtime_arm7tdmi.go b/src/runtime/runtime_arm7tdmi.go index 70b764042b..d03c42a73b 100644 --- a/src/runtime/runtime_arm7tdmi.go +++ b/src/runtime/runtime_arm7tdmi.go @@ -9,10 +9,6 @@ import ( type timeUnit int64 -func putchar(c byte) { - // dummy, TODO -} - //go:extern _sbss var _sbss [0]byte diff --git a/src/runtime/runtime_atsamd21.go b/src/runtime/runtime_atsamd21.go index a5f99293f7..d221e32c97 100644 --- a/src/runtime/runtime_atsamd21.go +++ b/src/runtime/runtime_atsamd21.go @@ -5,7 +5,6 @@ package runtime import ( "device/arm" "device/sam" - "machine" "runtime/interrupt" "runtime/volatile" "unsafe" @@ -29,12 +28,8 @@ func init() { initUSBClock() initADCClock() - // connect to USB CDC interface - machine.UART0.Configure(machine.UARTConfig{}) -} - -func putchar(c byte) { - machine.UART0.WriteByte(c) + // configure stdout (usually USB-CDC) + initOutput() } func initClocks() { diff --git a/src/runtime/runtime_atsamd51.go b/src/runtime/runtime_atsamd51.go index c21324eadb..7fdcc54df0 100644 --- a/src/runtime/runtime_atsamd51.go +++ b/src/runtime/runtime_atsamd51.go @@ -5,7 +5,6 @@ package runtime import ( "device/arm" "device/sam" - "machine" "runtime/interrupt" "runtime/volatile" ) @@ -28,12 +27,8 @@ func init() { initUSBClock() initADCClock() - // connect to USB CDC interface - machine.UART0.Configure(machine.UARTConfig{}) -} - -func putchar(c byte) { - machine.UART0.WriteByte(c) + // configure stdout (usually USB-CDC) + initOutput() } func initClocks() { diff --git a/src/runtime/runtime_avr.go b/src/runtime/runtime_avr.go index ae8a4d41e6..1f5f38c639 100644 --- a/src/runtime/runtime_avr.go +++ b/src/runtime/runtime_avr.go @@ -4,7 +4,6 @@ package runtime import ( "device/avr" - "machine" "unsafe" ) @@ -37,6 +36,7 @@ var _ebss [0]byte //export main func main() { preinit() + initOutput() run() abort() } @@ -55,18 +55,6 @@ func postinit() { avr.Asm("sei") } -func init() { - initUART() -} - -func initUART() { - machine.UART0.Configure(machine.UARTConfig{}) -} - -func putchar(c byte) { - machine.UART0.WriteByte(c) -} - const asyncScheduler = false const tickNanos = 1024 * 16384 // roughly 16ms in nanoseconds diff --git a/src/runtime/runtime_cortexm_qemu.go b/src/runtime/runtime_cortexm_qemu.go index bc4fc2d1c9..d72c68b6eb 100644 --- a/src/runtime/runtime_cortexm_qemu.go +++ b/src/runtime/runtime_cortexm_qemu.go @@ -49,7 +49,7 @@ func ticks() timeUnit { // UART0 output register. var stdoutWrite = (*volatile.Register8)(unsafe.Pointer(uintptr(0x4000c000))) -func putchar(c byte) { +func nativePutchar(c byte) { stdoutWrite.Set(uint8(c)) } diff --git a/src/runtime/runtime_esp32.go b/src/runtime/runtime_esp32.go index 6f2ad6defc..4004281989 100644 --- a/src/runtime/runtime_esp32.go +++ b/src/runtime/runtime_esp32.go @@ -5,7 +5,6 @@ package runtime import ( "device" "device/esp" - "machine" "unsafe" ) @@ -13,10 +12,6 @@ type timeUnit int64 var currentTime timeUnit -func putchar(c byte) { - machine.UART0.WriteByte(c) -} - func postinit() {} // This is the function called on startup right after the stack pointer has been @@ -52,8 +47,7 @@ func main() { // faster. preinit() - // Initialize UART. - machine.UART0.Configure(machine.UARTConfig{}) + initOutput() // Configure timer 0 in timer group 0, for timekeeping. // EN: Enable the timer. diff --git a/src/runtime/runtime_esp8266.go b/src/runtime/runtime_esp8266.go index 2ad1096399..be7db3227f 100644 --- a/src/runtime/runtime_esp8266.go +++ b/src/runtime/runtime_esp8266.go @@ -5,7 +5,6 @@ package runtime import ( "device" "device/esp" - "machine" "unsafe" ) @@ -13,10 +12,6 @@ type timeUnit int64 var currentTime timeUnit = 0 -func putchar(c byte) { - machine.UART0.WriteByte(c) -} - // Write to the internal control bus (using I2C?). // Signature found here: // https://github.com/espressif/ESP8266_RTOS_SDK/blob/14171de0/components/esp8266/include/esp8266/rom_functions.h#L54 @@ -37,7 +32,7 @@ func main() { rom_i2c_writeReg(103, 4, 2, 145) // Initialize UART. - machine.UART0.Configure(machine.UARTConfig{}) + initOutput() // Initialize timer. Bits: // ENABLE: timer enable diff --git a/src/runtime/runtime_fe310.go b/src/runtime/runtime_fe310.go index 437f03bf58..5bd2820036 100644 --- a/src/runtime/runtime_fe310.go +++ b/src/runtime/runtime_fe310.go @@ -6,7 +6,6 @@ package runtime import ( - "machine" "unsafe" "device/riscv" @@ -93,11 +92,7 @@ func initPeripherals() { sifive.RTC.RTCCFG.Set(sifive.RTC_RTCCFG_ENALWAYS) // Configure the UART. - machine.UART0.Configure(machine.UARTConfig{}) -} - -func putchar(c byte) { - machine.UART0.WriteByte(c) + initOutput() } const asyncScheduler = false diff --git a/src/runtime/runtime_k210.go b/src/runtime/runtime_k210.go index 457a1e1773..7b23bfc6c7 100644 --- a/src/runtime/runtime_k210.go +++ b/src/runtime/runtime_k210.go @@ -8,7 +8,6 @@ package runtime import ( "device/kendryte" "device/riscv" - "machine" "runtime/volatile" "unsafe" ) @@ -105,11 +104,7 @@ func initPeripherals() { // Enable FPIOA peripheral. kendryte.SYSCTL.CLK_EN_PERI.SetBits(kendryte.SYSCTL_CLK_EN_PERI_FPIOA_CLK_EN) - machine.UART0.Configure(machine.UARTConfig{}) -} - -func putchar(c byte) { - machine.UART0.WriteByte(c) + initOutput() } const asyncScheduler = false diff --git a/src/runtime/runtime_nintendoswitch.go b/src/runtime/runtime_nintendoswitch.go index f5107fa8d3..bbdc95907b 100644 --- a/src/runtime/runtime_nintendoswitch.go +++ b/src/runtime/runtime_nintendoswitch.go @@ -58,7 +58,7 @@ func ticks() timeUnit { var stdoutBuffer = make([]byte, 120) var position = 0 -func putchar(c byte) { +func nativePutchar(c byte) { if c == '\n' || position >= len(stdoutBuffer) { nxOutputString(&stdoutBuffer[0], uint64(position)) position = 0 diff --git a/src/runtime/runtime_nrf.go b/src/runtime/runtime_nrf.go index 20f81f1a40..ec35d5fffc 100644 --- a/src/runtime/runtime_nrf.go +++ b/src/runtime/runtime_nrf.go @@ -25,7 +25,7 @@ func main() { } func init() { - machine.UART0.Configure(machine.UARTConfig{}) + initOutput() initLFCLK() initRTC() } @@ -51,10 +51,6 @@ func initRTC() { intr.Enable() } -func putchar(c byte) { - machine.UART0.WriteByte(c) -} - const asyncScheduler = false func sleepTicks(d timeUnit) { diff --git a/src/runtime/runtime_nxpmk66f18.go b/src/runtime/runtime_nxpmk66f18.go index a46aa11e85..c7af07cea4 100644 --- a/src/runtime/runtime_nxpmk66f18.go +++ b/src/runtime/runtime_nxpmk66f18.go @@ -56,6 +56,7 @@ func main() { initSystem() arm.Asm("CPSIE i") initInternal() + initOutput() run() abort() @@ -229,10 +230,6 @@ func initInternal() { func postinit() {} -func putchar(c byte) { - machine.PutcharUART(&machine.UART0, c) -} - // ??? const asyncScheduler = false diff --git a/src/runtime/runtime_stm32f103xx.go b/src/runtime/runtime_stm32f103xx.go index 7407fa738a..bf19776495 100644 --- a/src/runtime/runtime_stm32f103xx.go +++ b/src/runtime/runtime_stm32f103xx.go @@ -14,11 +14,7 @@ func init() { initCLK() initRTC() initTIM() - machine.UART0.Configure(machine.UARTConfig{}) -} - -func putchar(c byte) { - machine.UART0.WriteByte(c) + initOutput() } // initCLK sets clock to 72MHz using HSE 8MHz crystal w/ PLL X 9 (8MHz x 9 = 72MHz). diff --git a/src/runtime/runtime_stm32f405.go b/src/runtime/runtime_stm32f405.go index 8e542fffad..9017abeab8 100644 --- a/src/runtime/runtime_stm32f405.go +++ b/src/runtime/runtime_stm32f405.go @@ -5,16 +5,15 @@ package runtime import ( "device/arm" "device/stm32" - "machine" "runtime/interrupt" "runtime/volatile" ) func init() { - initOSC() // configure oscillators - initCLK() // configure CPU, AHB, and APB bus clocks - initTIM() // configure timers - initCOM() // configure serial comm interfaces + initOSC() // configure oscillators + initCLK() // configure CPU, AHB, and APB bus clocks + initTIM() // configure timers + initOutput() // configure default output for println etc } const ( @@ -176,12 +175,6 @@ func initTIM() { tim7.Enable() } -func initCOM() { - if machine.NUM_UART_INTERFACES > 0 { - machine.UART0.Configure(machine.UARTConfig{}) - } -} - var ( // tick in milliseconds tickCount timeUnit @@ -242,7 +235,3 @@ func handleTIM7(interrupt.Interrupt) { tickCount++ } } - -func putchar(c byte) { - machine.UART0.WriteByte(c) -} diff --git a/src/runtime/runtime_stm32f407.go b/src/runtime/runtime_stm32f407.go index 626dabd94c..52cd30144a 100644 --- a/src/runtime/runtime_stm32f407.go +++ b/src/runtime/runtime_stm32f407.go @@ -5,7 +5,6 @@ package runtime import ( "device/arm" "device/stm32" - "machine" "runtime/interrupt" "runtime/volatile" ) @@ -13,14 +12,10 @@ import ( func init() { initCLK() initTIM3() - machine.UART0.Configure(machine.UARTConfig{}) + initOutput() initTIM7() } -func putchar(c byte) { - machine.UART0.WriteByte(c) -} - const ( HSE_STARTUP_TIMEOUT = 0x0500 /* PLL Options - See RM0090 Reference Manual pg. 95 */ diff --git a/src/runtime/runtime_tinygoriscv_qemu.go b/src/runtime/runtime_tinygoriscv_qemu.go index 27caa398ad..5d608b7532 100644 --- a/src/runtime/runtime_tinygoriscv_qemu.go +++ b/src/runtime/runtime_tinygoriscv_qemu.go @@ -54,7 +54,7 @@ var ( testFinisher = (*volatile.Register16)(unsafe.Pointer(uintptr(0x100000))) ) -func putchar(c byte) { +func nativePutchar(c byte) { stdoutWrite.Set(uint8(c)) } diff --git a/src/runtime/runtime_unix.go b/src/runtime/runtime_unix.go index 17940f69d3..4073342c3f 100644 --- a/src/runtime/runtime_unix.go +++ b/src/runtime/runtime_unix.go @@ -62,7 +62,7 @@ func runMain() { run() } -func putchar(c byte) { +func nativePutchar(c byte) { _putchar(int(c)) } diff --git a/src/runtime/runtime_wasm.go b/src/runtime/runtime_wasm.go index e37d432e04..31f651c5c9 100644 --- a/src/runtime/runtime_wasm.go +++ b/src/runtime/runtime_wasm.go @@ -27,7 +27,7 @@ var ( } ) -func putchar(c byte) { +func nativePutchar(c byte) { // write to stdout const stdout = 1 var nwritten uint diff --git a/targets/cortex-m-qemu.json b/targets/cortex-m-qemu.json index 03d688a364..7041bd3a4b 100644 --- a/targets/cortex-m-qemu.json +++ b/targets/cortex-m-qemu.json @@ -2,6 +2,7 @@ "inherits": ["cortex-m"], "llvm-target": "armv7m-none-eabi", "build-tags": ["qemu", "lm3s6965"], + "output": "native", "cflags": [ "--target=armv7m-none-eabi", "-Qunused-arguments" diff --git a/targets/digispark.json b/targets/digispark.json index 06861f4aaf..78a2ee6572 100644 --- a/targets/digispark.json +++ b/targets/digispark.json @@ -2,6 +2,7 @@ "inherits": ["avr"], "cpu": "attiny85", "build-tags": ["digispark", "attiny85", "attiny", "avr2", "avr25"], + "output": "none", "cflags": [ "-mmcu=attiny85" ], diff --git a/targets/gameboy-advance.json b/targets/gameboy-advance.json index 0675622c4b..77b978f34f 100644 --- a/targets/gameboy-advance.json +++ b/targets/gameboy-advance.json @@ -4,6 +4,7 @@ "build-tags": ["gameboyadvance", "arm7tdmi", "baremetal", "linux", "arm"], "goos": "linux", "goarch": "arm", + "output": "none", "compiler": "clang", "linker": "ld.lld", "rtlib": "compiler-rt", diff --git a/targets/nintendoswitch.json b/targets/nintendoswitch.json index aa8567b04f..6c016fbcb4 100644 --- a/targets/nintendoswitch.json +++ b/targets/nintendoswitch.json @@ -3,6 +3,7 @@ "build-tags": ["nintendoswitch", "arm64"], "goos": "linux", "goarch": "arm64", + "output": "native", "compiler": "clang", "linker": "ld.lld", "rtlib": "compiler-rt", diff --git a/targets/riscv-qemu.json b/targets/riscv-qemu.json index 4f2c695fe6..b0ee069525 100644 --- a/targets/riscv-qemu.json +++ b/targets/riscv-qemu.json @@ -2,6 +2,7 @@ "inherits": ["riscv32"], "features": ["+a", "+c", "+m"], "build-tags": ["virt", "qemu"], + "output": "native", "linkerscript": "targets/riscv-qemu.ld", "emulator": ["qemu-system-riscv32", "-machine", "virt", "-nographic", "-bios", "none", "-kernel"] } diff --git a/targets/wasi.json b/targets/wasi.json index 091e3c5ad8..20d1934d99 100644 --- a/targets/wasi.json +++ b/targets/wasi.json @@ -1,6 +1,7 @@ { "llvm-target": "wasm32--wasi", "build-tags": ["wasm", "wasi"], + "output": "native", "goos": "linux", "goarch": "arm", "compiler": "clang", diff --git a/targets/wasm.json b/targets/wasm.json index 7767cd96b4..724e03e6d8 100644 --- a/targets/wasm.json +++ b/targets/wasm.json @@ -3,6 +3,7 @@ "build-tags": ["js", "wasm"], "goos": "js", "goarch": "wasm", + "output": "native", "compiler": "clang", "linker": "wasm-ld", "cflags": [