Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
14 changes: 13 additions & 1 deletion compileopts/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
Expand Down Expand Up @@ -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 {
Expand Down
11 changes: 11 additions & 0 deletions compileopts/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"}
)
Expand All @@ -20,6 +21,7 @@ type Options struct {
GC string
PanicStrategy string
Scheduler string
Output string
PrintIR bool
DumpSSA bool
VerifyIR bool
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions compileopts/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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},
Expand Down
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -864,6 +865,7 @@ func main() {
GC: *gc,
PanicStrategy: *panicStrategy,
Scheduler: *scheduler,
Output: *output,
PrintIR: *printIR,
DumpSSA: *dumpSSA,
VerifyIR: *verifyIR,
Expand Down
6 changes: 6 additions & 0 deletions src/machine/machine_atmega.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
17 changes: 0 additions & 17 deletions src/machine/machine_attiny.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
6 changes: 0 additions & 6 deletions src/machine/machine_avr.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()}
)
2 changes: 1 addition & 1 deletion src/machine/uart.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// +build avr esp nrf sam sifive stm32 k210 nxp
// +build atmega esp nrf sam sifive stm32 k210 nxp

package machine

Expand Down
43 changes: 5 additions & 38 deletions src/machine/uart_nxpmk66f18.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -208,7 +180,6 @@ func (u UART) Disable() {

func (u UART) Flush() {
for u.Transmitting.Get() != 0 {
gosched()
}
}

Expand Down Expand Up @@ -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
}
24 changes: 24 additions & 0 deletions src/runtime/output_custom.go
Original file line number Diff line number Diff line change
@@ -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
}
13 changes: 13 additions & 0 deletions src/runtime/output_native.go
Original file line number Diff line number Diff line change
@@ -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)
}
13 changes: 13 additions & 0 deletions src/runtime/output_none.go
Original file line number Diff line number Diff line change
@@ -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) {
}
16 changes: 16 additions & 0 deletions src/runtime/output_uart.go
Original file line number Diff line number Diff line change
@@ -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)
}
4 changes: 0 additions & 4 deletions src/runtime/runtime_arm7tdmi.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ import (

type timeUnit int64

func putchar(c byte) {
// dummy, TODO
}

//go:extern _sbss
var _sbss [0]byte

Expand Down
9 changes: 2 additions & 7 deletions src/runtime/runtime_atsamd21.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package runtime
import (
"device/arm"
"device/sam"
"machine"
"runtime/interrupt"
"runtime/volatile"
"unsafe"
Expand All @@ -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() {
Expand Down
9 changes: 2 additions & 7 deletions src/runtime/runtime_atsamd51.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package runtime
import (
"device/arm"
"device/sam"
"machine"
"runtime/interrupt"
"runtime/volatile"
)
Expand All @@ -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() {
Expand Down
Loading