micropython / micropython

MicroPython - a lean and efficient Python implementation for microcontrollers and constrained systems
https://micropython.org
Other
18.97k stars 7.59k forks source link

STM32F429 - native, viper, asm_thumb decorators all crash when using SDRAM #4163

Open johnlr opened 5 years ago

johnlr commented 5 years ago

It works ok with all the SDRAM code in place if I don't actually use it. ie. in stm32/main.c use

gc_init(&_heap_start, &_heap_end);

When I attempt to use the SDRAM, the functions seem to compile ok, but when called, the processor resets

dpgeorge commented 5 years ago

There was a recent commit e562f99263f9ffc152b19b2adecc89d637d2e2aa which enabled execution from SDRAM. Are you using the latest version of the code?

johnlr commented 5 years ago

Yep, running latest. I wonder if it's just the F7 that can execute from SDRAM

Section 2.2.3 of this link http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/BABBBICA.html

indicates that it's in a XN region on the F4.

So could the F4 use the system heap for the emitters instead then?

dpgeorge commented 5 years ago

I think the SDRAM region can be changed from XN (never execute) to executable using the MPU. I think it's simply a matter of enabling the MPU in sdram.c for STM32F4 as well as STM32F7.

@johnlr if you change line 237 of sdram.c to #if defined(STM32F4) || defined(STM32F7) does it work?

johnlr commented 5 years ago

Nope. Turns out that 0xD0000000 is never executable even if that is set. The SDRAM can be remapped to 0x90000000 using LL_SYSCFG_EnableFMCMemorySwapping(); and then it works!

However this quick test shows that running viper'd code is much slower running from SDRAM than SRAM

import micropython
from time import ticks_us

micropython.mem_info()

def foo(x):
    for i in range(x):
        x*2

@micropython.native
def foo_n(x):
    for i in range(x):
        x*2

@micropython.viper
def foo_v(x:int)->int:
    for i in range(x):
        x*2

print()
t0=ticks_us();foo(100000);t1=ticks_us();print("BC", t1-t0)
t0=ticks_us();foo_n(100000);t1=ticks_us();print("NATIVE", t1-t0)
t0=ticks_us();foo_v(100000);t1=ticks_us();print("VIPER", t1-t0)

For SDRAM: stack: 1028 out of 80896 GC: total: 8196480, used: 1472, free: 8195008 No. of 1-blocks: 28, 2-blocks: 4, max blk sz: 14, max free sz: 512051

BC 491596 NATIVE 369743 VIPER 128824

NOSDRAM: stack: 1028 out of 80896 GC: total: 102976, used: 1472, free: 101504 No. of 1-blocks: 28, 2-blocks: 4, max blk sz: 14, max free sz: 6207

BC 345493 NATIVE 185786 VIPER 25683

andrewleech commented 5 years ago

As we started talking about during sdram driver review, if/once #3580 is done we could still have the internal ram operational and look at splitting allocation up based on block sizes? hint the gc to try to assign small objects in the faster internal, larger objects in external.

It would probably be worthwhile to change the sdram driver over to using the remapped space by default on F4 else the exec issue will hit more people!