runtime/nrf: translate nrf sleep function from C to Go
This is the last critical part of the C runtime. Code size is reduced by 4 bytes for examples/blinky2 (probably due to inlining) and is unchanged for examples/test.
Этот коммит содержится в:
родитель
67e33ac30e
коммит
f7f7d4cbbc
3 изменённых файлов: 27 добавлений и 39 удалений
6
Makefile
6
Makefile
|
@ -36,7 +36,6 @@ CFLAGS += -I$(CURDIR)/lib/nrfx/mdk
|
||||||
CFLAGS += -I$(CURDIR)/lib/CMSIS/CMSIS/Include
|
CFLAGS += -I$(CURDIR)/lib/CMSIS/CMSIS/Include
|
||||||
CFLAGS += -DNRF52832_XXAA
|
CFLAGS += -DNRF52832_XXAA
|
||||||
CFLAGS += -Wno-uninitialized
|
CFLAGS += -Wno-uninitialized
|
||||||
RUNTIME_PARTS += build/runtime_nrf.bc
|
|
||||||
RUNTIME_PARTS += build/nrfx_system_nrf52.bc
|
RUNTIME_PARTS += build/nrfx_system_nrf52.bc
|
||||||
OBJ += build/nrfx_startup_nrf51.o # TODO nrf52, see https://bugs.llvm.org/show_bug.cgi?id=31601
|
OBJ += build/nrfx_startup_nrf51.o # TODO nrf52, see https://bugs.llvm.org/show_bug.cgi?id=31601
|
||||||
|
|
||||||
|
@ -98,11 +97,6 @@ build/tgo: *.go
|
||||||
build/%.o: src/examples/% src/examples/%/*.go build/tgo src/runtime/*.go build/runtime-$(TARGET)-combined.bc
|
build/%.o: src/examples/% src/examples/%/*.go build/tgo src/runtime/*.go build/runtime-$(TARGET)-combined.bc
|
||||||
./build/tgo build $(TGOFLAGS) -runtime build/runtime-$(TARGET)-combined.bc -o $@ $(subst src/,,$<)
|
./build/tgo build $(TGOFLAGS) -runtime build/runtime-$(TARGET)-combined.bc -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 LLVM bitcode from LLVM source.
|
# Compile LLVM bitcode from LLVM source.
|
||||||
build/%.bc: src/runtime/%.ll
|
build/%.bc: src/runtime/%.ll
|
||||||
$(LLAS) -o $@ $<
|
$(LLAS) -o $@ $<
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
|
|
||||||
#include "hal/nrf_gpio.h"
|
|
||||||
#include "hal/nrf_uart.h"
|
|
||||||
#include "nrf.h"
|
|
||||||
#include "runtime.h"
|
|
||||||
#include "runtime_nrf.h"
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
static volatile bool rtc_wakeup;
|
|
||||||
|
|
||||||
void rtc_sleep(uint32_t ticks) {
|
|
||||||
NRF_RTC0->INTENSET = RTC_INTENSET_COMPARE0_Msk;
|
|
||||||
rtc_wakeup = false;
|
|
||||||
if (ticks == 1) {
|
|
||||||
// Race condition (even in hardware) at ticks == 1.
|
|
||||||
// TODO: fix this in a better way by detecting it, like the manual
|
|
||||||
// describes.
|
|
||||||
ticks = 2;
|
|
||||||
}
|
|
||||||
NRF_RTC0->CC[0] = (NRF_RTC0->COUNTER + ticks) & 0x00ffffff;
|
|
||||||
while (!rtc_wakeup) {
|
|
||||||
__WFI();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RTC0_IRQHandler() {
|
|
||||||
NRF_RTC0->INTENCLR = RTC_INTENSET_COMPARE0_Msk;
|
|
||||||
NRF_RTC0->EVENTS_COMPARE[0] = 0;
|
|
||||||
rtc_wakeup = true;
|
|
||||||
}
|
|
|
@ -7,8 +7,6 @@ import (
|
||||||
"device/nrf"
|
"device/nrf"
|
||||||
)
|
)
|
||||||
|
|
||||||
func _Cfunc_rtc_sleep(ticks uint32)
|
|
||||||
|
|
||||||
const Microsecond = 1
|
const Microsecond = 1
|
||||||
|
|
||||||
//go:export _start
|
//go:export _start
|
||||||
|
@ -55,7 +53,7 @@ func sleep(d Duration) {
|
||||||
for ticks64 != 0 {
|
for ticks64 != 0 {
|
||||||
monotime() // update timestamp
|
monotime() // update timestamp
|
||||||
ticks := uint32(ticks64) & 0x7fffff // 23 bits (to be on the safe side)
|
ticks := uint32(ticks64) & 0x7fffff // 23 bits (to be on the safe side)
|
||||||
_Cfunc_rtc_sleep(ticks) // TODO: not accurate (must be d / 30.5175...)
|
rtc_sleep(ticks) // TODO: not accurate (must be d / 30.5175...)
|
||||||
ticks64 -= Duration(ticks)
|
ticks64 -= Duration(ticks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,3 +86,29 @@ func abort() {
|
||||||
func align(ptr uintptr) uintptr {
|
func align(ptr uintptr) uintptr {
|
||||||
return (ptr + 3) &^ 3
|
return (ptr + 3) &^ 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type __volatile bool
|
||||||
|
|
||||||
|
var rtc_wakeup __volatile
|
||||||
|
|
||||||
|
func rtc_sleep(ticks uint32) {
|
||||||
|
nrf.RTC0.INTENSET = nrf.RTC0_INTENSET_COMPARE0_Msk
|
||||||
|
rtc_wakeup = false
|
||||||
|
if ticks == 1 {
|
||||||
|
// Race condition (even in hardware) at ticks == 1.
|
||||||
|
// TODO: fix this in a better way by detecting it, like the manual
|
||||||
|
// describes.
|
||||||
|
ticks = 2
|
||||||
|
}
|
||||||
|
nrf.RTC0.CC[0] = (nrf.RTC0.COUNTER + nrf.RegValue(ticks)) & 0x00ffffff
|
||||||
|
for !rtc_wakeup {
|
||||||
|
arm.Asm("wfi")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:export RTC0_IRQHandler
|
||||||
|
func RTC0_IRQHandler() {
|
||||||
|
nrf.RTC0.INTENCLR = nrf.RTC0_INTENSET_COMPARE0_Msk
|
||||||
|
nrf.RTC0.EVENTS_COMPARE[0] = 0
|
||||||
|
rtc_wakeup = true
|
||||||
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче