// // Created by xemon on 02.11.22. // #include CMSIS_device_header typedef void (*pFunction)(void); __attribute__(( naked, noreturn )) void BootJumpASM(uint32_t SP, uint32_t RH) { __asm("MSR MSP,r0"); __asm("BX r1"); } #define EnablePrivilegedMode() __asm("SVC #0") static void BootJumpA(uint32_t *Address) { if (CONTROL_nPRIV_Msk & __get_CONTROL()) //THIS is from the arm doku, but it is always false in our implementation and skipped. { /* not in privileged mode */ EnablePrivilegedMode( ) ; } NVIC->ICER[0] = 0xFFFFFFFF; NVIC->ICPR[0] = 0xFFFFFFFF; SysTick->CTRL = 0; SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk; if (CONTROL_SPSEL_Msk & __get_CONTROL()) //THIS is from the arm doku, but it is always false in our implementation and skipped. (only 1 stack pointer used) { /* MSP is not active */ __set_MSP(__get_PSP()); __set_CONTROL(__get_CONTROL() & ~CONTROL_SPSEL_Msk); } SCB->VTOR = (uint32_t) Address; //Setting the Vector Table Offset Register to the start of the user app. // BootJumpASM(Address[0], Address[1]); //This function is taken from the Arm Documentation } void BootJumpToAddress(const uint32_t address) { BootJumpA(address); // // while (1); #if defined (AT32F437xx) __disable_irq(); /* ahb periph1 */ crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, FALSE); /*!< gpioa periph clock */ crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, FALSE); /*!< gpiob periph clock */ crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, FALSE); /*!< gpioc periph clock */ crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, FALSE); /*!< gpiod periph clock */ crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, FALSE); /*!< gpioe periph clock */ crm_periph_clock_enable(CRM_GPIOF_PERIPH_CLOCK, FALSE); /*!< gpiof periph clock */ crm_periph_clock_enable(CRM_GPIOG_PERIPH_CLOCK, FALSE); /*!< gpiog periph clock */ crm_periph_clock_enable(CRM_GPIOH_PERIPH_CLOCK, FALSE); /*!< gpioh periph clock */ crm_periph_clock_enable(CRM_CRC_PERIPH_CLOCK, FALSE); /*!< crc periph clock */ crm_periph_clock_enable(CRM_EDMA_PERIPH_CLOCK, FALSE); /*!< edma periph clock */ crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, FALSE); /*!< dma1 periph clock */ crm_periph_clock_enable(CRM_DMA2_PERIPH_CLOCK, FALSE); /*!< dma2 periph clock */ crm_periph_clock_enable(CRM_EMAC_PERIPH_CLOCK, FALSE); /*!< emac periph clock */ crm_periph_clock_enable(CRM_EMACTX_PERIPH_CLOCK, FALSE); /*!< emac tx periph clock */ crm_periph_clock_enable(CRM_EMACRX_PERIPH_CLOCK, FALSE); /*!< emac rx periph clock */ crm_periph_clock_enable(CRM_EMACPTP_PERIPH_CLOCK, FALSE); /*!< emac ptp periph clock */ crm_periph_clock_enable(CRM_OTGFS2_PERIPH_CLOCK, FALSE); /*!< otgfs2 periph clock */ /* ahb periph2 */ crm_periph_clock_enable(CRM_DVP_PERIPH_CLOCK, FALSE); /*!< dvp periph clock */ crm_periph_clock_enable(CRM_OTGFS1_PERIPH_CLOCK, FALSE); /*!< otgfs1 periph clock */ crm_periph_clock_enable(CRM_SDIO1_PERIPH_CLOCK, FALSE); /*!< sdio1 periph clock */ /* ahb periph3 */ crm_periph_clock_enable(CRM_XMC_PERIPH_CLOCK, FALSE); /*!< xmc periph clock */ crm_periph_clock_enable(CRM_QSPI1_PERIPH_CLOCK, FALSE); /*!< qspi1 periph clock */ crm_periph_clock_enable(CRM_QSPI2_PERIPH_CLOCK, FALSE); /*!< qspi2 periph clock */ crm_periph_clock_enable(CRM_SDIO2_PERIPH_CLOCK, FALSE); /*!< sdio2 periph clock */ /* apb1 periph */ crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, FALSE); /*!< tmr2 periph clock */ crm_periph_clock_enable(CRM_TMR3_PERIPH_CLOCK, FALSE); /*!< tmr3 periph clock */ crm_periph_clock_enable(CRM_TMR4_PERIPH_CLOCK, FALSE); /*!< tmr4 periph clock */ crm_periph_clock_enable(CRM_TMR5_PERIPH_CLOCK, FALSE); /*!< tmr5 periph clock */ crm_periph_clock_enable(CRM_TMR6_PERIPH_CLOCK, FALSE); /*!< tmr6 periph clock */ crm_periph_clock_enable(CRM_TMR7_PERIPH_CLOCK, FALSE); /*!< tmr7 periph clock */ crm_periph_clock_enable(CRM_TMR12_PERIPH_CLOCK, FALSE); /*!< tmr12 periph clock */ crm_periph_clock_enable(CRM_TMR13_PERIPH_CLOCK, FALSE); /*!< tmr13 periph clock */ crm_periph_clock_enable(CRM_TMR14_PERIPH_CLOCK, FALSE); /*!< tmr14 periph clock */ crm_periph_clock_enable(CRM_WWDT_PERIPH_CLOCK, FALSE); /*!< wwdt periph clock */ crm_periph_clock_enable(CRM_SPI2_PERIPH_CLOCK, FALSE); /*!< spi2 periph clock */ crm_periph_clock_enable(CRM_SPI3_PERIPH_CLOCK, FALSE); /*!< spi3 periph clock */ crm_periph_clock_enable(CRM_USART2_PERIPH_CLOCK, FALSE); /*!< usart2 periph clock */ crm_periph_clock_enable(CRM_USART3_PERIPH_CLOCK, FALSE); /*!< usart3 periph clock */ crm_periph_clock_enable(CRM_UART4_PERIPH_CLOCK, FALSE); /*!< uart4 periph clock */ crm_periph_clock_enable(CRM_UART5_PERIPH_CLOCK, FALSE); /*!< uart5 periph clock */ crm_periph_clock_enable(CRM_I2C1_PERIPH_CLOCK, FALSE); /*!< i2c1 periph clock */ crm_periph_clock_enable(CRM_I2C2_PERIPH_CLOCK, FALSE); /*!< i2c2 periph clock */ crm_periph_clock_enable(CRM_I2C3_PERIPH_CLOCK, FALSE); /*!< i2c3 periph clock */ crm_periph_clock_enable(CRM_CAN1_PERIPH_CLOCK, FALSE); /*!< can1 periph clock */ crm_periph_clock_enable(CRM_CAN2_PERIPH_CLOCK, FALSE); /*!< can2 periph clock */ crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, FALSE); /*!< pwc periph clock */ crm_periph_clock_enable(CRM_DAC_PERIPH_CLOCK, FALSE); /*!< dac periph clock */ crm_periph_clock_enable(CRM_UART7_PERIPH_CLOCK, FALSE); /*!< uart7 periph clock */ crm_periph_clock_enable(CRM_UART8_PERIPH_CLOCK, FALSE); /*!< uart8 periph clock */ /* apb2 periph */ crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, FALSE); /*!< tmr1 periph clock */ crm_periph_clock_enable(CRM_TMR8_PERIPH_CLOCK, FALSE); /*!< tmr8 periph clock */ crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, FALSE); /*!< usart1 periph clock */ crm_periph_clock_enable(CRM_USART6_PERIPH_CLOCK, FALSE); /*!< usart6 periph clock */ crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, FALSE); /*!< adc1 periph clock */ crm_periph_clock_enable(CRM_ADC2_PERIPH_CLOCK, FALSE); /*!< adc2 periph clock */ crm_periph_clock_enable(CRM_ADC3_PERIPH_CLOCK, FALSE); /*!< adc3 periph clock */ crm_periph_clock_enable(CRM_SPI1_PERIPH_CLOCK, FALSE); /*!< spi1 periph clock */ crm_periph_clock_enable(CRM_SPI4_PERIPH_CLOCK, FALSE); /*!< spi4 periph clock */ crm_periph_clock_enable(CRM_SCFG_PERIPH_CLOCK, FALSE); /*!< scfg periph clock */ crm_periph_clock_enable(CRM_TMR9_PERIPH_CLOCK, FALSE); /*!< tmr9 periph clock */ crm_periph_clock_enable(CRM_TMR10_PERIPH_CLOCK, FALSE); /*!< tmr10 periph clock */ crm_periph_clock_enable(CRM_TMR11_PERIPH_CLOCK, FALSE); /*!< tmr11 periph clock */ crm_periph_clock_enable(CRM_TMR20_PERIPH_CLOCK, FALSE); /*!< tmr20 periph clock */ crm_periph_clock_enable(CRM_ACC_PERIPH_CLOCK, FALSE); /*!< acc periph clock */ #elif #error "нужно сделать выключение всей переферии под текущий контроллер, пример выше" #endif uint32_t appStack; pFunction appEntry; // get the application stack pointer (1st entry in the app vector table) appStack = (uint32_t) *((__IO uint32_t *) address); // Get the app entry point (2nd entry in the app vector table appEntry = (pFunction) *(__IO uint32_t *) (address + 4); // HAL_RCC_DeInit(); // HAL_DeInit(); SysTick->CTRL = 0; SysTick->LOAD = 0; SysTick->VAL = 0; uint32_t i = SCB->VTOR; i++; // Reconfigure vector table offset to match the app location //#if (SET_VECTOR_TABLE) // SCB->VTOR = address; //#endif // //// __disable_irq(); // disable interrupt //// __enable_irq(); //// __set_PRIMASK(1); //// __set_MSP(appStack); // Set app stack pointer //останавливаем SysTick SysTick->CTRL = 0UL; SysTick->VAL = 0UL; __set_MSP(appStack); SCB->VTOR = address; __enable_irq(); // __asm volatile ( "bl 0x08020004"); appEntry(); // Start the app while (1); // never reached }