Be able to actually run the blinky example on an nRF
runtime.Sleep() doesn't work yet so it prints a lot of data. Also, this depends on a small patch to nrfx.
Этот коммит содержится в:
родитель
10427c2b6f
коммит
a446b4de97
3 изменённых файлов: 156 добавлений и 17 удалений
97
Makefile
97
Makefile
|
@ -2,27 +2,96 @@
|
|||
# aliases
|
||||
all: tgo
|
||||
tgo: build/tgo
|
||||
test: build/hello.o
|
||||
|
||||
.PHONY: all tgo test run-test clean
|
||||
.PHONY: all tgo run-hello run-blinky flash-blinky clean
|
||||
|
||||
CFLAGS = -Wall -Werror -O2 -g -flto
|
||||
# Custom LLVM toolchain.
|
||||
LLVM =
|
||||
LINK = $(LLVM)llvm-link
|
||||
LLC = $(LLVM)llc
|
||||
|
||||
build/tgo: *.go
|
||||
@mkdir -p build
|
||||
@go build -o build/tgo -i .
|
||||
CFLAGS = -Wall -Werror -Os -g -fno-exceptions -flto -ffunction-sections -fdata-sections $(LLFLAGS)
|
||||
|
||||
build/hello.o: build/tgo src/examples/hello/*.go src/runtime/*.go
|
||||
@./build/tgo -printir -o build/hello.o examples/hello
|
||||
RUNTIME = build/runtime.bc
|
||||
|
||||
build/runtime.o: src/runtime/*.c src/runtime/*.h
|
||||
clang $(CFLAGS) -c -o $@ src/runtime/*.c
|
||||
ifeq ($(TARGET),pca10040)
|
||||
GCC = arm-none-eabi-gcc
|
||||
LD = arm-none-eabi-ld -T arm.ld
|
||||
OBJCOPY = arm-none-eabi-objcopy
|
||||
LLFLAGS += -target armv7m-none-eabi
|
||||
TGOFLAGS += -target $(TARGET)
|
||||
CFLAGS += -I$(CURDIR)/src/runtime
|
||||
CFLAGS += -I$(CURDIR)/lib/nrfx
|
||||
CFLAGS += -I$(CURDIR)/lib/nrfx/mdk
|
||||
CFLAGS += -I$(CURDIR)/lib/CMSIS/CMSIS/Include
|
||||
CFLAGS += -DNRF52832_XXAA
|
||||
CFLAGS += -Wno-uninitialized
|
||||
RUNTIME += build/runtime_nrf.bc
|
||||
RUNTIME += build/system_nrf52.bc
|
||||
OBJ += build/startup_nrf51.o # TODO nrf52, see https://bugs.llvm.org/show_bug.cgi?id=31601
|
||||
|
||||
build/hello: build/hello.o build/runtime.o
|
||||
@clang $(CFLAGS) -o $@ $^
|
||||
else
|
||||
# Regular *nix system.
|
||||
GCC = gcc
|
||||
LD = clang
|
||||
endif
|
||||
|
||||
run-test: build/hello
|
||||
@./build/hello
|
||||
|
||||
|
||||
run-hello: build/hello
|
||||
./build/hello
|
||||
|
||||
run-blinky: build/blinky
|
||||
./build/blinky
|
||||
|
||||
flash-blinky: build/blinky.hex
|
||||
nrfjprog -f nrf52 --sectorerase --program $< --reset
|
||||
|
||||
clean:
|
||||
@rm -rf build
|
||||
|
||||
|
||||
|
||||
# Build the Go compiler.
|
||||
build/tgo: *.go
|
||||
@mkdir -p build
|
||||
go build -o build/tgo -i .
|
||||
|
||||
# Build textual IR with the Go compiler.
|
||||
build/%.ll: src/examples/% src/examples/%/*.go build/tgo src/runtime/*.go
|
||||
./build/tgo $(TGOFLAGS) -printir -o $@ $(subst src/,,$<)
|
||||
|
||||
# Compile C sources for the runtime.
|
||||
build/%.bc: src/runtime/%.c src/runtime/*.h
|
||||
@mkdir -p build
|
||||
clang $(CFLAGS) -c -o $@ $<
|
||||
|
||||
# Compile system_* file for the nRF.
|
||||
build/%.bc: lib/nrfx/mdk/%.c
|
||||
@mkdir -p build
|
||||
clang $(CFLAGS) -c -o $@ $^
|
||||
|
||||
# Compile startup_* file for the nRF.
|
||||
build/%.o: lib/nrfx/mdk/gcc_%.S
|
||||
@mkdir -p build
|
||||
clang $(CFLAGS) -c -o $@ $^
|
||||
|
||||
# Merge all LLVM files together in a single bitcode file.
|
||||
build/%.bc: $(RUNTIME) build/%.ll
|
||||
$(LINK) -o $@ $^
|
||||
|
||||
# Generate an ELF object file from a LLVM bitcode file.
|
||||
build/%.o: build/%.bc
|
||||
$(LLC) -filetype=obj -O2 -o $@ $^
|
||||
|
||||
# Generate output ELF executable.
|
||||
build/%: build/%.o $(OBJ)
|
||||
$(LD) -o $@ $^
|
||||
|
||||
# Generate output ELF for use in objcopy (on a microcontroller).
|
||||
build/%.elf: build/%.o $(OBJ)
|
||||
$(LD) -o $@ $^
|
||||
|
||||
# Convert executable to Intel hex file (for flashing).
|
||||
build/%.hex: build/%.elf
|
||||
$(OBJCOPY) -O ihex $^ $@
|
||||
|
|
63
arm.ld
Обычный файл
63
arm.ld
Обычный файл
|
@ -0,0 +1,63 @@
|
|||
|
||||
MEMORY
|
||||
{
|
||||
FLASH_TEXT (rw) : ORIGIN = 0x00000000, LENGTH = 256K /* .text */
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K
|
||||
}
|
||||
|
||||
|
||||
/* define output sections */
|
||||
SECTIONS
|
||||
{
|
||||
/* The program code and other data goes into FLASH */
|
||||
.text :
|
||||
{
|
||||
_stext = .;
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector))
|
||||
*(.text) /* .text sections (code) */
|
||||
*(.text*) /* .text* sections (code) */
|
||||
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
||||
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||
. = ALIGN(4);
|
||||
_etext = .; /* define a global symbol at end of code */
|
||||
} >FLASH_TEXT
|
||||
|
||||
/* used by the startup to initialize data */
|
||||
_sidata = LOADADDR(.data);
|
||||
|
||||
/* This is the initialized data section
|
||||
The program executes knowing that the data is in the RAM
|
||||
but the loader puts the initial values in the FLASH (inidata).
|
||||
It is one task of the startup to copy the initial values from FLASH to RAM. */
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
|
||||
*(.data) /* .data sections */
|
||||
*(.data*) /* .data* sections */
|
||||
|
||||
. = ALIGN(4);
|
||||
_edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
|
||||
} >RAM AT>FLASH_TEXT
|
||||
|
||||
/* Uninitialized data section */
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sbss = .; /* define a global symbol at bss start; used by startup code */
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN(4);
|
||||
_ebss = .; /* define a global symbol at bss end; used by startup code and GC */
|
||||
} >RAM
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
}
|
||||
|
||||
/* For the nrfx startup file */
|
||||
__etext = _etext;
|
||||
__data_start__ = _sdata;
|
||||
__bss_start__ = _sbss;
|
13
tgo.go
13
tgo.go
|
@ -140,7 +140,7 @@ func NewCompiler(pkgName, triple string) (*Compiler, error) {
|
|||
return c, nil
|
||||
}
|
||||
|
||||
func (c *Compiler) Parse(mainPath string) error {
|
||||
func (c *Compiler) Parse(mainPath string, buildTags []string) error {
|
||||
tripleSplit := strings.Split(c.triple, "-")
|
||||
|
||||
config := loader.Config {
|
||||
|
@ -152,7 +152,7 @@ func (c *Compiler) Parse(mainPath string) error {
|
|||
CgoEnabled: true,
|
||||
UseAllFiles: false,
|
||||
Compiler: "gc", // must be one of the recognized compilers
|
||||
BuildTags: []string{"tgo"},
|
||||
BuildTags: append([]string{"tgo"}, buildTags...),
|
||||
},
|
||||
AllowErrors: true,
|
||||
}
|
||||
|
@ -1074,12 +1074,19 @@ func (c *Compiler) EmitObject(path string) error {
|
|||
|
||||
// Helper function for Compiler object.
|
||||
func Compile(pkgName, outpath, target string, printIR bool) error {
|
||||
var buildTags []string
|
||||
// TODO: put this somewhere else
|
||||
if target == "pca10040" {
|
||||
buildTags = append(buildTags, "nrf")
|
||||
target = "armv7m-none-eabi"
|
||||
}
|
||||
|
||||
c, err := NewCompiler(pkgName, target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parseErr := c.Parse(pkgName)
|
||||
parseErr := c.Parse(pkgName, buildTags)
|
||||
if printIR {
|
||||
fmt.Println(c.IR())
|
||||
}
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче