STM32F4 HAL库Boot至APP跳转
  Ja5R8ZAZggo4 2023年11月02日 84 0

boot跳转代码如下:

typedef void(*pFunction)(void);

/**
  ******************************************************************************
  * @file    iap.c
  * @brief   跳转到应用程序段.
	* @param 	 addr:应用程序的起始地址
	* @retval  None
*****************************************************************************/
void Jump_To_User_App(uint32_t addr)
{
	pFunction Jump_To_Application;
	uint8_t i;

	if ( ( ( * ( __IO uint32_t * ) addr ) & 0x2FFE0000 ) == 0x20000000 ) {	 //检查栈顶地址是否合法.
	 
		HAL_CAN_MspDeInit(&hcan1);		
		HAL_TIM_Base_MspDeInit(&htim2);	
		__HAL_RCC_GPIOA_CLK_DISABLE();
		__HAL_RCC_GPIOB_CLK_DISABLE();
		__HAL_RCC_GPIOC_CLK_DISABLE();
		__HAL_RCC_GPIOH_CLK_DISABLE();
			
		/* 设置所有时钟到默认状态,使用HSI时钟 */
		HAL_RCC_DeInit();		
		/* 关中断 */	
		__set_BASEPRI(0x20);		//屏蔽到TIM2/3/4中断响应
		__set_PRIMASK(1);
		__set_FAULTMASK(1);
			
		/* 关闭所有中断,清除所有中断挂起标志 */
		for (i = 0; i < 8; i++)		
		{
			NVIC->ICER[i]=0xFFFFFFFF;
			NVIC->ICPR[i]=0xFFFFFFFF;
		}
		
		SysTick->CTRL = 0;	//关闭掉系统滴答定时器,该定时器会在APP的程序中重新启动,调用HAL_Init();函数会启动;
		SysTick->LOAD = 0;
		SysTick->VAL = 0;

		__set_BASEPRI(0);		//重新启动中断开关
		__set_PRIMASK(0);
		__set_FAULTMASK(0);
			
		//
				/*
				1)不使用OS时: 只用到MSP(中断和非中断都使用MSP);
				2)使用OS时(如UCOSII): main函数和中断使用MSP; 各个Task(线程)使用PSP(即任务栈);
				*/
		__set_MSP(*(uint32_t*)addr);	//当带操作系统从APP区跳转到BOOT区的时候需要将SP设置为MSP,否则在BOOT区中使用中断将会引发硬件错误!
		__set_PSP(*(uint32_t*)addr);
		__set_CONTROL(0);  						// 在RTOS工程,这条语句很重要,设置为特权级模式,使用MSP指针 
		__ISB();											//指令同步隔离。最严格:它会清洗流水线,以保证所有它前面的指令都执行完毕之后,才执行它后面的指令。
			
		Jump_To_Application = ( pFunction ) * ( __IO uint32_t * ) ( addr + 4 );	//用户代码区第二个字为程序开始地址(复位地址)
		
		Jump_To_Application();
	}
}

app在魔法棒里面设置跳转地址:

STM32F4 HAL库Boot至APP跳转_STM32

设置偏移地址与魔法棒地址相同,打开宏

#define USER_VECT_TAB_ADDRESS 

修改VECT_TAB_OFFSET偏移地址:

#define USER_VECT_TAB_ADDRESS 

#if defined(USER_VECT_TAB_ADDRESS)
/*!< Uncomment the following line if you need to relocate your vector Table
     in Sram else user remap will be done in Flash. */
/* #define VECT_TAB_SRAM */
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS   SRAM_BASE       /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET         0x00000000U     /*!< Vector Table base offset field.
                                                     This value must be a multiple of 0x200. */
#else
#define VECT_TAB_BASE_ADDRESS   FLASH_BASE      /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET         0x00010000U     /*!< Vector Table base offset field.
                                                     This value must be a multiple of 0x200. */
#endif /* VECT_TAB_SRAM */
#endif /* USER_VECT_TAB_ADDRESS */

app的main起始添加如下函数:

  /* USER CODE BEGIN 1 */
	HAL_DeInit();
	HAL_RCC_DeInit();
  /* USER CODE END 1 */

完成以上配置,即可完成boot至app的跳转。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论