diff --git a/Inc/BootJump.h b/Inc/BootJump.h index 9f202f1..059a109 100644 --- a/Inc/BootJump.h +++ b/Inc/BootJump.h @@ -7,6 +7,7 @@ #include "stdint.h" +void BootFastJumpToAddress(const uint32_t address); void BootJumpToAddress(const uint32_t address); void Reset(); diff --git a/Src/BootJump.c b/Src/BootJump.c index d21b881..9a301a0 100644 --- a/Src/BootJump.c +++ b/Src/BootJump.c @@ -150,6 +150,40 @@ void BootJumpToAddress(const uint32_t address) { while (1); } + +void BootFastJumpToAddress(const uint32_t address) { + + + // 1. Подготовка процессора + if (CONTROL_nPRIV_Msk & __get_CONTROL()) { + EnablePrivilegedMode(); + } + + if (CONTROL_SPSEL_Msk & __get_CONTROL()) { + __set_MSP(__get_PSP()); + __set_CONTROL(__get_CONTROL() & ~CONTROL_SPSEL_Msk); + } + + // 2. Получаем стек и точку входа приложения + uint32_t appStack = *((__IO uint32_t *) address); + pFunction appEntry = (pFunction) *((__IO uint32_t *) (address + 4)); + + // 3. Устанавливаем VTOR и стек + SCB->VTOR = address; + __set_MSP(appStack); + + // 4. Очищаем регистры, которые могут содержать данные загрузчика + __ISB(); // Instruction Synchronization Barrier + __DSB(); // Data Synchronization Barrier + + // 5. Переход БЕЗ включения прерываний! + // Приложение само должно включить прерывания после инициализации + appEntry(); + + while (1); +} + + void Reset() { // DeInitAll();