OpenEdv-开源电子网

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

STM32CUBEIDE IAP跳转失败,求助?!!

[复制链接]

53

主题

566

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2095
金钱
2095
注册时间
2017-2-11
在线时间
306 小时
发表于 2020-12-2 16:45:18 | 显示全部楼层 |阅读模式
5金钱
本帖最后由 jiangyy 于 2020-12-2 16:46 编辑

  使用STM32CUBEIDE编写工程,功能基本上完成。因为项目上使用到  bootloader升级,所以内部flash给了16kb用来存储bootloader代码。所以需要修改flash偏移量,具体修改如下:1.falsh存储偏移量设置

设置

设置



2.中断偏移量设置
在system_stm32f4xx.c文件,修改VECT_TAB_OFFSET,代码如下:
  1. void SystemInit(void)
  2. {
  3.   /* FPU settings ------------------------------------------------------------*/
  4.   #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  5.     SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
  6.   #endif

  7. #if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
  8.   SystemInit_ExtMemCtl();
  9. #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */

  10.   /* Configure the Vector Table location add offset address ------------------*/
  11. #ifdef VECT_TAB_SRAM
  12.   SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
  13. #else
  14.   SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
  15. #endif
  16. }
复制代码
其中VECT_TAB_OFFSET是一个宏定义,我修改如下:
  1. /*!< Uncomment the following line if you need to relocate your vector Table in
  2.      Internal SRAM. */
  3. /* #define VECT_TAB_SRAM */
  4. #define VECT_TAB_OFFSET  0x4000 /*!< Vector Table base offset field.
  5.                                    This value must be a multiple of 0x200. */
  6. /******************************************************************************/
复制代码
之前是#define VECT_TAB_OFFSET 0x00 ,后面我改为 #define VECT_TAB_OFFSET 0x4000。


  后面我使用STM32CUBEProgrammer软件烧录,如下:

烧录

烧录

上图表示烧录成功,hex文件上面的address也变成了   0x8004000。烧录成功,板子自动重启正常,但是手动复位一下单片机就再也起不来了,很纳闷。贴友们哪位知道的话,请留言一下,谢谢。

最佳答案

查看完整内容[请看2#楼]

废了九牛二虎之力(花了两天时间研究IAP),终于搞定了IDE软件如何IAP跳转。具体细节如下: 一、准备bootloader程序 因为STM32CUBEIDE软件生成的hex文件比较大,所以要给足够大的空间给bootloader(具体要看你生成的bin文件大小),我自己没加什么东西,就有32kb了,在这里我只是简单的做个演示,所以我给了它48kb。 下面几个步骤很关键,如下: 1.修改内部flash链接文件(STM32F407ZGTX_FLASH.ld) 2.编写一个 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

53

主题

566

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2095
金钱
2095
注册时间
2017-2-11
在线时间
306 小时
 楼主| 发表于 2020-12-2 16:45:19 | 显示全部楼层
本帖最后由 jiangyy 于 2020-12-9 10:06 编辑

  废了九牛二虎之力(花了两天时间研究IAP),终于搞定了IDE软件如何IAP跳转。具体细节如下:

一、准备bootloader程序
  因为STM32CUBEIDE软件生成的hex文件比较大,所以要给足够大的空间给bootloader(具体要看你生成的bin文件大小),我自己没加什么东西,就有32kb了,在这里我只是简单的做个演示,所以我给了它48kb。
  下面几个步骤很关键,如下:
  1.修改内部flash链接文件(STM32F407ZGTX_FLASH.ld)

  1. /* Memories definition */
  2. MEMORY
  3. {
  4.   CCMRAM    (xrw)    : ORIGIN = 0x10000000,   LENGTH = 64K
  5.   RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 128K
  6.   FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 48K
  7. }
复制代码
2.编写一个IAP跳转函数  你可以自己建立一个文件,也可以在main.c文件编写这个函数。  

  1. #define ApplicationAddress       0x800C000          //应用程序起始地址(存放在FLASH)
  2. typedef  void ( * pFunction ) ( void ); //定义一个函数类型的参数.
  3. void iap_load_app(uint32_t appAddr);

  4. //ulAddr_App:用户代码起始地址.
  5. void iap_load_app(uint32_t appAddr)
  6. {
  7.         pFunction jump2app;
  8.         printf("first word : 0x%x\r\n",(*(uint32_t*)appAddr));

  9.         if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20020000)
  10.         {
  11.                 printf("IAP load APP!\r\n");
  12.                 HAL_RCC_DeInit();
  13.                 jump2app = (void (*)())*(__IO uint32_t*) (appAddr + 4);
  14.                 __set_MSP(*(__IO uint32_t*) appAddr);
  15.                 jump2app();
  16.         }
  17. }
复制代码

  特别注意,HAL_RCC_DeInit();这个一定要加上,否则无法跳转!!!!这个坑我挖了好长时间终于找到是这个地方缺少了导致无法跳转,我也不清楚为啥一定要初始化复位RCC寄存器。还有一个坑是地址校验,不知道有没有小伙伴注意到,就是if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20020000)。红色的地方要修改,否则无法跳转!!!别问我为什么,你用STM32CubeProgrammer读取芯片flash的内容就知道首地址的值是多少就知道了,下面是我一个截图:
截图20201208214639955.jpg

  3.main函数添加IAP跳转函数

  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.   MX_RTC_Init();
  17.   MX_USART1_UART_Init();
  18.   /* USER CODE BEGIN 2 */
  19.   __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
  20.   /* USER CODE END 2 */

  21.   /* Infinite loop */
  22.   /* USER CODE BEGIN WHILE */
  23.   while (1)
  24.   {
  25.         HAL_GPIO_TogglePin(GPIOF,LED0_Pin);
  26.         HAL_Delay(500);
  27.         iap_load_app(ApplicationAddress);
  28.     /* USER CODE END WHILE */

  29.     /* USER CODE BEGIN 3 */
  30.   }
  31.   /* USER CODE END 3 */
  32. }
复制代码

此工作完成了一个简单的bootloader程序,下面就是要做一个APP程序了。

二、准备APP程序
  1.修改内部flash链接文件(STM32F407ZGTX_FLASH.ld)

  1. MEMORY
  2. {
  3.   CCMRAM    (xrw)    : ORIGIN = 0x10000000,   LENGTH = 64K
  4.   RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 128K
  5.   FLASH    (rx)    : ORIGIN = 0x800C000,   LENGTH = 976K
  6. }
复制代码

  在这里有人有点小疑问,为啥ORIGIN = 0x800C000?因为bootloader分配了0xC000字节大小,也就是48kb;起先默认FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K,所以在这里就应该修改ORIGIN = 0x800C000,LENGTH = 1024K-48K = 976K,不懂可以看一下芯片手册。

  2.修改中断偏移量地址
  这个很关键,不然APP是无法启动的。具体修改的地方是在文件夹Core - > Src文件夹 -> system_stm32f4xx.c文件,其中有个宏定义 VECT_TAB_OFFSET,这个值默认是 0x00,修改为:

  1. /*!< Uncomment the following line if you need to relocate your vector Table in
  2.      Internal SRAM. */
  3. /* #define VECT_TAB_SRAM */
  4. #define VECT_TAB_OFFSET  0xC000 /*!< Vector Table base offset field.
  5.                                    This value must be a multiple of 0x200. */
复制代码

  3.main函数写个简单的应用,如下:
  1. int main(void)
  2. {
  3.   /* USER CODE BEGIN 1 */
  4.         uint8_t i = 0;
  5.   /* USER CODE END 1 */

  6.   /* MCU Configuration--------------------------------------------------------*/

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

  9.   /* USER CODE BEGIN Init */

  10.   /* USER CODE END Init */

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

  13.   /* USER CODE BEGIN SysInit */

  14.   /* USER CODE END SysInit */

  15.   /* Initialize all configured peripherals */
  16.   MX_GPIO_Init();
  17.   MX_RTC_Init();
  18.   MX_USART1_UART_Init();
  19.   /* USER CODE BEGIN 2 */
  20.   __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
  21.   /* USER CODE END 2 */

  22.   /* Infinite loop */
  23.   /* USER CODE BEGIN WHILE */
  24.   HAL_GPIO_WritePin(GPIOF,BEEP_Pin,GPIO_PIN_SET);
  25.   HAL_Delay(500);
  26.   HAL_GPIO_WritePin(GPIOF,BEEP_Pin,GPIO_PIN_RESET);
  27.   while (1)
  28.   {
  29.         HAL_GPIO_TogglePin(GPIOF,LED1_Pin);
  30.         HAL_Delay(200);
  31.         i++;
  32.         printf("i = %d\r\n",i);
  33.     /* USER CODE END WHILE */

  34.     /* USER CODE BEGIN 3 */
  35.   }
  36.   /* USER CODE END 3 */
  37. }
复制代码

  好了,一切准备就绪,开始准备烧录bootloader。使用STM32CubeProgrammer全片擦除falsh,然后烧录bootloader和APP程序,串口打印显示如下:
   截图20201208215020970.jpg

  可以正常运行了,哎,心累啊!!!不过终于解决了这个问题,希望对使用STM32CubeIDE编程的小伙伴有帮助,也希望点个赞告慰一下我坚持不懈的找BUG。3QY


回复

使用道具 举报

53

主题

566

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2095
金钱
2095
注册时间
2017-2-11
在线时间
306 小时
 楼主| 发表于 2020-12-2 17:26:35 | 显示全部楼层
不能沉下去啊,贴友们,帮忙分析一下,3QY
回复

使用道具 举报

3

主题

821

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3329
金钱
3329
注册时间
2011-11-10
在线时间
207 小时
发表于 2020-12-2 17:49:12 | 显示全部楼层
检查你的bootloader程序,复位后跳转那一块的条件
回复

使用道具 举报

4

主题

83

帖子

1

精华

高级会员

Rank: 4

积分
660
金钱
660
注册时间
2013-10-21
在线时间
88 小时
发表于 2020-12-2 17:52:56 | 显示全部楼层
jiangyy 发表于 2020-12-2 17:26
不能沉下去啊,贴友们,帮忙分析一下,3QY

1606902728(1).jpg
这个地方的偏移量加了吗?
回复

使用道具 举报

53

主题

566

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2095
金钱
2095
注册时间
2017-2-11
在线时间
306 小时
 楼主| 发表于 2020-12-2 18:05:45 | 显示全部楼层
旮旯旭 发表于 2020-12-2 17:52
这个地方的偏移量加了吗?

我不是用的MDK5,用的是STM32CUBEIDE。MDK5没什么问题,现在很少用MDK5了,用STM32CUBEIDE比较多。
回复

使用道具 举报

53

主题

566

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2095
金钱
2095
注册时间
2017-2-11
在线时间
306 小时
 楼主| 发表于 2020-12-2 18:06:29 | 显示全部楼层
c2007s 发表于 2020-12-2 17:49
检查你的bootloader程序,复位后跳转那一块的条件

用MDK5的工程可以跳转,但是用STM32CUBEIDE无法跳转。
回复

使用道具 举报

4

主题

83

帖子

1

精华

高级会员

Rank: 4

积分
660
金钱
660
注册时间
2013-10-21
在线时间
88 小时
发表于 2020-12-2 18:16:14 | 显示全部楼层
jiangyy 发表于 2020-12-2 18:05
我不是用的MDK5,用的是STM32CUBEIDE。MDK5没什么问题,现在很少用MDK5了,用STM32CUBEIDE比较多。

我一直用MDK,MDK的RTE不香吗,CubeIDE没用过,
回复

使用道具 举报

53

主题

566

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2095
金钱
2095
注册时间
2017-2-11
在线时间
306 小时
 楼主| 发表于 2020-12-2 18:32:48 | 显示全部楼层
旮旯旭 发表于 2020-12-2 18:16
我一直用MDK,MDK的RTE不香吗,CubeIDE没用过,

各有各的好处
回复

使用道具 举报

3

主题

312

帖子

0

精华

高级会员

Rank: 4

积分
907
金钱
907
注册时间
2011-10-19
在线时间
196 小时
发表于 2020-12-2 23:07:51 | 显示全部楼层
看似设置上没什么问题。不过你应该更关注一下bootlader。可以尝试以下操作来排查:
  • 将APP的启动地址改回0x08000000;
  • MDK版bootlader配CubeIDE版APP;
  • CubeIDE版botlader配MDK版APP。

值得注意的是,烧录完成后的程序运行似乎跟手动复位运行的情况并不一样。
我以前也出现过你这样的问题:烧录完可以运行,但手动复位就不能运行,后来发现是Option Bytes上的启动地址设置不正确导致。

另外,我也在CubeIDE上实现过IAP,不过我的片子上的flash较小而SRM很大,所以我把bootlader放SRAM里。IAP时,先用APP接收bootlader固件放到预定SRAM位置,再跳转到SRAM里去运行bootlader,然后才去升级APP。

回复

使用道具 举报

53

主题

566

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2095
金钱
2095
注册时间
2017-2-11
在线时间
306 小时
 楼主| 发表于 2020-12-3 16:23:20 | 显示全部楼层
ufbycd 发表于 2020-12-2 23:07
看似设置上没什么问题。不过你应该更关注一下bootlader。可以尝试以下操作来排查:
  • 将APP的启动地址 ...

  • 我猜测是不是因为我的bootloader用MDK5写的导致的,后期我试着用IDE写个bootloader看看能否运行。
    回复

    使用道具 举报

    0

    主题

    5

    帖子

    0

    精华

    新手上路

    积分
    39
    金钱
    39
    注册时间
    2014-5-22
    在线时间
    5 小时
    发表于 2020-12-4 11:38:58 | 显示全部楼层
    这个应该是一个坑,ide上bootloader跳app会hardfault,
    ide编译完成app的地址第一个字,和keil编译出来的不一样,跳到栈顶不是程序正常运行的起始位置。
    好久之前尝试过ide上写代码,基本完成后想加bootloader,但是发现其编译的结果和我们常规理解的ram起始地址不一样,当时赶时间,全盘移植到keil,
    如果想用ide,可能要忍受一些其他工具不需要忍受的痛。
    回复

    使用道具 举报

    0

    主题

    5

    帖子

    0

    精华

    新手上路

    积分
    39
    金钱
    39
    注册时间
    2014-5-22
    在线时间
    5 小时
    发表于 2020-12-4 11:41:50 | 显示全部楼层
    ufbycd 发表于 2020-12-2 23:07
    看似设置上没什么问题。不过你应该更关注一下bootlader。可以尝试以下操作来排查:
  • 将APP的启动地址 ...

  • bootloader后置或者放在ram中,是一个方法,不过有一个弊端就是假设在写flash的时候断电,那就变砖了,不过我正在用bootloader后置,代价就是,尽量减少升级,尽量测试做足,
    不过此方法能解决楼主的问题。
    回复

    使用道具 举报

    53

    主题

    566

    帖子

    0

    精华

    金牌会员

    Rank: 6Rank: 6

    积分
    2095
    金钱
    2095
    注册时间
    2017-2-11
    在线时间
    306 小时
     楼主| 发表于 2020-12-4 16:44:31 | 显示全部楼层
    stardaniel 发表于 2020-12-4 11:41
    bootloader后置或者放在ram中,是一个方法,不过有一个弊端就是假设在写flash的时候断电,那就变砖了,不 ...

    我试了好多次,都无法跳转到APP程序中,很纳闷。而且我做了一个最简单的工程,点亮一盏灯,还是无法跳转。
    回复

    使用道具 举报

    53

    主题

    566

    帖子

    0

    精华

    金牌会员

    Rank: 6Rank: 6

    积分
    2095
    金钱
    2095
    注册时间
    2017-2-11
    在线时间
    306 小时
     楼主| 发表于 2020-12-4 16:51:32 | 显示全部楼层
    ufbycd 发表于 2020-12-2 23:07
    看似设置上没什么问题。不过你应该更关注一下bootlader。可以尝试以下操作来排查:
  • 将APP的启动地址 ...

  • MDK 的  boot loader  配   MDK的  APP程序,跳转成功  
    MDK 的  boot loader  配   IDE的  APP程序,跳转失败

    理论上说,bootloader应该是没问题,不然MDK 的  boot loader  配   MDK的  APP程序不会错的。
    回复

    使用道具 举报

    3

    主题

    312

    帖子

    0

    精华

    高级会员

    Rank: 4

    积分
    907
    金钱
    907
    注册时间
    2011-10-19
    在线时间
    196 小时
    发表于 2020-12-5 08:12:36 | 显示全部楼层
    jiangyy 发表于 2020-12-4 16:51
    MDK 的  boot loader  配   MDK的  APP程序,跳转成功  
    MDK 的  boot loader  配   IDE的  APP程序,跳 ...

    找不到问题的原因常常是因为想当然。以为xx没有问题,就不去仔细测试xx。
    回复

    使用道具 举报

    53

    主题

    566

    帖子

    0

    精华

    金牌会员

    Rank: 6Rank: 6

    积分
    2095
    金钱
    2095
    注册时间
    2017-2-11
    在线时间
    306 小时
     楼主| 发表于 2020-12-6 17:12:25 | 显示全部楼层
    ufbycd 发表于 2020-12-5 08:12
    找不到问题的原因常常是因为想当然。以为xx没有问题,就不去仔细测试xx。

    ID 的  boot loader  配   IDE的  APP程序,无法跳转,估计IDE这块有问题
    回复

    使用道具 举报

    5

    主题

    35

    帖子

    0

    精华

    中级会员

    Rank: 3Rank: 3

    积分
    221
    金钱
    221
    注册时间
    2018-7-31
    在线时间
    34 小时
    发表于 2021-11-22 10:31:27 | 显示全部楼层
    感谢楼主,第一次用hal库+第一次搞IAP,移植的标准库的程序,跳转前没加初始化RCC,搞了好几天,终于跳转成功了。
    回复

    使用道具 举报

    0

    主题

    1

    帖子

    0

    精华

    新手上路

    积分
    28
    金钱
    28
    注册时间
    2018-3-26
    在线时间
    4 小时
    发表于 2022-1-30 09:05:35 | 显示全部楼层
    楼主厉害啊,我这个也是折磨了我几天就是不行,各种改。我也是发现我的栈顶也是必须这样if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20020000),同时必须加入RCC_DeInit();不然根本不成功。
    回复

    使用道具 举报

    28

    主题

    104

    帖子

    0

    精华

    初级会员

    Rank: 2

    积分
    150
    金钱
    150
    注册时间
    2018-1-11
    在线时间
    64 小时
    发表于 2022-5-9 23:27:06 | 显示全部楼层
    感谢楼主,我用的cubemx做的工程,然后 RCC_DeInit();坑了一天。真是天坑啊
    回复

    使用道具 举报

    30

    主题

    184

    帖子

    0

    精华

    高级会员

    Rank: 4

    积分
    596
    金钱
    596
    注册时间
    2020-4-17
    在线时间
    110 小时
    发表于 2022-5-29 23:39:53 | 显示全部楼层
    jiangyy 发表于 2020-12-4 16:51
    MDK 的  boot loader  配   MDK的  APP程序,跳转成功  
    MDK 的  boot loader  配   IDE的  APP程序,跳 ...

    可以了吗,是什么原因跳转不了
    回复

    使用道具 举报

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

    本版积分规则



    关闭

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

    正点原子公众号

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

    GMT+8, 2024-12-5 04:21

    Powered by OpenEdv-开源电子网

    © 2001-2030 OpenEdv-开源电子网

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