avr: drop GNU toolchain dependency
- Use compiler-rt and picolibc instead of avr-libc. - Use ld.lld instead of avr-ld (or avr-gcc). This makes it much easier to get started with TinyGo on AVR because installing these extra tools (gcc-avr, avr-libc) can be a hassle. It also opens the door for future improvements such as ThinLTO. There is a code size increase but I think it's worth it in the long run. The code size increase can hopefully be reduced with improvements to the LLVM AVR backend and to compiler-rt.
Этот коммит содержится в:
родитель
b9bb605257
коммит
df888acd5e
22 изменённых файлов: 74 добавлений и 41 удалений
|
@ -63,8 +63,6 @@ commands:
|
||||||
clang-<<parameters.llvm>> \
|
clang-<<parameters.llvm>> \
|
||||||
libclang-<<parameters.llvm>>-dev \
|
libclang-<<parameters.llvm>>-dev \
|
||||||
lld-<<parameters.llvm>> \
|
lld-<<parameters.llvm>> \
|
||||||
gcc-avr \
|
|
||||||
avr-libc \
|
|
||||||
cmake \
|
cmake \
|
||||||
ninja-build
|
ninja-build
|
||||||
- hack-ninja-jobs
|
- hack-ninja-jobs
|
||||||
|
|
2
.github/workflows/build-macos.yml
предоставленный
2
.github/workflows/build-macos.yml
предоставленный
|
@ -93,7 +93,7 @@ jobs:
|
||||||
path: build/tinygo.darwin-amd64.tar.gz
|
path: build/tinygo.darwin-amd64.tar.gz
|
||||||
- name: Smoke tests
|
- name: Smoke tests
|
||||||
shell: bash
|
shell: bash
|
||||||
run: make smoketest TINYGO=$(PWD)/build/tinygo AVR=0
|
run: make smoketest TINYGO=$(PWD)/build/tinygo
|
||||||
test-macos-homebrew:
|
test-macos-homebrew:
|
||||||
name: homebrew-install
|
name: homebrew-install
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
|
|
7
.github/workflows/linux.yml
предоставленный
7
.github/workflows/linux.yml
предоставленный
|
@ -133,11 +133,6 @@ jobs:
|
||||||
mkdir -p ~/lib
|
mkdir -p ~/lib
|
||||||
tar -C ~/lib -xf tinygo.linux-amd64.tar.gz
|
tar -C ~/lib -xf tinygo.linux-amd64.tar.gz
|
||||||
ln -s ~/lib/tinygo/bin/tinygo ~/go/bin/tinygo
|
ln -s ~/lib/tinygo/bin/tinygo ~/go/bin/tinygo
|
||||||
- name: Install apt dependencies
|
|
||||||
run: |
|
|
||||||
sudo apt-get install --no-install-recommends \
|
|
||||||
gcc-avr \
|
|
||||||
avr-libc
|
|
||||||
- run: make tinygo-test-wasi-fast
|
- run: make tinygo-test-wasi-fast
|
||||||
- run: make smoketest
|
- run: make smoketest
|
||||||
assert-test-linux:
|
assert-test-linux:
|
||||||
|
@ -158,8 +153,6 @@ jobs:
|
||||||
qemu-system-arm \
|
qemu-system-arm \
|
||||||
qemu-system-riscv32 \
|
qemu-system-riscv32 \
|
||||||
qemu-user \
|
qemu-user \
|
||||||
gcc-avr \
|
|
||||||
avr-libc \
|
|
||||||
simavr \
|
simavr \
|
||||||
ninja-build
|
ninja-build
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
|
|
2
.github/workflows/windows.yml
предоставленный
2
.github/workflows/windows.yml
предоставленный
|
@ -125,7 +125,7 @@ jobs:
|
||||||
run: 7z x release.zip -r
|
run: 7z x release.zip -r
|
||||||
- name: Smoke tests
|
- name: Smoke tests
|
||||||
shell: bash
|
shell: bash
|
||||||
run: make smoketest TINYGO=$(PWD)/build/tinygo/bin/tinygo AVR=0
|
run: make smoketest TINYGO=$(PWD)/build/tinygo/bin/tinygo
|
||||||
|
|
||||||
stdlib-test-windows:
|
stdlib-test-windows:
|
||||||
runs-on: windows-2022
|
runs-on: windows-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
FROM golang:1.19 AS tinygo-llvm
|
FROM golang:1.19 AS tinygo-llvm
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y apt-utils make cmake clang-11 binutils-avr gcc-avr avr-libc ninja-build
|
apt-get install -y apt-utils make cmake clang-11 ninja-build
|
||||||
|
|
||||||
COPY ./Makefile /tinygo/Makefile
|
COPY ./Makefile /tinygo/Makefile
|
||||||
|
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -674,7 +674,6 @@ ifneq ($(STM32), 0)
|
||||||
$(TINYGO) build -size short -o test.hex -target=swan examples/blinky1
|
$(TINYGO) build -size short -o test.hex -target=swan examples/blinky1
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
endif
|
endif
|
||||||
ifneq ($(AVR), 0)
|
|
||||||
$(TINYGO) build -size short -o test.hex -target=atmega1284p examples/serial
|
$(TINYGO) build -size short -o test.hex -target=atmega1284p examples/serial
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=arduino examples/blinky1
|
$(TINYGO) build -size short -o test.hex -target=arduino examples/blinky1
|
||||||
|
@ -693,7 +692,6 @@ ifneq ($(AVR), 0)
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=digispark -gc=leaking examples/blinky1
|
$(TINYGO) build -size short -o test.hex -target=digispark -gc=leaking examples/blinky1
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
endif
|
|
||||||
ifneq ($(XTENSA), 0)
|
ifneq ($(XTENSA), 0)
|
||||||
$(TINYGO) build -size short -o test.bin -target=esp32-mini32 examples/blinky1
|
$(TINYGO) build -size short -o test.bin -target=esp32-mini32 examples/blinky1
|
||||||
@$(MD5SUM) test.bin
|
@$(MD5SUM) test.bin
|
||||||
|
|
|
@ -162,6 +162,15 @@ var aeabiBuiltins = []string{
|
||||||
"udivmodsi4.c",
|
"udivmodsi4.c",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var avrBuiltins = []string{
|
||||||
|
"avr/divmodhi4.S",
|
||||||
|
"avr/divmodqi4.S",
|
||||||
|
"avr/mulhi3.S",
|
||||||
|
"avr/mulqi3.S",
|
||||||
|
"avr/udivmodhi4.S",
|
||||||
|
"avr/udivmodqi4.S",
|
||||||
|
}
|
||||||
|
|
||||||
// CompilerRT is a library with symbols required by programs compiled with LLVM.
|
// CompilerRT is a library with symbols required by programs compiled with LLVM.
|
||||||
// These symbols are for operations that cannot be emitted with a single
|
// These symbols are for operations that cannot be emitted with a single
|
||||||
// instruction or a short sequence of instructions for that target.
|
// instruction or a short sequence of instructions for that target.
|
||||||
|
@ -186,6 +195,9 @@ var CompilerRT = Library{
|
||||||
if strings.HasPrefix(target, "arm") || strings.HasPrefix(target, "thumb") {
|
if strings.HasPrefix(target, "arm") || strings.HasPrefix(target, "thumb") {
|
||||||
builtins = append(builtins, aeabiBuiltins...)
|
builtins = append(builtins, aeabiBuiltins...)
|
||||||
}
|
}
|
||||||
|
if strings.HasPrefix(target, "avr") {
|
||||||
|
builtins = append(builtins, avrBuiltins...)
|
||||||
|
}
|
||||||
return builtins, nil
|
return builtins, nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ var picolibcSources = []string{
|
||||||
"libc/tinystdio/fputc.c",
|
"libc/tinystdio/fputc.c",
|
||||||
"libc/tinystdio/fputs.c",
|
"libc/tinystdio/fputs.c",
|
||||||
"libc/tinystdio/fread.c",
|
"libc/tinystdio/fread.c",
|
||||||
"libc/tinystdio/freopen.c",
|
//"libc/tinystdio/freopen.c", // crashes with AVR, see: https://github.com/picolibc/picolibc/pull/369
|
||||||
"libc/tinystdio/fscanf.c",
|
"libc/tinystdio/fscanf.c",
|
||||||
"libc/tinystdio/fseek.c",
|
"libc/tinystdio/fseek.c",
|
||||||
"libc/tinystdio/fseeko.c",
|
"libc/tinystdio/fseeko.c",
|
||||||
|
|
|
@ -37,3 +37,39 @@ func procPin() {
|
||||||
func procUnpin() {
|
func procUnpin() {
|
||||||
interrupt.Restore(procPinnedMask)
|
interrupt.Restore(procPinnedMask)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The following functions are workarounds for things missing in compiler-rt.
|
||||||
|
// They will likely need special assembly implementations.
|
||||||
|
|
||||||
|
//export __mulsi3
|
||||||
|
func __mulsi3(a, b uint32) uint32 {
|
||||||
|
var r uint32
|
||||||
|
for a != 0 {
|
||||||
|
if a&1 != 0 {
|
||||||
|
r += b
|
||||||
|
}
|
||||||
|
a >>= 1
|
||||||
|
b <<= 1
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
//export __divsi3
|
||||||
|
func __divsi3(a, b int32) int32
|
||||||
|
|
||||||
|
//export __udivsi3
|
||||||
|
func __udivsi3(a, b uint32) uint32
|
||||||
|
|
||||||
|
//export __divmodsi4
|
||||||
|
func __divmodsi4(a, b int32) uint64 {
|
||||||
|
d := __divsi3(a, b)
|
||||||
|
rem := a - (d * b)
|
||||||
|
return uint64(uint32(d)) | uint64(uint32(rem))<<32
|
||||||
|
}
|
||||||
|
|
||||||
|
//export __udivmodsi4
|
||||||
|
func __udivmodsi4(a, b uint32) uint64 {
|
||||||
|
d := __udivsi3(a, b)
|
||||||
|
rem := a - (d * b)
|
||||||
|
return uint64(d) | uint64(rem)<<32
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"inherits": ["atmega1280"],
|
"inherits": ["atmega1280"],
|
||||||
"build-tags": ["arduino_mega1280"],
|
"build-tags": ["arduino_mega1280"],
|
||||||
"ldflags": [
|
"ldflags": [
|
||||||
"-Wl,--defsym=_bootloader_size=4096"
|
"--defsym=_bootloader_size=4096"
|
||||||
],
|
],
|
||||||
"flash-command":"avrdude -c arduino -b 57600 -p atmega1280 -P {port} -U flash:w:{hex}:i -v -D"
|
"flash-command":"avrdude -c arduino -b 57600 -p atmega1280 -P {port} -U flash:w:{hex}:i -v -D"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"inherits": ["atmega2560"],
|
"inherits": ["atmega2560"],
|
||||||
"build-tags": ["arduino_mega2560"],
|
"build-tags": ["arduino_mega2560"],
|
||||||
"ldflags": [
|
"ldflags": [
|
||||||
"-Wl,--defsym=_bootloader_size=8192"
|
"--defsym=_bootloader_size=8192"
|
||||||
],
|
],
|
||||||
"flash-command":"avrdude -c wiring -b 115200 -p atmega2560 -P {port} -U flash:w:{hex}:i -v -D"
|
"flash-command":"avrdude -c wiring -b 115200 -p atmega2560 -P {port} -U flash:w:{hex}:i -v -D"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
"inherits": ["atmega328p"],
|
"inherits": ["atmega328p"],
|
||||||
"build-tags": ["arduino_nano"],
|
"build-tags": ["arduino_nano"],
|
||||||
"ldflags": [
|
"ldflags": [
|
||||||
"-Wl,--defsym=_bootloader_size=512",
|
"--defsym=_bootloader_size=512",
|
||||||
"-Wl,--defsym=_stack_size=512"
|
"--defsym=_stack_size=512"
|
||||||
],
|
],
|
||||||
"flash-command": "avrdude -c arduino -p atmega328p -b 57600 -P {port} -U flash:w:{hex}:i",
|
"flash-command": "avrdude -c arduino -p atmega328p -b 57600 -P {port} -U flash:w:{hex}:i",
|
||||||
"emulator": "simavr -m atmega328p -f 16000000 {}"
|
"emulator": "simavr -m atmega328p -f 16000000 {}"
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
"inherits": ["atmega328p"],
|
"inherits": ["atmega328p"],
|
||||||
"build-tags": ["arduino"],
|
"build-tags": ["arduino"],
|
||||||
"ldflags": [
|
"ldflags": [
|
||||||
"-Wl,--defsym=_bootloader_size=512",
|
"--defsym=_bootloader_size=512",
|
||||||
"-Wl,--defsym=_stack_size=512"
|
"--defsym=_stack_size=512"
|
||||||
],
|
],
|
||||||
"flash-command": "avrdude -c arduino -p atmega328p -P {port} -U flash:w:{hex}:i",
|
"flash-command": "avrdude -c arduino -p atmega328p -P {port} -U flash:w:{hex}:i",
|
||||||
"serial-port": ["2341:0043", "2341:0001", "2a03:0043", "2341:0243"],
|
"serial-port": ["2341:0043", "2341:0001", "2a03:0043", "2341:0243"],
|
||||||
|
|
|
@ -4,8 +4,7 @@
|
||||||
"build-tags": ["atmega1280", "atmega"],
|
"build-tags": ["atmega1280", "atmega"],
|
||||||
"serial": "uart",
|
"serial": "uart",
|
||||||
"ldflags": [
|
"ldflags": [
|
||||||
"-mmcu=avr51",
|
"--defsym=_stack_size=512"
|
||||||
"-Wl,--defsym=_stack_size=512"
|
|
||||||
],
|
],
|
||||||
"linkerscript": "src/device/avr/atmega1280.ld",
|
"linkerscript": "src/device/avr/atmega1280.ld",
|
||||||
"extra-files": [
|
"extra-files": [
|
||||||
|
|
|
@ -4,9 +4,8 @@
|
||||||
"build-tags": ["atmega1284p", "atmega"],
|
"build-tags": ["atmega1284p", "atmega"],
|
||||||
"serial": "uart",
|
"serial": "uart",
|
||||||
"ldflags": [
|
"ldflags": [
|
||||||
"-mmcu=avr51",
|
"--defsym=_bootloader_size=0",
|
||||||
"-Wl,--defsym=_bootloader_size=0",
|
"--defsym=_stack_size=512"
|
||||||
"-Wl,--defsym=_stack_size=512"
|
|
||||||
],
|
],
|
||||||
"linkerscript": "src/device/avr/atmega1284p.ld",
|
"linkerscript": "src/device/avr/atmega1284p.ld",
|
||||||
"extra-files": [
|
"extra-files": [
|
||||||
|
|
|
@ -4,8 +4,7 @@
|
||||||
"build-tags": ["atmega2560", "atmega"],
|
"build-tags": ["atmega2560", "atmega"],
|
||||||
"serial": "uart",
|
"serial": "uart",
|
||||||
"ldflags": [
|
"ldflags": [
|
||||||
"-mmcu=avr6",
|
"--defsym=_stack_size=512"
|
||||||
"-Wl,--defsym=_stack_size=512"
|
|
||||||
],
|
],
|
||||||
"linkerscript": "src/device/avr/atmega2560.ld",
|
"linkerscript": "src/device/avr/atmega2560.ld",
|
||||||
"extra-files": [
|
"extra-files": [
|
||||||
|
|
|
@ -3,9 +3,6 @@
|
||||||
"cpu": "atmega328p",
|
"cpu": "atmega328p",
|
||||||
"build-tags": ["atmega328p", "atmega", "avr5"],
|
"build-tags": ["atmega328p", "atmega", "avr5"],
|
||||||
"serial": "uart",
|
"serial": "uart",
|
||||||
"ldflags": [
|
|
||||||
"-mmcu=avr5"
|
|
||||||
],
|
|
||||||
"linkerscript": "src/device/avr/atmega328p.ld",
|
"linkerscript": "src/device/avr/atmega328p.ld",
|
||||||
"extra-files": [
|
"extra-files": [
|
||||||
"targets/avr.S",
|
"targets/avr.S",
|
||||||
|
|
|
@ -5,9 +5,6 @@
|
||||||
"cflags": [
|
"cflags": [
|
||||||
"-D__AVR_ARCH__=25"
|
"-D__AVR_ARCH__=25"
|
||||||
],
|
],
|
||||||
"ldflags": [
|
|
||||||
"-mmcu=avr25"
|
|
||||||
],
|
|
||||||
"linkerscript": "src/device/avr/attiny85.ld",
|
"linkerscript": "src/device/avr/attiny85.ld",
|
||||||
"extra-files": [
|
"extra-files": [
|
||||||
"targets/avr.S",
|
"targets/avr.S",
|
||||||
|
|
|
@ -4,16 +4,17 @@
|
||||||
"goos": "linux",
|
"goos": "linux",
|
||||||
"goarch": "arm",
|
"goarch": "arm",
|
||||||
"gc": "conservative",
|
"gc": "conservative",
|
||||||
"linker": "avr-gcc",
|
"linker": "ld.lld",
|
||||||
"scheduler": "none",
|
"scheduler": "none",
|
||||||
"rtlib": "compiler-rt",
|
"rtlib": "compiler-rt",
|
||||||
|
"libc": "picolibc",
|
||||||
"default-stack-size": 256,
|
"default-stack-size": 256,
|
||||||
"cflags": [
|
"cflags": [
|
||||||
"-Werror"
|
"-Werror"
|
||||||
],
|
],
|
||||||
"ldflags": [
|
"ldflags": [
|
||||||
"-T", "targets/avr.ld",
|
"-T", "targets/avr.ld",
|
||||||
"-Wl,--gc-sections"
|
"--gc-sections"
|
||||||
],
|
],
|
||||||
"extra-files": [
|
"extra-files": [
|
||||||
"src/internal/task/task_stack_avr.S",
|
"src/internal/task/task_stack_avr.S",
|
||||||
|
|
|
@ -5,6 +5,8 @@ MEMORY
|
||||||
RAM (xrw) : ORIGIN = 0x800000 + __ram_start, LENGTH = __ram_size
|
RAM (xrw) : ORIGIN = 0x800000 + __ram_start, LENGTH = __ram_size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENTRY(__vector_RESET)
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
.text :
|
.text :
|
||||||
|
@ -12,9 +14,11 @@ SECTIONS
|
||||||
KEEP(*(.vectors))
|
KEEP(*(.vectors))
|
||||||
KEEP(*(.text.__vector_RESET))
|
KEEP(*(.text.__vector_RESET))
|
||||||
KEEP(*(.text.main)) /* main must follow the reset handler */
|
KEEP(*(.text.main)) /* main must follow the reset handler */
|
||||||
|
*(.text)
|
||||||
*(.text.*)
|
*(.text.*)
|
||||||
*(.progmem)
|
*(.progmem)
|
||||||
*(.progmem.*)
|
*(.progmem.*)
|
||||||
|
. = ALIGN(16); /* needed with ld.lld for some reasoon */
|
||||||
}
|
}
|
||||||
|
|
||||||
.stack (NOLOAD) :
|
.stack (NOLOAD) :
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
"inherits": ["attiny85"],
|
"inherits": ["attiny85"],
|
||||||
"build-tags": ["digispark"],
|
"build-tags": ["digispark"],
|
||||||
"ldflags": [
|
"ldflags": [
|
||||||
"-Wl,--defsym=_bootloader_size=2180",
|
"--defsym=_bootloader_size=2180",
|
||||||
"-Wl,--defsym=_stack_size=128"
|
"--defsym=_stack_size=128"
|
||||||
],
|
],
|
||||||
"flash-command": "micronucleus --run {hex}",
|
"flash-command": "micronucleus --run {hex}",
|
||||||
"emulator": "simavr -m attiny85 -f 16000000 {}"
|
"emulator": "simavr -m attiny85 -f 16000000 {}"
|
||||||
|
|
|
@ -60,7 +60,7 @@ type Device struct {
|
||||||
|
|
||||||
// AddressSpace is the Go version of an XML element like the following:
|
// AddressSpace is the Go version of an XML element like the following:
|
||||||
//
|
//
|
||||||
// <address-space endianness="little" name="data" id="data" start="0x0000" size="0x0900">
|
// <address-space endianness="little" name="data" id="data" start="0x0000" size="0x0900">
|
||||||
//
|
//
|
||||||
// It describes one address space in an AVR microcontroller. One address space
|
// It describes one address space in an AVR microcontroller. One address space
|
||||||
// may have multiple memory segments.
|
// may have multiple memory segments.
|
||||||
|
@ -71,7 +71,7 @@ type AddressSpace struct {
|
||||||
|
|
||||||
// MemorySegment is the Go version of an XML element like the following:
|
// MemorySegment is the Go version of an XML element like the following:
|
||||||
//
|
//
|
||||||
// <memory-segment name="IRAM" start="0x0100" size="0x0800" type="ram" external="false"/>
|
// <memory-segment name="IRAM" start="0x0100" size="0x0800" type="ram" external="false"/>
|
||||||
//
|
//
|
||||||
// It describes a single contiguous area of memory in a particular address space
|
// It describes a single contiguous area of memory in a particular address space
|
||||||
// (see AddressSpace).
|
// (see AddressSpace).
|
||||||
|
@ -432,7 +432,7 @@ __vector_default:
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
; The interrupt vector of this device. Must be placed at address 0 by the linker.
|
||||||
.section .vectors
|
.section .vectors, "a", %progbits
|
||||||
.global __vectors
|
.global __vectors
|
||||||
`))
|
`))
|
||||||
err = t.Execute(out, device.metadata)
|
err = t.Execute(out, device.metadata)
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче