Обновление
This commit is contained in:
parent
ab35a1932e
commit
19a0f33d34
152
Src/BootJump.c
152
Src/BootJump.c
|
|
@ -16,77 +16,8 @@ typedef void (*pFunction)(void);
|
||||||
|
|
||||||
#define EnablePrivilegedMode() __asm("SVC #0")
|
#define EnablePrivilegedMode() __asm("SVC #0")
|
||||||
|
|
||||||
void BootJumpToAddress(const uint32_t address) {
|
|
||||||
// 1. ГЛОБАЛЬНО отключаем прерывания (первое, что делаем)
|
|
||||||
__disable_irq();
|
|
||||||
|
|
||||||
// 2. Отключаем ВСЕ прерывания в NVIC
|
void DeInitAll() {
|
||||||
for (int i = 0; i < 8; i++) { // Обычно достаточно 8 банков для всех прерываний
|
|
||||||
NVIC->ICER[i] = 0xFFFFFFFF;
|
|
||||||
NVIC->ICPR[i] = 0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Останавливаем SysTick и сбрасываем
|
|
||||||
SysTick->CTRL = 0;
|
|
||||||
SysTick->LOAD = 0;
|
|
||||||
SysTick->VAL = 0;
|
|
||||||
|
|
||||||
// 4. Сбрасываем все pending-флаги
|
|
||||||
SCB->ICSR |= SCB_ICSR_PENDSVCLR_Msk | SCB_ICSR_PENDSTCLR_Msk;
|
|
||||||
|
|
||||||
// 5. Отключаем периферию, которая может генерировать прерывания
|
|
||||||
|
|
||||||
// 5.1. DMA
|
|
||||||
DMA_DeInit(DMA_INSTANCE_0);
|
|
||||||
|
|
||||||
// 5.2. UART
|
|
||||||
for (uint8_t i = 0; i < FCUART_INSTANCE_COUNT; ++i) {
|
|
||||||
FCUART_DeInit(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5.3 RESET CLK
|
|
||||||
PCC_GenPeripheralReset(PCC_CLK_DMA0);
|
|
||||||
PCC_GenPeripheralReset(PCC_CLK_DMAMUX0);
|
|
||||||
PCC_GenPeripheralReset(PCC_CLK_FCUART0);
|
|
||||||
PCC_GenPeripheralReset(PCC_CLK_FCUART1);
|
|
||||||
PCC_GenPeripheralReset(PCC_CLK_FCUART2);
|
|
||||||
PCC_GenPeripheralReset(PCC_CLK_FCUART3);
|
|
||||||
PCC_GenPeripheralReset(PCC_CLK_FCUART4);
|
|
||||||
PCC_GenPeripheralReset(PCC_CLK_FCUART5);
|
|
||||||
PCC_GenPeripheralReset(PCC_CLK_FCUART6);
|
|
||||||
PCC_GenPeripheralReset(PCC_CLK_FCUART7);
|
|
||||||
|
|
||||||
|
|
||||||
// 6. Подготовка процессора
|
|
||||||
if (CONTROL_nPRIV_Msk & __get_CONTROL()) {
|
|
||||||
EnablePrivilegedMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CONTROL_SPSEL_Msk & __get_CONTROL()) {
|
|
||||||
__set_MSP(__get_PSP());
|
|
||||||
__set_CONTROL(__get_CONTROL() & ~CONTROL_SPSEL_Msk);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 7. Получаем стек и точку входа приложения
|
|
||||||
uint32_t appStack = *((__IO uint32_t *) address);
|
|
||||||
pFunction appEntry = (pFunction) *((__IO uint32_t *) (address + 4));
|
|
||||||
|
|
||||||
// 8. Устанавливаем VTOR и стек
|
|
||||||
SCB->VTOR = address;
|
|
||||||
__set_MSP(appStack);
|
|
||||||
|
|
||||||
// 9. Очищаем регистры, которые могут содержать данные загрузчика
|
|
||||||
__ISB(); // Instruction Synchronization Barrier
|
|
||||||
__DSB(); // Data Synchronization Barrier
|
|
||||||
|
|
||||||
// 10. Переход БЕЗ включения прерываний!
|
|
||||||
// Приложение само должно включить прерывания после инициализации
|
|
||||||
appEntry();
|
|
||||||
|
|
||||||
while (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reset() {
|
|
||||||
// 1. ГЛОБАЛЬНО отключаем прерывания (первое, что делаем)
|
// 1. ГЛОБАЛЬНО отключаем прерывания (первое, что делаем)
|
||||||
__disable_irq();
|
__disable_irq();
|
||||||
|
|
||||||
|
|
@ -128,7 +59,7 @@ void Reset() {
|
||||||
TPU_DeInit();
|
TPU_DeInit();
|
||||||
|
|
||||||
|
|
||||||
// 5.3 RESET CLK
|
// 5.6 RESET CLK
|
||||||
PCC_GenPeripheralReset(PCC_CLK_DMA0);
|
PCC_GenPeripheralReset(PCC_CLK_DMA0);
|
||||||
PCC_GenPeripheralReset(PCC_CLK_DMAMUX0);
|
PCC_GenPeripheralReset(PCC_CLK_DMAMUX0);
|
||||||
PCC_GenPeripheralReset(PCC_CLK_FLEXCAN0);
|
PCC_GenPeripheralReset(PCC_CLK_FLEXCAN0);
|
||||||
|
|
@ -146,6 +77,85 @@ void Reset() {
|
||||||
PCC_GenPeripheralReset(PCC_CLK_FCUART6);
|
PCC_GenPeripheralReset(PCC_CLK_FCUART6);
|
||||||
PCC_GenPeripheralReset(PCC_CLK_FCUART7);
|
PCC_GenPeripheralReset(PCC_CLK_FCUART7);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void BootJumpToAddress(const uint32_t address) {
|
||||||
|
/*
|
||||||
|
// 1. ГЛОБАЛЬНО отключаем прерывания (первое, что делаем)
|
||||||
|
__disable_irq();
|
||||||
|
|
||||||
|
// 2. Отключаем ВСЕ прерывания в NVIC
|
||||||
|
for (int i = 0; i < 8; i++) { // Обычно достаточно 8 банков для всех прерываний
|
||||||
|
NVIC->ICER[i] = 0xFFFFFFFF;
|
||||||
|
NVIC->ICPR[i] = 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Останавливаем SysTick и сбрасываем
|
||||||
|
SysTick->CTRL = 0;
|
||||||
|
SysTick->LOAD = 0;
|
||||||
|
SysTick->VAL = 0;
|
||||||
|
|
||||||
|
// 4. Сбрасываем все pending-флаги
|
||||||
|
SCB->ICSR |= SCB_ICSR_PENDSVCLR_Msk | SCB_ICSR_PENDSTCLR_Msk;
|
||||||
|
|
||||||
|
// 5. Отключаем периферию, которая может генерировать прерывания
|
||||||
|
|
||||||
|
// 5.1. DMA
|
||||||
|
DMA_DeInit(DMA_INSTANCE_0);
|
||||||
|
|
||||||
|
// 5.2. UART
|
||||||
|
for (uint8_t i = 0; i < FCUART_INSTANCE_COUNT; ++i) {
|
||||||
|
FCUART_DeInit(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.3 RESET CLK
|
||||||
|
PCC_GenPeripheralReset(PCC_CLK_DMA0);
|
||||||
|
PCC_GenPeripheralReset(PCC_CLK_DMAMUX0);
|
||||||
|
PCC_GenPeripheralReset(PCC_CLK_FCUART0);
|
||||||
|
PCC_GenPeripheralReset(PCC_CLK_FCUART1);
|
||||||
|
PCC_GenPeripheralReset(PCC_CLK_FCUART2);
|
||||||
|
PCC_GenPeripheralReset(PCC_CLK_FCUART3);
|
||||||
|
PCC_GenPeripheralReset(PCC_CLK_FCUART4);
|
||||||
|
PCC_GenPeripheralReset(PCC_CLK_FCUART5);
|
||||||
|
PCC_GenPeripheralReset(PCC_CLK_FCUART6);
|
||||||
|
PCC_GenPeripheralReset(PCC_CLK_FCUART7);
|
||||||
|
|
||||||
|
*/
|
||||||
|
DeInitAll();
|
||||||
|
|
||||||
|
// 6. Подготовка процессора
|
||||||
|
if (CONTROL_nPRIV_Msk & __get_CONTROL()) {
|
||||||
|
EnablePrivilegedMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CONTROL_SPSEL_Msk & __get_CONTROL()) {
|
||||||
|
__set_MSP(__get_PSP());
|
||||||
|
__set_CONTROL(__get_CONTROL() & ~CONTROL_SPSEL_Msk);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. Получаем стек и точку входа приложения
|
||||||
|
uint32_t appStack = *((__IO uint32_t *) address);
|
||||||
|
pFunction appEntry = (pFunction) *((__IO uint32_t *) (address + 4));
|
||||||
|
|
||||||
|
// 8. Устанавливаем VTOR и стек
|
||||||
|
SCB->VTOR = address;
|
||||||
|
__set_MSP(appStack);
|
||||||
|
|
||||||
|
// 9. Очищаем регистры, которые могут содержать данные загрузчика
|
||||||
|
__ISB(); // Instruction Synchronization Barrier
|
||||||
|
__DSB(); // Data Synchronization Barrier
|
||||||
|
|
||||||
|
// 10. Переход БЕЗ включения прерываний!
|
||||||
|
// Приложение само должно включить прерывания после инициализации
|
||||||
|
appEntry();
|
||||||
|
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset() {
|
||||||
|
|
||||||
|
DeInitAll();
|
||||||
|
|
||||||
NVIC_SystemReset();
|
NVIC_SystemReset();
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue