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在魔法棒里面设置跳转地址:
设置偏移地址与魔法棒地址相同,打开宏
#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的跳转。