STM32F107VCT6模拟U盘升级程序


STM32F107VCT6模拟U盘升级程序

具体的操作能查到详细的步骤,这里只记录实际中遇到的一些问题。

1 Bootloader程序跳转

 1  /* Test if user code is programmed starting from address "FLASH_APP_ADDR" */
 2  if (((*(__IO uint32_t*)FLASH_APP_ADDR) & 0x2FFE0000 ) == 0x20000000)
 3 {
 4     printf("Running APP...");
 5     /* 关总中断 */
 6     __disable_irq();
 7     /* 恢复时钟设置,使用内部HSI低速时钟 */
 8     HAL_RCC_DeInit();
 9     /* 关闭所有中断,清除所有挂起中断*/
10     for(int i=0;i<8;i++)
11     {
12         NVIC->ICER[i] = 0xFFFFFFFF;
13         NVIC->ICPR[i] = 0xFFFFFFFF;
14     }
15     /* Jump to user application */
16     JumpAddress = *(__IO uint32_t*) (FLASH_APP_ADDR + 4);
17     JumpToApplication = (pFunction) JumpAddress;
18     /* Initialize user application's Stack Pointer */
19     __set_MSP(*(__IO uint32_t*) FLASH_APP_ADDR);
20     JumpToApplication();
21   }             

此处需要注意,有某些平台,只需要关闭全局中断即可。

__disable_irq();

在一款STM32F103芯片上只关闭全局中断就可以,但在STM32F107上还需要清除所有挂起中断标志,否则出现App程序不能进中断的问题。

for(int i=0;i<8;i++)
{
    NVIC->ICER[i] = 0xFFFFFFFF;
    NVIC->ICPR[i] = 0xFFFFFFFF;
}

另外如果在App程序中需要重新配置时钟PLL的话,需要先将时钟恢复到初始设置。

HAL_RCC_DeInit();

否则,App程序重新配置时钟时可能出错,现像是App程序不运行,感觉像是跳转失败,其实不是。

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
  Error_Handler();
}

2 App更新中断矢量

SCB->VTOR = FLASH_BASE | FLASH_BOOT_SIZE;

其中FLASH_BASE = 0x08000000,FLASH_BOOT_SIZE是偏移量,比如

#define FLASH_BOOT_SIZE    0x00010000

有时候需要手动开启全局中断。

__enable_irq();

否则也会出现App程序不能进中断的问题,如果App程序调用HAL_Delay()延时函数,就可能卡在此处。

mcu