硬汉嵌入式论坛

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

[其它] stm32g031在进行IAP在线升级时,使用串口DMA+空闲中断接收不定长度数据,当接受到跳转指令,就执行跳转

[复制链接]

3

主题

4

回帖

13

积分

新手上路

积分
13
发表于 2023-7-30 23:01:37 | 显示全部楼层 |阅读模式
我用stm32g031在进行IAP在线升级时,使用串口DMA+空闲中断接收不定长度数据,当接受到跳转指令,就执行跳转。但是将跳转函数加到主函数的while里面,程序就会卡死,请问大家有遇见这样的吗?
下载 (2).png
这是我的跳转函数
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
发表于 2023-7-31 08:44:08 | 显示全部楼层
楼主测试用的MDK AC5还是AC6, 优化等级多少

1、这个变量BootAddr改成全局变量。
2、HAL_RCC_Deinit放在三条Systick前面。
回复

使用道具 举报

3

主题

4

回帖

13

积分

新手上路

积分
13
 楼主| 发表于 2023-7-31 09:32:33 | 显示全部楼层
感谢感谢,我去试试
回复

使用道具 举报

3

主题

4

回帖

13

积分

新手上路

积分
13
 楼主| 发表于 2023-7-31 09:51:20 | 显示全部楼层
eric2013 发表于 2023-7-31 08:44
楼主测试用的MDK AC5还是AC6, 优化等级多少

1、这个变量BootAddr改成全局变量。

应该是AC5,我按照你说的改了一下,还是不行,还是不管上位机有没有发数据,空闲中断都会自动进入
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
发表于 2023-7-31 09:54:56 | 显示全部楼层
hcr 发表于 2023-7-31 09:51
应该是AC5,我按照你说的改了一下,还是不行,还是不管上位机有没有发数据,空闲中断都会自动进入

这个的话,就与boot跳转没有关系了,是你自己程序设计问题,前面我理解成了你boot卡死了。

上电自动进入空闲中断没关系,很多时候上电使能空闲中断后会立即进入一次,这个是正常的。其他问题自己再找找吧
回复

使用道具 举报

3

主题

4

回帖

13

积分

新手上路

积分
13
 楼主| 发表于 2023-7-31 09:56:18 | 显示全部楼层
eric2013 发表于 2023-7-31 09:54
这个的话,就与boot跳转没有关系了,是你自己程序设计问题,前面我理解成了你boot卡死了。

上电自动进 ...

好的,感谢
回复

使用道具 举报

4

主题

46

回帖

58

积分

初级会员

积分
58
发表于 2023-7-31 13:25:00 | 显示全部楼层
[C] 纯文本查看 复制代码
//板卡IAP跳转到APP
ERROR_SUB BoardIapJumpApp(void)
{
    ERROR_SUB errorSub = ERROR_SUB_OK;
    uint32_t app_address = MCU_FLASH_APP;
    //首先检测APP是否存在
    uint32_t stackPointAddr = ((*(volatile uint32_t*)app_address)&0xF0000000);
    //检查栈顶地址是否合法.D1_DTCMRAM_BASE是DTCM的起始地址,也是程序的栈顶地址
    //如果这个位置的数据不对,那么说明没有APP
    if(stackPointAddr != D1_DTCMRAM_BASE)	
    {
        MCU_LogPrintf("BoardIapJumpApp App stackPointAddr: 0X%08X,Need 0X%08X\r\n",stackPointAddr,D1_DTCMRAM_BASE);
        //不存在APP程序,设置失败并设置运行模式是BOOT模式
        errorSub = BoardParamSetRunningModeBoot();
        return errorSub;
    }
    //系统运行模式修改为APP模式
    errorSub = BoardParamSetRunningModeApp();
    if(errorSub != ERROR_SUB_OK)
    {
        MCU_LogPrintf("BoardParamSetRunningModeApp Failed,ErrorSub: 0X%08X\r\n",errorSub);
        return errorSub;
    }
    //存在APP而且可以跳转
    MCU_LogPrintf("BoardIapJumpApp Start\r\n");
    CoreDelayMs(10);
    //系统锁定
    lastBoardIapGlobalIntState = CoreLockIntGlobal();
    //清除系统全部中断
    CoreClearSystemAllInt();
    //获取当前中断向量偏移
    vtorBoardIapCurrent = SCB->VTOR;
    //设置新的中断向量
    SCB->VTOR = app_address;
    //获取线程PSP
    pspBoardIapCurrent = __get_PSP();
    //设置线程PSP
    __set_PSP(*(uint32_t*)app_address);
    //强制切换到特权级
    __set_CONTROL(0);
    //获取主堆栈MSP
    mspBoardIapCurrent = __get_MSP();
    //设置主堆栈MSP
    __set_MSP(*(uint32_t*)app_address);
    //系统刷新,保证设置生效
    __ISB();
    //强制跳转
    ((BoardIapJmpAddressFuncPtr)(*(uint32_t*)(app_address + 4)))();
    //到这里,应该执行不下去了,如果执行到这里,需要修复系统运行时环境
    SCB->VTOR = vtorBoardIapCurrent;
    //设置MSP,现在还是特权模式
    __set_MSP(mspBoardIapCurrent);
    //退出特权模式
    __set_CONTROL(1);
    //设置PSP,现在是线程模式了
    __set_PSP(pspBoardIapCurrent);
    //系统刷新,保证设置生效
    __ISB();
    //解锁
    CoreUnlockIntGlobal(lastBoardIapGlobalIntState);
    //报错
    MCU_LogPrintf("BoardIapJumpApp Failed\r\n");
    CoreDelayMs(10);
    //跳转失败,系统运行模式修改为BOOT模式
    errorSub = BoardParamSetRunningModeBoot();
    if(errorSub != ERROR_SUB_OK)
    {
        MCU_LogPrintf("BoardParamSetRunningModeBoot Failed,ErrorSub: 0X%08X\r\n",errorSub);
        return errorSub;
    }
    return ERROR_SUB_BOARD_IAP_JMP_APP_FAILED;
}
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-29 18:11 , Processed in 0.282603 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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