硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2076|回复: 6
收起左侧

[有问必答] stm32f103zg程序跳转到系统bootloader失败

[复制链接]

14

主题

11

回帖

53

积分

初级会员

积分
53
发表于 2021-9-4 10:08:38 | 显示全部楼层 |阅读模式
目前用的芯片是stm32f103zg,准备使用串口升级程序,看到手册AN2606中,该芯片是支持USART1通过系统boot loader更新程序的。现在的程序是用stm32cubemx生成的,程序如下
  1. int main(void)
  2. {
  3.   /* USER CODE BEGIN 1 */

  4.   /* USER CODE END 1 */

  5.   /* MCU Configuration--------------------------------------------------------*/

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

  8.   /* USER CODE BEGIN Init */

  9.   /* USER CODE END Init */

  10.   /* Configure the system clock */
  11.   SystemClock_Config();

  12.   /* USER CODE BEGIN SysInit */

  13.   /* USER CODE END SysInit */

  14.   /* Initialize all configured peripherals */
  15.   MX_GPIO_Init();
  16.   /* USER CODE BEGIN 2 */

  17.   /* USER CODE END 2 */

  18.   /* Infinite loop */
  19.   /* USER CODE BEGIN WHILE */
  20.   while (1)
  21.   {
  22.     /* USER CODE END WHILE */

  23.     /* USER CODE BEGIN 3 */
  24.                 if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_10)==GPIO_PIN_RESET)
  25.                 {
  26.                         JumpToBootloader();
  27.                 }
  28.                 else
  29.                 {
  30.                         JumpToApp();
  31.                 }               
  32.   }
  33.   /* USER CODE END 3 */
  34. }

  35. /* USER CODE BEGIN 4 */

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

  52.         /* 关闭所有中断,清除中断挂起标志 */
  53.         for (i = 0; i < 8; i++)
  54.         {
  55.                 NVIC->ICER[i]=0xFFFFFFFF;
  56.                 NVIC->ICPR[i]=0xFFFFFFFF;
  57.         }
  58.         
  59.         /* 使能全局中断 */
  60.         __enable_irq();
  61.         
  62.         /*设置重映射到系统Flash */
  63. //        __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();
  64.         
  65.         /* 跳转到系统 BootLoader,首地址是MSP,地址 +4 是复位中断服务程序地址 */
  66.         SysMemBootJump = (void (*)(void)) (*((uint32_t *) (BootAddr + 4)));
  67.         
  68.         /* 设置主堆栈地址*/
  69.         __set_MSP(*(uint32_t *)BootAddr);
  70.         
  71.         /*在RTOS工程,这条语句很重要,设置为特权模式,使用MSP指针 */
  72.         __set_CONTROL(0);
  73.         
  74.         /* 跳转到系统 BootLoader */
  75.         SysMemBootJump();
  76. }

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

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

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

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

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

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

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

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

  106.         /* 跳转到系统 BootLoader */
  107.         SysMemBootJump();
  108. }
  109. /* USER CODE END 4 *
复制代码
现在这个程序是可以正常跳转到APP程序的,就是跳转bootloader不成功,用stm32programmer,连接不上串口。如果直接把BOOT0置高是可以连接上串口的,所以硬件上应该没有问题。
请各位大神帮我看看到底是什么原因不能跳转到系统boot loader呢?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106771
QQ
发表于 2021-9-4 16:02:51 | 显示全部楼层
F103跳转到系统BootLoader确实有一些奇葩问题,无法跳转到系统BootLoader里面。

之前帮一个网友整,也没有搞定。估计还有一些区别于F4和H7的骚操作要执行下。
回复

使用道具 举报

5

主题

132

回帖

147

积分

初级会员

积分
147
发表于 2021-10-26 17:31:15 | 显示全部楼层
我之前也遇到了这个问题,发现要调整一下顺序,否则滴答定时器关不掉,影响跳转
/*设置所有时钟到默认状态,使用HSI时钟*/
HAL_RCC_DeInit();

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


最后问一下硬汉哥
/*在RTOS工程,这条语句很重要,设置为特权模式,使用MSP指针 */
__set_CONTROL(0);
这句有用吗?我看M3权威指南中有说  只有在中断中才能从1变0
微信图片_20211026172829.png

回复

使用道具 举报

12

主题

68

回帖

104

积分

初级会员

积分
104
发表于 2021-12-25 10:42:58 | 显示全部楼层
无关风月 发表于 2021-10-26 17:31
我之前也遇到了这个问题,发现要调整一下顺序,否则滴答定时器关不掉,影响跳转
/*设置所有时钟到默认状 ...

有其他人验证过这个吗?
我使用F302也是没法跳转到系统boot,识别不到usb
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106771
QQ
发表于 2021-12-26 09:51:02 | 显示全部楼层
weboser 发表于 2021-12-25 10:42
有其他人验证过这个吗?
我使用F302也是没法跳转到系统boot,识别不到usb

可以上ST的社区找找F302的跳转地址,像我之前H7的就是,手册上给的地址不对。
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2024-4-3 15:15:48 | 显示全部楼层
可以试试下面的代码,我测试使用后没有问题,代码中的HAL_DeInit()必须调用,经测试可以正常跳转
[C] 纯文本查看 复制代码
/*
 ******************************************************************************************************
 *    函 数 名: JumpToBootloader
 *    功能说明: 跳转到系统BootLoader   //ref  stm32AN2606
 *    形    参: 无
 *    返 回 值: 无
 ******************************************************************************************************
 */
static void JumpToBootloader(void)
{
    void (*SysMemBootJump)(void); 
		if(wdg_dev)
			rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, NULL);
		HAL_DeInit();
		HAL_RCC_DeInit();
		SysTick->CTRL = 0;
		SysTick->LOAD = 0;
		SysTick->VAL = 0;
		__disable_irq();
    __IO uint32_t BootAddr = 0x1FFFF000; /* STM32系统BootLoader地址 */
    SysMemBootJump = (void (*)(void)) (*((uint32_t *) (BootAddr + 4)));
    __set_MSP(*(uint32_t *) BootAddr);
    SysMemBootJump();
    while (1);
}
MSH_CMD_EXPORT_ALIAS(JumpToBootloader, reboot_loader, jump to system memory);

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106771
QQ
发表于 2024-4-4 09:19:43 | 显示全部楼层
illusion_killer 发表于 2024-4-3 15:15
可以试试下面的代码,我测试使用后没有问题,代码中的HAL_DeInit()必须调用,经测试可以正常跳转
[mw_shl ...

谢谢分享。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-6 01:03 , Processed in 0.311795 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表