问答

汇集网友智慧,解决技术难题

21ic问答首页 - stm32f103zg程序跳转到系统bootloader失败

Bootloader STM32F103 se ic rc TI

stm32f103zg程序跳转到系统bootloader失败

jing8803112021-09-04
目前用的芯片是stm32f103zg,准备使用串口升级程序,看到手册AN2606中,该芯片是支持USART1通过系统boot loader更新程序的。现在的程序是用stm32cubemx生成的,程序如下
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
                if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_10)==GPIO_PIN_RESET)
                {
                        JumpToBootloader();
                }
                else
                {
                        JumpToApp();
                }               
  }
  /* USER CODE END 3 */
}

/* USER CODE BEGIN 4 */

static void JumpToBootloader(void)
{
        uint32_t i=0;
        void (*SysMemBootJump)(void); /*声明一个函数指针*/
        __IO uint32_t BootAddr =  0x1FFFE000;//0x1FFF0000; /* STM32F103 的系统 BootLoader 地址*/
       
        /*关闭全局中断*/
        __disable_irq();
       
        /*关闭滴答定时器,恢复到默认值*/
        SysTick->CTRL = 0;
        SysTick->LOAD = 0;
        SysTick->VAL = 0;
       
        /*设置所有时钟到默认状态,使用HSI时钟*/
        HAL_RCC_DeInit();

        /* 关闭所有中断,清除中断挂起标志 */
        for (i = 0; i < 8; i++)
        {
                NVIC->ICER[i]=0xFFFFFFFF;
                NVIC->ICPR[i]=0xFFFFFFFF;
        }
       
        /* 使能全局中断 */
        __enable_irq();
       
        /*设置重映射到系统Flash */
//        __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();
       
        /* 跳转到系统 BootLoader,首地址是MSP,地址 +4 是复位中断服务程序地址 */
        SysMemBootJump = (void (*)(void)) (*((uint32_t *) (BootAddr + 4)));
       
        /* 设置主堆栈地址*/
        __set_MSP(*(uint32_t *)BootAddr);
       
        /*在RTOS工程,这条语句很重要,设置为特权模式,使用MSP指针 */
        __set_CONTROL(0);
       
        /* 跳转到系统 BootLoader */
        SysMemBootJump();
}

static void JumpToApp(void)
{
        uint32_t i=0;
        void (*SysMemBootJump)(void);        /*声明一个函数指针*/
        __IO uint32_t BootAddr = 0x8001800; /* APP程序地址*/       
       

        /*关闭全局中断*/
        __disable_irq();

        /*关闭滴答定时器,恢复到默认值*/
        SysTick->CTRL = 0;
          SysTick->LOAD = 0;
          SysTick->VAL = 0;

        /*设置所有时钟到默认状态,使用HSI时钟*/
        HAL_RCC_DeInit();

        /* 关闭所有中断,清除中断挂起标志 */
        for (i = 0; i < 8; i++)
        {
                NVIC->ICER[i]=0xFFFFFFFF;
                NVIC->ICPR[i]=0xFFFFFFFF;
        }       

        /* 使能全局中断 */
        __enable_irq();

        /* 跳转到系统 BootLoader,首地址是MSP,地址 +4 是复位中断服务程序地址 */
        SysMemBootJump = (void (*)(void)) (*((uint32_t *) (BootAddr + 4)));

        /* 设置主堆栈地址*/
        __set_MSP(*(uint32_t *)BootAddr);
       
        /*在RTOS工程,这条语句很重要,设置为特权模式,使用MSP指针 */
        __set_CONTROL(0);

        /* 跳转到系统 BootLoader */
        SysMemBootJump();
}
/* USER CODE END 4 */


现在这个程序是可以正常跳转到APP程序的,就是跳转bootloader不成功,用stm32programmer,连接不上串口。如果直接把BOOT0置高是可以连接上串口的,所以硬件上应该没有问题。





回答 +关注 1
1975人浏览 0人回答问题 分享 举报
0 个回答

您需要登录后才可以回复 登录 | 注册