笔记本的自嘲 发表于 2022-9-30 09:36:52

[求助]V6开发板跳转系统BootLoader失败

开发环境:win10专业版
IDE:mdk5.37.0.0

软件是通过STM32CUBEMX生成的最小测试系统,方便测试这个问题。

MCU资源用到了TIM9(1000ms)/USART1(软件中未开启接收中断,只用了输出功能)/PB6(Output)/PC13(Input)。

实测发现,软件无法从APP跳转到系统BootLoader,其表现就是按下KEY2后串口反复打印system start,同时PB6引脚上的灯(自己焊接的)还是会1s周期闪烁,这是系统在不断复位。如果成功跳转的话,串口将不会有任何输出,灯也不会闪烁。


根据ST官网如下链接,已经试了-O0/-O1两种优化等级,还是无法将软件保持在BootLoader。
IAP bootloader not jumping to the application address. (st.com)
application jump to system memory bootloader

有没有道友遇到过这个问题呢?

eric2013 发表于 2022-9-30 11:07:43

意思是boot向app跳转正常,而app像boot跳转不正常? 这种情况在app里面直接调用systemreset函数就行了,就重新从boot开始运行了。不知道是否满足楼主的需求。

笔记本的自嘲 发表于 2022-9-30 11:17:36

eric2013 发表于 2022-9-30 11:07
意思是boot向app跳转正常,而app像boot跳转不正常? 这种情况在app里面直接调用systemreset函数就行了,就 ...

不是呢,我是根据咱们的例程《V6-009_基于系统bootloader的USB接口方式IAP升级(USB DFU)》,在做从App跳转到系统BootLoader的实验,结果发现一运行跳转代码系统就复位了。

笔记本的自嘲 发表于 2022-9-30 16:13:07

自己发的问题自己回复下解决方案。
现在发现将全局中断开启这句关掉,代码优化开-O1就能正常跳转,但是代码优化设置成O0就不行。这个现象我无法理解,这么小的代码量堆栈也不会超啊。有谁知道吗?
static void JumpToBootloader(void)
{
    uint32_t i = 0;
    void (*SysMemBootJump)(void);      /* 声明一个函数指针 */
    __IO uint32_t BootAddr = 0x1FFF0000; /* STM32F4的系统BootLoader地址 */

    /* 关闭全局中断 */
    DISABLE_INT();

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

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

    /* 关闭所有中断,清除所有中断挂起标志 */
    for (i = 0; i < 8; i++)
    {
      NVIC->ICER=0xFFFFFFFF;
      NVIC->ICPR=0xFFFFFFFF;
    }

    //注释掉这句就行了
//    /* 使能全局中断 */
//    ENABLE_INT();

    /* 设置重映射到系统Flash */
    __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();

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

    /* 设置朱堆栈指针 */
    __set_MSP(*(uint32_t *)BootAddr);

    /* 在RTOS工程,这条语句很重要,设置为特权级模式,使用MSP指针 */
    __set_CONTROL(0);

    /* 跳转到系统BootLoader */
    SysMemBootJump();

    /* 跳转成功的话,不会执行到这里,用户可以在这里添加代码 */
    while (1)
    {

    }
}

eric2013 发表于 2022-10-1 00:29:12

笔记本的自嘲 发表于 2022-9-30 16:13
自己发的问题自己回复下解决方案。
现在发现将全局中断开启这句关掉,代码优化开-O1就能正常跳转,但是代 ...
特别注意,函数
HAL_RCC_DeInit();

要放在下面函数的前面,因为这个HAL_RCC_DeInit会再次开启滴答定时器。

SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;

笔记本的自嘲 发表于 2022-10-1 18:40:47

eric2013 发表于 2022-10-1 00:29
特别注意,函数
HAL_RCC_DeInit();



有效果,但是无法连接programmer,翻了以前的帖子,买了个FT232再试下,谢谢老大,国庆快乐鸭
页: [1]
查看完整版本: [求助]V6开发板跳转系统BootLoader失败