diff --git a/ion/src/device/n0200/drivers/board.cpp b/ion/src/device/n0200/drivers/board.cpp index ce9c30ebf..f370dad03 100644 --- a/ion/src/device/n0200/drivers/board.cpp +++ b/ion/src/device/n0200/drivers/board.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -85,7 +86,7 @@ void initMPU() { Cache::isb(); } -void init(bool initBacklight) { +void init() { initFPU(); initMPU(); initClocks(); @@ -106,7 +107,7 @@ void init(bool initBacklight) { GPIO(g).PUPDR()->set(0x00000000); // All to "None" } - initPeripherals(initBacklight); + ExternalFlash::init(); // Initiate L1 cache after initiating the external flash Cache::enable(); } diff --git a/ion/src/device/n0200/flash.ld b/ion/src/device/n0200/flash.ld index c68964716..64769cea1 100644 --- a/ion/src/device/n0200/flash.ld +++ b/ion/src/device/n0200/flash.ld @@ -48,12 +48,12 @@ SECTIONS { /* Internal flash memory */ - /* We link 'non_inlined_ion_main' in a separate section from text.internal. + /* We link 'jump_to_external_flash' in a separate section from text.internal. * Indeed, it is the only internal flash symbol that refers the external * flash. This way we can assert that there are no cross references from the * internal flash to the external flash. */ .text.internal_to_external : { - *(.text._ZL20non_inlined_ion_mainv) + *(.text._ZL22jump_to_external_flashv) } >INTERNAL_FLASH /* Use boot routine and required dependencies */ @@ -61,38 +61,44 @@ SECTIONS { * done with -fdata-sections -ffunction-sections */ .text.internal : { . = ALIGN(4); - *(.text.__assert) - *(.text.start) *(.text.abort) *(.text.isr_systick) + *(.text.__assert) *(.text.memcpy) + *(.text.memset) + /* *(.text.strlen) *(.text.strncmp) *(.text.strlcpy) *(.text.strcmp) - *(.text.memset) *(.text.memmove) - *(.text._ZN3Ion*) - *(.text._ZNV3Ion*) - *(.text._ZNK3Ion*) - *(.text.LZ4_*) + */ + /* 'start' dependecies */ + *(.text.start) + *(.text._ZN3Ion6Device5Board4initEv) + *(.text._ZN3Ion6Device5Board7initFPUEv) + *(.text._ZN3Ion6Device5Board7initMPUEv) + *(.text._ZN3Ion6Device5Board10initClocksEv) + *(.text._ZNV3Ion6Device4Regs8Register*) + *(.text._ZN3Ion6Device4Regs8Register*) + *(.text._ZNK3Ion6Device4Regs9AFGPIOPin*) + *(.text._ZN3Ion6Device13ExternalFlash*) + *(.text._ZN3Ion6Device5Cache*) + *(.text._ZN3Ion6Timing6usleepEj) + + /* 'abort' dependcies */ + *(.text._ZN3Ion6Device5Reset4coreEv) + + /**(.text._ZN3Ion5Power7suspendEb)*/ + + /* Optimization */ */libgcc.a:(.text) } >INTERNAL_FLASH .rodata.internal : { . = ALIGN(4); - *(.rodata.dfu_bootloader) - *(.rodata) - *(.rodata.str1.1) - *(.rodata._ZN3Ion*) - *(.rodata._ZZN3Ion*) - *(.rodata._ZNK3Ion*) - *(.rodata._ZTVN3Ion6*) - *(.rodata._ZN3KDColor*) - *(.rodata._ZL11KDColor*) - *(.rodata._ZL12KDColor*) - *(.rodata._ZL13KDColor*) + *(.rodata._ZN3Ion6Device13ExternalFlash*) } >INTERNAL_FLASH /* External flash memory */ @@ -103,6 +109,7 @@ SECTIONS { } >EXTERNAL_FLASH .rodata.external : { + *(.rodata) *(.rodata.*) } >EXTERNAL_FLASH diff --git a/ion/src/device/shared/boot/rt0.cpp b/ion/src/device/shared/boot/rt0.cpp index c43115dfd..63f76eaf5 100644 --- a/ion/src/device/shared/boot/rt0.cpp +++ b/ion/src/device/shared/boot/rt0.cpp @@ -27,7 +27,23 @@ void abort() { #endif } -/* This additional function call 'non_inlined_ion_main' serves two purposes: +/* In order to ensure that this method is execute from the external flash, we + * forbid inlining it.*/ + +static void __attribute__((noinline)) external_flash_start() { + /* Init the peripherals. If there is the on boarding app, do not initialize the + * backlight so that the user does not see the LCD tests. The backlight will + * be initialized after the Power-On Self-Test.*/ +#if EPSILON_ONBOARDING_APP == 0 + Ion::Device::Board::initPeripherals(true); +#else + Ion::Device::Board::initPeripherals(false); +#endif + + return ion_main(0, nullptr); +} + +/* This additional function call 'jump_to_external_flash' serves two purposes: * - By default, the compiler is free to inline any function call he wants. If * the compiler decides to inline some functions that make use of VFP * registers, it will need to push VFP them onto the stack in calling @@ -40,16 +56,20 @@ void abort() { * start(), we isolate it in its very own non-inlined function call. * - To avoid jumping on the external flash when it is shut down, we ensure * there is no symbol references from the internal flash to the external - * flash except the jump to ion_main. In order to do that, we isolate this + * flash except this jump. In order to do that, we isolate this * jump in a symbol that we link in a special section separated from the * internal flash section. We can than forbid cross references from the * internal flash to the external flash. */ -static void __attribute__((noinline)) non_inlined_ion_main() { - return ion_main(0, nullptr); +static void __attribute__((noinline)) jump_to_external_flash() { + external_flash_start(); } -void start() { +/* When 'start' is executed, the external flash is supposed to be shutdown. We + * thus forbid inlining to prevent executing this code from external flash + * (just in case 'start' was to be called from the external flash). */ + +void __attribute__((noinline)) start() { /* This is where execution starts after reset. * Many things are not initialized yet so the code here has to pay attention. */ @@ -90,16 +110,12 @@ void start() { } #endif - /* Init the board. If there is the on boarding app, do not initialize the - * backlight so that the user does not see the LCD tests. The backlight will - * be initialized after the Power-On Self-Test.*/ -#if EPSILON_ONBOARDING_APP == 0 - Ion::Device::Board::init(true); -#else - Ion::Device::Board::init(false); -#endif + Ion::Device::Board::init(); - non_inlined_ion_main(); + /* At this point, we initialized clocks and the external flash but no other + * peripherals. */ + + jump_to_external_flash(); abort(); } diff --git a/ion/src/device/shared/drivers/board.cpp b/ion/src/device/shared/drivers/board.cpp index e8300d69b..ffdcc222e 100644 --- a/ion/src/device/shared/drivers/board.cpp +++ b/ion/src/device/shared/drivers/board.cpp @@ -42,11 +42,9 @@ void initPeripherals(bool initBacklight) { Console::init(); SWD::init(); Timing::init(); - ExternalFlash::init(); } void shutdownPeripherals(bool keepLEDAwake) { - ExternalFlash::shutdown(); Timing::shutdown(); SWD::shutdown(); Console::shutdown(); diff --git a/ion/src/device/shared/drivers/board.h b/ion/src/device/shared/drivers/board.h index 31acc0941..9bcb5388d 100644 --- a/ion/src/device/shared/drivers/board.h +++ b/ion/src/device/shared/drivers/board.h @@ -5,7 +5,7 @@ namespace Ion { namespace Device { namespace Board { -void init(bool initBacklight = true); +void init(); void shutdown(); void initFPU();