硬汉嵌入式论坛

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

[有问必答] 请教一下,基于stm32f1的IAP跳转的奇怪问题

[复制链接]

2

主题

7

回帖

13

积分

新手上路

积分
13
发表于 2022-3-16 21:10:38 | 显示全部楼层 |阅读模式
我用stm32F103zet6做的iap 基于ymodem协议的升级。内存够大,我算过,没有超出。采用的systick,状态机轮询,下载app


但是常常下载app,卡在了JumpToApp();失败的多,成功跳转的少。

但是奇怪的是:
   1、有时候成功跳转,运行正常,但是我再擦除,下载,又失败了,卡在跳转函数处JumpToApp()
   2、有时候跳转只执行了app工程的初始化-打印logo信息,没有进入main中while循环;
   3、有时候卡住,没有进入main第一行;
但是,再调试模式下又都正常!

我使用的外设和中断都在跳转之前都关闭、复位了了,但还是上述情况!


  1. HAL_UART_MspDeInit(&huart2);
  2. HAL_NVIC_DisableIRQ(USART2_IRQn); //恢复NVIC为复位状态.使中断不再发生
  3. HAL_NVIC_ClearPendingIRQ(USART2_IRQn);
  4. HAL_UART_DeInit(&huart2);

  5. HAL_NVIC_DisableIRQ(DMA1_Channel6_IRQn);
  6. HAL_NVIC_DisableIRQ(DMA1_Channel7_IRQn);

  7. // 设置所有时钟到默认状态,使用HSI时钟
  8. HAL_RCC_DeInit();
  9. //__HAL_RCC_USART2_CLK_DISABLE();

  10. // 关闭所有中断,清除所有中断挂起标志
  11. for (int i = 0; i < 8; i++)
  12. {
  13. NVIC->ICER[i]=0xFFFFFFFF;
  14. NVIC->ICPR[i]=0xFFFFFFFF;
  15. }

  16. HAL_RCC_DeInit();

  17. // 关闭滴答定时器,复位到默认值
  18. SysTick->CTRL = 0;
  19. SysTick->LOAD = 0;
  20. SysTick->VAL = 0;

  21. HAL_DeInit();
  22. HAL_NVIC_DisableIRQ(SysTick_IRQn); //
  23. HAL_NVIC_ClearPendingIRQ(SysTick_IRQn); //清除外部中断的挂起位。

  24. //关闭全局中断
  25. //__set_PRIMASK(1);
  26. __disable_irq();
复制代码
我在app工程,打开中断,还是一样的效果...
而且我下载app的bin文件之后,调试读取app区的flash,是有值的,

有时能跳转成功、回跳等,说明中断向量地址是对的;下载app的bin文件,我读取flash也有值,擦除、读、写都没问题;

实在找不到问题了,脑袋晕...
求哪位大佬指点一下!!






回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117563
QQ
发表于 2022-3-17 09:20:43 | 显示全部楼层
应该是跳转前,环境还不够干净,要不试试我下面这个。

实战技能分享,一劳永逸的解决BOOT跳转APP失败问题,含MDK AC5,AC6和IAR,同时制作了一个视频操作说明
https://forum.anfulai.cn/forum.p ... 9595&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

2

主题

7

回帖

13

积分

新手上路

积分
13
 楼主| 发表于 2022-3-17 11:14:21 | 显示全部楼层
eric2013 发表于 2022-3-17 09:20
应该是跳转前,环境还不够干净,要不试试我下面这个。

实战技能分享,一劳永逸的解决BOOT跳转APP失败问 ...

谢谢!你的分享加载设置:那里没看懂,但是源码中好像是直接设置标记位,复位读取标记位进行跳转,大概意思明白了,放在main初始化之后判断有没有影响?还有什么要注意的地方吗?我去试一下
回复

使用道具 举报

2

主题

7

回帖

13

积分

新手上路

积分
13
 楼主| 发表于 2022-3-17 14:06:54 | 显示全部楼层
eric2013 发表于 2022-3-17 09:20
应该是跳转前,环境还不够干净,要不试试我下面这个。

实战技能分享,一劳永逸的解决BOOT跳转APP失败问 ...

还是不行!
  1. void jump_init(void)
  2. {
  3.         if (g_JumpInit == 0x00001111)                /* 软件复位后再进入APP,提供一个干净的CPU环境给APP */
  4.         {       
  5.         /* 去执行APP程序 */
  6.         if(JumpToApp(Application_1_Addr)) //跳转失败
  7.             Set_Start_Mode(Startup_Normol); //0xFFFF FFFF 默认标志的数据(空片子的情况)                                   
  8.         }
  9.         else
  10.         {
  11.                 /* 返回 */
  12.         return;
  13.         }
  14. }
复制代码


我在跳转之前复位,在main中一开始就进入该函数(初始化之前),还是有时候跳不过去
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117563
QQ
发表于 2022-3-17 18:08:37 | 显示全部楼层

现在确定一个问题,上电后main函数里面直接跳转,不要做任何初始化了,你看看是否正常。
回复

使用道具 举报

2

主题

7

回帖

13

积分

新手上路

积分
13
 楼主| 发表于 2022-3-17 19:58:51 | 显示全部楼层
eric2013 发表于 2022-3-17 18:08
现在确定一个问题,上电后main函数里面直接跳转,不要做任何初始化了,你看看是否正常。

是下载了app程序后吗?现在就是下载app后,复位,从mian进入,就跳转;
改成mian就留这个跳转函数?是确定跳转的问题还是其他原因?我试着屏蔽systcik中断源,失能它,结果我printf都打印不出来...
我试一下,谢谢
回复

使用道具 举报

2

主题

7

回帖

13

积分

新手上路

积分
13
 楼主| 发表于 2022-3-18 09:15:38 | 显示全部楼层
eric2013 发表于 2022-3-17 18:08
现在确定一个问题,上电后main函数里面直接跳转,不要做任何初始化了,你看看是否正常。

传bin文件之后复位,进入main第一个就是执行这个跳转,跳转失败或标记判断不对,就开始初始化,跳不过
回复

使用道具 举报

3

主题

70

回帖

79

积分

初级会员

积分
79
发表于 2022-3-18 10:10:31 | 显示全部楼层
bootloader里面, 开了什么外设,开了什么中断, 在跳转之前统统关掉,
给你看看我的
bootloader -------------------------------------------

extern HCD_HandleTypeDef hUsbHostFS;
extern USBH_HandleTypeDef hUsbHostHS;
extern  UART_HandleTypeDef huart1;
extern HCD_HandleTypeDef hhcd_USB_OTG_FS;
extern HCD_HandleTypeDef hhcd_USB_OTG_HS;
extern TIM_HandleTypeDef htim1;
extern SPI_HandleTypeDef hspi1;
//extern SPI_HandleTypeDef hspi3;

typedef  void ( *pFunction ) ( void );
uint8_t COMMAND_Jump_to_Application ( void )
{
    uint32_t JumpAddress;
    static pFunction Jump_To_Application;

    uint32_t dwDelay = 0;

    /* Check Vector Table: Test if user code is programmed starting from
     * address "APPLICATION_ADDRESS" */
    if (   ( ( ( * ( __IO uint32_t * ) APP_START_ADDR ) & 0xFF000000 ) == 0x20000000 )
        || ( ( ( * ( __IO uint32_t * ) APP_START_ADDR ) & 0xFF000000 ) == 0x10000000 ) )
    {
        debug_msg_y ( "jump to application... 0x%08x \r\n", APP_START_ADDR );
        // __disable_irq();

      __HAL_HCD_CLEAR_FLAG(&hhcd_USB_OTG_HS, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
      __HAL_HCD_CLEAR_FLAG(&hhcd_USB_OTG_HS, USB_OTG_GINTSTS_IISOIXFR);
      __HAL_HCD_CLEAR_FLAG(&hhcd_USB_OTG_HS, USB_OTG_GINTSTS_PTXFE);
      __HAL_HCD_CLEAR_FLAG(&hhcd_USB_OTG_HS, USB_OTG_GINTSTS_MMIS);
      __HAL_HCD_CLEAR_FLAG(&hhcd_USB_OTG_HS, USB_OTG_GINTSTS_DISCINT);
      __HAL_HCD_CLEAR_FLAG(&hhcd_USB_OTG_HS, USB_OTG_GINTSTS_SOF);
      __HAL_HCD_CLEAR_FLAG(&hhcd_USB_OTG_HS, USB_OTG_GINTSTS_HCINT);

        HAL_HCD_MspDeInit ( &hhcd_USB_OTG_HS ); // &hUsbHostFS );
        HAL_UART_MspDeInit( &huart1 );
        HAL_SPI_MspDeInit ( &hspi1 );
        //HAL_SPI_MspDeInit ( &hspi3 );

        __HAL_TIM_CLEAR_IT( &htim1, TIM_IT_UPDATE);
        __HAL_TIM_CLEAR_FLAG ( &htim1, TIM_FLAG_UPDATE);
        HAL_SuspendTick();

        HAL_Init();
        HAL_RCC_DeInit();
        HAL_DeInit();

__set_FAULTMASK(1);


        dwDelay = 100000;
        while ( dwDelay-- )
        {
        }

        /* Jump to user application */
        JumpAddress = * ( __IO uint32_t * ) ( APP_START_ADDR + 4 );
        Jump_To_Application = ( pFunction ) JumpAddress;

        /* Initialize user application's Stack Pointer */
        __set_MSP ( * ( __IO uint32_t * ) APP_START_ADDR );
        Jump_To_Application();

        while ( 1 )
        {

        }
    }
    else
    {

        printf ( "application is not found.\r\n" );

        return 0;
    }
}

application ------------------------------
int main(void)
{
  /* USER CODE BEGIN 1 */
__set_FAULTMASK(0);
  /* 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();
  MX_DMA_Init();
  MX_ADC1_Init();
回复

使用道具 举报

2

主题

7

回帖

13

积分

新手上路

积分
13
 楼主| 发表于 2022-3-19 15:36:14 | 显示全部楼层
westzg 发表于 2022-3-18 10:10
bootloader里面, 开了什么外设,开了什么中断, 在跳转之前统统关掉,
给你看看我的
bootloader ---------- ...

我之前也是这样的,不行
回复

使用道具 举报

1

主题

5

回帖

8

积分

新手上路

积分
8
发表于 2022-6-16 14:39:47 | 显示全部楼层
我分享一下我之前遇到的问题,现象和楼主非常像,就是接仿真器调试没问题,正常运行的时候有概率跑飞。

loader里面设置PLL把时钟频率升起来,然后跳转APP之前降低时钟频率不能一下子降下去,要分几个频率段去降,否则就会出现问题。
至于硬件调试的时候为什么不出问题,好像是因为硬件调试的时候时钟频率是会降下来的。

如果是其他问题,硬件调试的时候应该都是可以检测到的,如果有中断触发都是会按照中断向量表跳转的。

我建议可以试试loader里面系统时钟就用默认的HSI频率,不要用PLL。
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2023-3-13 23:19:30 | 显示全部楼层
楼主问题解决没,怎么解决的,我的一样有这个问题。。。。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-14 16:18 , Processed in 0.042800 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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