Работает!
Внутри процесса FreeRTOS Heap и стек выделяются динамически и передаются в init_go() Потом работают функции, требующие heap Работает и GC! Когда память заканчивается - очистка и всё по-новой! call_start_cpu0 переименован, чтобы не мешать основной прошивке malloc/free убраны для того же GC/scanstack требует текущий указатель стека, но выход в асм почему-то не работает. Зато простая специальная функция делает это. bss не инициализируется - т.к. это уже делает основная прошивка.
Этот коммит содержится в:
родитель
7c34f7704e
коммит
3fe4d0f1c5
4 изменённых файлов: 32 добавлений и 11 удалений
|
@ -7,11 +7,11 @@
|
||||||
#define PS_WOE PS_WOE_MASK
|
#define PS_WOE PS_WOE_MASK
|
||||||
|
|
||||||
// Only calling it call_start_cpu0 for consistency with ESP-IDF.
|
// Only calling it call_start_cpu0 for consistency with ESP-IDF.
|
||||||
.section .text.call_start_cpu0
|
.section .text.call_start_cpu0_go
|
||||||
1:
|
1:
|
||||||
.long _stack_top
|
.long _stack_top
|
||||||
.global call_start_cpu0
|
.global call_start_cpu0_go
|
||||||
call_start_cpu0:
|
call_start_cpu0_go:
|
||||||
// We need to set the stack pointer to a different value. This is somewhat
|
// We need to set the stack pointer to a different value. This is somewhat
|
||||||
// complicated in the Xtensa architecture. The code below is a modified
|
// complicated in the Xtensa architecture. The code below is a modified
|
||||||
// version of the following code:
|
// version of the following code:
|
||||||
|
|
|
@ -6,10 +6,8 @@ import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:extern _heap_start
|
|
||||||
var heapStartSymbol [0]byte
|
var heapStartSymbol [0]byte
|
||||||
|
|
||||||
//go:extern _heap_end
|
|
||||||
var heapEndSymbol [0]byte
|
var heapEndSymbol [0]byte
|
||||||
|
|
||||||
//go:extern _globals_start
|
//go:extern _globals_start
|
||||||
|
@ -18,7 +16,6 @@ var globalsStartSymbol [0]byte
|
||||||
//go:extern _globals_end
|
//go:extern _globals_end
|
||||||
var globalsEndSymbol [0]byte
|
var globalsEndSymbol [0]byte
|
||||||
|
|
||||||
//go:extern _stack_top
|
|
||||||
var stackTopSymbol [0]byte
|
var stackTopSymbol [0]byte
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -36,20 +33,17 @@ func growHeap() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
//export malloc
|
|
||||||
func libc_malloc(size uintptr) unsafe.Pointer {
|
func libc_malloc(size uintptr) unsafe.Pointer {
|
||||||
// Note: this zeroes the returned buffer which is not necessary.
|
// Note: this zeroes the returned buffer which is not necessary.
|
||||||
// The same goes for bytealg.MakeNoZero.
|
// The same goes for bytealg.MakeNoZero.
|
||||||
return alloc(size, nil)
|
return alloc(size, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export calloc
|
|
||||||
func libc_calloc(nmemb, size uintptr) unsafe.Pointer {
|
func libc_calloc(nmemb, size uintptr) unsafe.Pointer {
|
||||||
// No difference between calloc and malloc.
|
// No difference between calloc and malloc.
|
||||||
return libc_malloc(nmemb * size)
|
return libc_malloc(nmemb * size)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export free
|
|
||||||
func libc_free(ptr unsafe.Pointer) {
|
func libc_free(ptr unsafe.Pointer) {
|
||||||
free(ptr)
|
free(ptr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ func scanCurrentStack()
|
||||||
|
|
||||||
//go:export tinygo_scanstack
|
//go:export tinygo_scanstack
|
||||||
func scanstack(sp uintptr) {
|
func scanstack(sp uintptr) {
|
||||||
|
sp = getCurrentStackPointer()
|
||||||
// Mark current stack.
|
// Mark current stack.
|
||||||
// This function is called by scanCurrentStack, after pushing all registers onto the stack.
|
// This function is called by scanCurrentStack, after pushing all registers onto the stack.
|
||||||
// Callee-saved registers have been pushed onto stack by tinygo_localscan, so this will scan them too.
|
// Callee-saved registers have been pushed onto stack by tinygo_localscan, so this will scan them too.
|
||||||
|
|
|
@ -59,10 +59,36 @@ func main() {
|
||||||
exit(0)
|
exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:extern _sbss
|
//export init_go
|
||||||
|
func init_go(heap_start uintptr, heap_length int) {
|
||||||
|
stackTop = getCurrentStackPointer()
|
||||||
|
println("stackTop:", stackTop, "\n")
|
||||||
|
// Disable the protection on the watchdog timer (needed when started from
|
||||||
|
// the bootloader).
|
||||||
|
esp.RTC_CNTL.WDTWPROTECT.Set(0x050D83AA1)
|
||||||
|
|
||||||
|
// Disable both watchdog timers that are enabled by default on startup.
|
||||||
|
// Note that these watchdogs can be protected, but the ROM bootloader
|
||||||
|
// doesn't seem to protect them.
|
||||||
|
esp.RTC_CNTL.WDTCONFIG0.Set(0)
|
||||||
|
esp.TIMG0.WDTCONFIG0.Set(0)
|
||||||
|
|
||||||
|
// Чистить BSS можно только свой. Т.е. когда при сборке tinygo BSS будет в отдельной секции
|
||||||
|
// clearbss()
|
||||||
|
|
||||||
|
// Initialize main system timer used for time.Now.
|
||||||
|
initTimer()
|
||||||
|
|
||||||
|
// Initialize the heap, call main.main, etc.
|
||||||
|
heapStart = heap_start
|
||||||
|
heapEnd = heap_start + uintptr(heap_length)
|
||||||
|
|
||||||
|
initHeap()
|
||||||
|
initAll()
|
||||||
|
}
|
||||||
|
|
||||||
var _sbss [0]byte
|
var _sbss [0]byte
|
||||||
|
|
||||||
//go:extern _ebss
|
|
||||||
var _ebss [0]byte
|
var _ebss [0]byte
|
||||||
|
|
||||||
func abort() {
|
func abort() {
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче