STM32F4跳转函数

JMP2APP

void JMP2APP(void)
{
  
    pFunction Jump_To_Application;
    uint32_t JumpAddress;
   
    if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)
    {
      //将使用过的中断和外设全部关闭
//      NVIC->ICER[TIM7_IRQn/32]|=1<<TIM7_IRQn%32;
//      NVIC->ICER[TIM3_IRQn/32]|=1<<TIM3_IRQn%32;
//      NVIC->ICER[TIM4_IRQn/32]|=1<<TIM4_IRQn%32;
      NVIC->ICER[OTG_FS_IRQn/32]|=1<<OTG_FS_IRQn%32;
      
      SysTick->CTRL&=~(1<<0);
      SysTick->CTRL&=~(1<<1);
      SysTick->LOAD=0;
      RCC->APB1ENR&=~(1<<1);	//TIM3时钟关闭
      RCC->APB1ENR&=~(1<<2);	//TIM4时钟关闭
      RCC->APB1ENR&=~(1<<5);	//TIM7时钟关闭 
      RCC->APB2ENR&=~(1<<0);	//TIM1时钟关闭 
      RCC->APB2ENR&=~(1<<1);	//TIM8时钟关闭 
      RCC->AHB2ENR&=~(1<<7);    //关闭USB OTG时钟
      
      ADC3->CR1=0;
      ADC3->CR2=0;              //关闭AD转换器   
      
      UART4->CR1 = 0;
      UART4->CR3 = 0;
      UART5->CR1 = 0;
      UART5->CR3 = 0;
      USART6->CR1 = 0;
      USART6->CR3 = 0;
      USART1->CR1 = 0;
      USART1->CR3 = 0;
      
      DMA2_Stream0->NDTR=0;
      DMA2_Stream0->CR=0;      //关闭ADC的DMA传输
      DMA2_Stream1->NDTR=0;
      DMA2_Stream1->CR=0;      
      DMA2_Stream2->NDTR=0;
      DMA2_Stream2->CR=0;      
      
      DMA1_Stream7->NDTR=0;
      DMA1_Stream7->CR=0;      //关闭DMA传输
      DMA1_Stream5->NDTR=0;
      DMA1_Stream5->CR=0;      //关闭DMA传输
      DMA1_Stream2->NDTR=0;
      DMA1_Stream2->CR=0;      //关闭DMA传输
      DMA1_Stream0->NDTR=0;
      DMA1_Stream0->CR=0;      //关闭DMA传输
           
      
      RCC->APB2ENR&=~(1<<10);    //关闭ADC3
      RCC->AHB1ENR&=~(1<<21);//DMA1时钟关闭  
      RCC->AHB1ENR&=~(1<<22);//DMA2时钟关闭    
      
      
      RCC->APB1ENR&=~(1<<19);    //关闭USART4
      RCC->APB1ENR&=~(1<<20);    //关闭USART5
      RCC->APB2ENR&=~(1<<4);    //关闭USART1
      RCC->APB2ENR&=~(1<<5);    //关闭USART6
      RCC->APB2ENR&=~(1<<14);    //关闭SYSCFG时钟
      
      /* Jump to user application */
      JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
      Jump_To_Application = (pFunction) JumpAddress;
      
      //control_flag = __get_CONTROL();
      __set_CONTROL(0);   //重置CONTROL,使线程模式处于特权等级,使用主栈指针
      /* Initialize user application's Stack Pointer */
      __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
      __set_PSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
      Jump_To_Application();
    }
}

跳转后的代码

SCB->VTOR = 0x08000000 | (0x20000 & (uint32_t)0x1FFFFF80);  //重映射到0x08020000
__asm("CPSIE  I");
原文地址:https://www.cnblogs.com/penuel/p/13226016.html