avr: convert initialization from asm to Go
This increases code size by 1 instruction (2 bytes) because LLVM isn't yet smart enough to recognize that it doesn't need to clear a register to use 0: it can just use r1 which is always 0 according to the convention. It makes initialization a lot easier to read, however.
Этот коммит содержится в:
родитель
0d8a7e1666
коммит
39e3fe28db
5 изменённых файлов: 38 добавлений и 18 удалений
|
@ -22,9 +22,15 @@ var hasScheduler bool
|
||||||
// Entry point for Go. Initialize all packages and call main.main().
|
// Entry point for Go. Initialize all packages and call main.main().
|
||||||
//go:export main
|
//go:export main
|
||||||
func main() int {
|
func main() int {
|
||||||
|
// Initialize memory etc.
|
||||||
|
preinit()
|
||||||
|
|
||||||
// Run initializers of all packages.
|
// Run initializers of all packages.
|
||||||
initAll()
|
initAll()
|
||||||
|
|
||||||
|
// Enable interrupts etc.
|
||||||
|
postinit()
|
||||||
|
|
||||||
// This branch must be optimized away. Only one of the targets must remain,
|
// This branch must be optimized away. Only one of the targets must remain,
|
||||||
// or there will be link errors.
|
// or there will be link errors.
|
||||||
if hasScheduler {
|
if hasScheduler {
|
||||||
|
|
|
@ -4,6 +4,7 @@ package runtime
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"device/avr"
|
"device/avr"
|
||||||
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
const BOARD = "arduino"
|
const BOARD = "arduino"
|
||||||
|
@ -28,6 +29,25 @@ const (
|
||||||
WDT_PERIOD_2S
|
WDT_PERIOD_2S
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_extern__sbss unsafe.Pointer // defined by the linker
|
||||||
|
_extern__ebss unsafe.Pointer // defined by the linker
|
||||||
|
)
|
||||||
|
|
||||||
|
func preinit() {
|
||||||
|
// Initialize .bss: zero-initialized global variables.
|
||||||
|
ptr := uintptr(unsafe.Pointer(&_extern__sbss))
|
||||||
|
for ptr != uintptr(unsafe.Pointer(&_extern__ebss)) {
|
||||||
|
*(*uint8)(unsafe.Pointer(ptr)) = 0
|
||||||
|
ptr += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func postinit() {
|
||||||
|
// Enable interrupts after initialization.
|
||||||
|
avr.Asm("sei")
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
initUART()
|
initUART()
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,12 @@ func _start() {
|
||||||
main()
|
main()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func preinit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func postinit() {
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
initUART()
|
initUART()
|
||||||
initLFCLK()
|
initLFCLK()
|
||||||
|
|
|
@ -24,6 +24,12 @@ type timespec struct {
|
||||||
|
|
||||||
const CLOCK_MONOTONIC_RAW = 4
|
const CLOCK_MONOTONIC_RAW = 4
|
||||||
|
|
||||||
|
func preinit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func postinit() {
|
||||||
|
}
|
||||||
|
|
||||||
func putchar(c byte) {
|
func putchar(c byte) {
|
||||||
_Cfunc_putchar(int(c))
|
_Cfunc_putchar(int(c))
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,30 +11,12 @@ isr:
|
||||||
reset:
|
reset:
|
||||||
clr r1 ; r1 is expected to be 0 by the C calling convention
|
clr r1 ; r1 is expected to be 0 by the C calling convention
|
||||||
|
|
||||||
; Zero .bss
|
|
||||||
clear_bss:
|
|
||||||
ldi xl, lo8(_sbss)
|
|
||||||
ldi xh, hi8(_sbss)
|
|
||||||
clear_bss_loop:
|
|
||||||
ldi yl, lo8(_ebss)
|
|
||||||
ldi yh, hi8(_ebss)
|
|
||||||
cp xl, yl ; if x == y
|
|
||||||
cpc xh, yh
|
|
||||||
breq clear_bss_end
|
|
||||||
st x+, r1 ; zero byte in *x
|
|
||||||
rjmp clear_bss_loop
|
|
||||||
clear_bss_end:
|
|
||||||
|
|
||||||
; Set up the stack pointer.
|
; Set up the stack pointer.
|
||||||
ldi xl, lo8(_stack_top)
|
ldi xl, lo8(_stack_top)
|
||||||
ldi xh, hi8(_stack_top)
|
ldi xh, hi8(_stack_top)
|
||||||
out 0x3d, xl; SPL
|
out 0x3d, xl; SPL
|
||||||
out 0x3e, xh; SPH
|
out 0x3e, xh; SPH
|
||||||
|
|
||||||
; Enable interrupts.
|
|
||||||
; TODO: make sure interrupts are started after all initializers have run.
|
|
||||||
sei
|
|
||||||
|
|
||||||
; main will be placed right after here by the linker script so there's no
|
; main will be placed right after here by the linker script so there's no
|
||||||
; need to jump.
|
; need to jump.
|
||||||
|
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче