Обновление

This commit is contained in:
cfif 2026-06-20 11:28:57 +03:00
parent ab35a1932e
commit 19a0f33d34
1 changed files with 81 additions and 71 deletions

View File

@ -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();
} }