OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6701|回复: 7

stm32f103zg程序跳转到系统bootloader失败

[复制链接]

14

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
103
金钱
103
注册时间
2014-6-27
在线时间
24 小时
发表于 2021-9-4 10:03:32 | 显示全部楼层 |阅读模式
5金钱
目前用的芯片是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呢?

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

80

主题

931

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3348
金钱
3348
注册时间
2013-5-28
在线时间
468 小时
发表于 2021-9-4 10:41:00 | 显示全部楼层
我就好奇,我们是转跳前把所有的中断什么全关了,你为啥开起来啊?
还有绝大部分转跳失败是因为地址的数据类型有问题.
自己参照下这个
if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)
                        { /* Jump to user application */
                                JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);
                                Jump_To_Application = (pFunction) JumpAddress;
                                /* Initialize user application's Stack Pointer */
                                __set_MSP(*(__IO uint32_t*) ApplicationAddress);
                                Jump_To_Application();
                        }
回复

使用道具 举报

14

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
103
金钱
103
注册时间
2014-6-27
在线时间
24 小时
 楼主| 发表于 2021-9-4 10:57:21 | 显示全部楼层
聚东风 发表于 2021-9-4 10:41
我就好奇,我们是转跳前把所有的中断什么全关了,你为啥开起来啊?
还有绝大部分转跳失败是因为地址的数据类 ...

按照这样测试了,也是不行
  1. #define BOOTLOADERADD             0x1FFFE000
  2. static void JumpToBootloader(void)
  3. {
  4.             JumpAddress = *(__IO uint32_t*) (BOOTLOADERADD + 4);
  5.             JumpToApplication = (pFunction) JumpAddress;

  6.             /* Initialize user application's Stack Pointer */
  7.             __set_MSP(*(__IO uint32_t*) BOOTLOADERADD);
  8.             JumpToApplication();

  9. }
复制代码

目前跳转到APP是没有问题的,就是跳转到系统bootloader不行,系统的bootloader地址是 0x1FFFE000,这个地址应该是没有问题的
回复

使用道具 举报

3

主题

312

帖子

0

精华

高级会员

Rank: 4

积分
907
金钱
907
注册时间
2011-10-19
在线时间
196 小时
发表于 2021-9-4 13:47:19 | 显示全部楼层
参照这方法: http://www.openedv.com/forum.php ... p;extra=#pid1164145
同时调试bootloader和APP工程的话,问题应该好找点
回复

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2021-9-4 23:55:27 | 显示全部楼层
官方好像有个文档详细讲解了怎么跳转的,找找
回复

使用道具 举报

80

主题

931

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3348
金钱
3348
注册时间
2013-5-28
在线时间
468 小时
发表于 2021-9-6 10:20:27 | 显示全部楼层
系统bootloader部分情况下会失效的,你看下自己是不是属于这种情况,就是一旦锁定了,bootloader就不能用
回复

使用道具 举报

14

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
103
金钱
103
注册时间
2014-6-27
在线时间
24 小时
 楼主| 发表于 2021-9-8 18:21:22 | 显示全部楼层
聚东风 发表于 2021-9-6 10:20
系统bootloader部分情况下会失效的,你看下自己是不是属于这种情况,就是一旦锁定了,bootloader就不能用

这个怎么判断呢?或者有资料说明吗?
回复

使用道具 举报

80

主题

931

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3348
金钱
3348
注册时间
2013-5-28
在线时间
468 小时
发表于 2021-9-9 09:03:34 | 显示全部楼层
jinger0311 发表于 2021-9-8 18:21
这个怎么判断呢?或者有资料说明吗?

不是说了吗?锁定,只要你动了只读,就会取消系统的bootloader
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-6 21:50

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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