硬汉嵌入式论坛

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

[BOOT/IAP] stm32h7 bootloader跳转app不能运行

[复制链接]

3

主题

17

回帖

26

积分

新手上路

积分
26
发表于 2023-5-10 12:27:11 | 显示全部楼层 |阅读模式
求助。stm32h7做IAP,bootloader和app都是用cubemx的hal库写的,两个程序都用了FreeRTOS,其中bootloader用了硬汉哥一劳永逸的软件复位方法。现象是:
第一:如果手动用keil下载app到0x08040000,然后在bootloader的main函数第一句直接jump to app,可以运行app,说明app程序应该没有问题。
第二:如果在bootloader里通过网口下载好app程序并写入Flash(调试bootloader看过写入的数据,完全正确),然后设置好标志位,软件复位后判断标志位,直接jump to app,这样app跳过去就会卡死在SystemClock_Config里面。而且每次调试app总是跑飞在不同的位置,有时候卡死在
        while (__HAL_RCC_GET_SYSCLK_SOURCE() !=  (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
        {
          if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
          {
            return HAL_TIMEOUT;
          }
        }
有时候跳过了这里卡死在后面的

  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

app程序中,在main函数第一句设置中断向量表偏移和在systeminit里面直接改VECT_TAB_OFFSET都试过,都不能运行。
请问是什么原因导致第一种情况app可以运行而第二种情况app不能运行呢?
回复

使用道具 举报

3

主题

17

回帖

26

积分

新手上路

积分
26
 楼主| 发表于 2023-5-10 12:28:44 | 显示全部楼层
硬汉哥可以指点一下吗
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106738
QQ
发表于 2023-5-10 14:58:00 | 显示全部楼层
你的“软件复位后判断标志位,直接jump to app” 和你的“main函数第一句直接jump to app” 是不是有区别。从你的描述来看,跳转前应该还有点问题。
回复

使用道具 举报

3

主题

17

回帖

26

积分

新手上路

积分
26
 楼主| 发表于 2023-5-10 15:42:10 | 显示全部楼层
刚刚又全部验证了一遍,情况和上面说的没有变化,附上代码如下:


bootloader的主函数(直接跳就不注释最后一行,平常是注释的):
int main(void)
{
  /* USER CODE BEGIN 1 */
                if(g_JumpInit==0xaa553344){
                if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
                {
                        iap_load_app(FLASH_APP1_ADDR);//执行FLASH APP代码
                }
}
iap_load_app(FLASH_APP1_ADDR);//执行FLASH APP代码


IAP更新的代码(在这里写入Flash完成后,设置标志位然后软件复位):
        //IAP更新代码
                        if(((*(vu32*)(0x24010000+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
                        {
                                iap_write_appbin(FLASH_APP1_ADDR,UPDATE_BUF,appsize);//更新FLASH代码   
                        }
                        appsize=0;
                        is_CGI_getdata=0;
                        g_JumpInit=0xaa553344;
                        HAL_NVIC_SystemReset(); // 复位


跳转函数:
//跳转到应用程序段
//appxaddr:用户代码起始地址.
void iap_load_app(uint32_t appxaddr)
{        
        if(((*(vu32*)appxaddr)&0x2FF00000)==0x24000000)        //检查栈顶地址是否合法.
        {
                jump2app=(iapfun)*(vu32*)(appxaddr+4);                //用户代码区第二个字为程序开始地址(复位地址)               
                        /* 设置主堆栈指针 */
                MSR_MSP(*(vu32*)appxaddr);
                __set_CONTROL(0);
                jump2app();                                                                        //跳转到APP.
        }
}


app死在了这里:
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
再具体一点是HAL_RCC_ClockConfig这个函数里面的
tickstart = HAL_GetTick();

        while (__HAL_RCC_GET_SYSCLK_SOURCE() !=  (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
        {
          if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
          {
            return HAL_TIMEOUT;
          }
        }
在这一段跑飞了。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106738
QQ
发表于 2023-5-10 15:55:09 | 显示全部楼层
菜鸟9号 发表于 2023-5-10 15:42
刚刚又全部验证了一遍,情况和上面说的没有变化,附上代码如下:

为什么代码都喜欢加个这种东西,一点用没有。
如果APP程序主RAM用的TCM,0x2000 0000还没法玩了。

if(((*(vu32*)(0x24010000+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
回复

使用道具 举报

3

主题

17

回帖

26

积分

新手上路

积分
26
 楼主| 发表于 2023-5-10 16:46:51 | 显示全部楼层
硬汉哥您好,我是从正点原子h7的串口IAP例程改过来的,正点原子在0x24010000处定义了一个接收app数据的数组,我用的是网口接收app数据,也需要这样一个数组,所以这个地方没有改,这个if判断会造成什么影响吗?
另外“如果APP程序主RAM用的TCM,0x2000 0000还没法玩了。”这句我不是很懂,我看了一下目前app的栈指针是初始化在0x2400fca0,这是app程序地址的配置
C:\Users\001\Desktop\666.png
回复

使用道具 举报

3

主题

17

回帖

26

积分

新手上路

积分
26
 楼主| 发表于 2023-5-10 16:56:57 | 显示全部楼层
不好意思,不太会用这个发图片。。
666.png
回复

使用道具 举报

36

主题

1445

回帖

1553

积分

至尊会员

积分
1553
发表于 2023-5-10 17:08:42 | 显示全部楼层
eric2013 发表于 2023-5-10 15:55
为什么代码都喜欢加个这种东西,一点用没有。
如果APP程序主RAM用的TCM,0x2000 0000还没法玩了。

老大 他这个不是判断栈顶,判断的是栈顶后面4个字节的值
11.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106738
QQ
发表于 2023-5-10 17:14:19 | 显示全部楼层
sanit 发表于 2023-5-10 17:08
老大 他这个不是判断栈顶,判断的是栈顶后面4个字节的值

一样,如果是外部QSPI Flash,0x9000 0000怎么玩,如果加载到SDRAM,地址是0xC000 0000怎么玩。

通用性很差,一点用没有。

之前我在很多地方都谈过这个问题,自己写的APP,自己还不知道能不能用吗


回复

使用道具 举报

3

主题

17

回帖

26

积分

新手上路

积分
26
 楼主| 发表于 2023-5-10 17:55:01 | 显示全部楼层
好的,以后我会注意这个判断,确实是在这里没有考虑到外部Flash和RAM运行的情况,谢谢硬汉哥指点。
那么我遇到的这个问题来说,跳转前是存在什么问题,才会导致“软件复位后判断标志位,直接jump to app” 和“main函数第一句直接jump to app”之间的区别呢,我实在找不到这个
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106738
QQ
发表于 2023-5-11 00:30:01 | 显示全部楼层
菜鸟9号 发表于 2023-5-10 17:55
好的,以后我会注意这个判断,确实是在这里没有考虑到外部Flash和RAM运行的情况,谢谢硬汉哥指点。
那么我 ...

除了做个地方,还有个关键地方忘了排除了,你的网口更新程序,APP程序做CRC校验之类的没,建议看下更新的正确不。
回复

使用道具 举报

3

主题

17

回帖

26

积分

新手上路

积分
26
 楼主| 发表于 2023-5-11 21:16:31 | 显示全部楼层
多谢硬汉哥。根据您的指点,把Flash的数据全部检查一遍,排查出网口传输确实存在一点问题,传170k的数据错了几个字节,都是把0x20错误地传输成了0x00,现在改了传输方式app,写入Flash的数据正确了,app可以运行了。
最开始调试的时候也有这个数据可能不正确的想法,但是那时候在调试界面检查了写入Flash的前2k字节都没有问题,就认为这方面出问题的概率很低,没有全部检查。没想到这。。。传输这么多数据偏偏错了那么几个字节。
多谢硬汉哥和各位大佬的指点,帮助我建立了好的检查思维。
回复

使用道具 举报

3

主题

1222

回帖

1231

积分

至尊会员

积分
1231
发表于 2023-5-12 08:43:03 | 显示全部楼层
((*(vu32*)(0x24010000+4))&0xFF000000)==0x08000000
这个检查,是不是也去掉了?
回复

使用道具 举报

14

主题

62

回帖

104

积分

初级会员

积分
104
发表于 2023-5-12 11:21:46 | 显示全部楼层
boot 调 APP前清空RAM
回复

使用道具 举报

3

主题

17

回帖

26

积分

新手上路

积分
26
 楼主| 发表于 2023-5-23 11:26:24 | 显示全部楼层
morning_enr6U 发表于 2023-5-12 08:43
((*(vu32*)(0x24010000+4))&0xFF000000)==0x08000000
这个检查,是不是也去掉了?

这句检查入口地址在我这个程序里面有没有都不会造成影响,我没有管它。如果你要用到这句判断,就得先搞清楚Flash的确定位置,比如可能有外部Flash
回复

使用道具 举报

3

主题

17

回帖

26

积分

新手上路

积分
26
 楼主| 发表于 2023-5-23 11:27:43 | 显示全部楼层
apleilx 发表于 2023-5-12 11:21
boot 调 APP前清空RAM

清空了,按照硬汉哥的思路,下载完app程序后直接软件复位,然后重新上电跳过去。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-3 02:46 , Processed in 0.306351 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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