GD32IAP 升级中 APP 中断失效问题总结
因为在这个c文件中存在下面这个函数#else#endifIROM1 设置 ≠ VTOR 设置IAP 架构下,APP 必须独立完成中断向量表重定位“能跳转但不进中断”是 IAP 中非常典型的问题现象建议统一在中完成 VTOR 配置,避免遗漏在 IAP 架构中,APP 中断失效的根本原因是未正确重定位中断向量表(SCB->VTOR),而非程序跳转或链接地址错误。备注:该问题是学习过程中遇到的实际问题,
一、问题背景
在基于 GD32F103(Cortex-M3) 的 IAP 升级方案中,系统采用 Bootloader + APP 的 Flash 分区架构:
- Bootloader 位于 Flash 起始地址
0x08000000 - APP 位于 Flash 地址
0x08005000 - 通过 Bootloader 跳转方式进入 APP 程序运行
在实际测试中发现:
APP 程序可以正常跳转并执行
main(),但所有中断(如 SysTick、外设中断)均无法进入。
二、问题现象
- Bootloader 运行正常
- 跳转到 APP 后:
- 主循环可执行
- 外设初始化正常
- 中断函数不响应
该问题在 IAP 场景下具有较强的迷惑性。
三、问题原因分析
1. Keil 中 IROM1 的作用被误解
在 APP 工程中已将 Keil 的 IROM1 起始地址设置为 0x08005000,但该设置:
- 仅影响链接阶段
- 决定代码在 Flash 中的存放位置
- 不会影响 CPU 运行时中断向量表的位置
2. Cortex-M3 中断向量表机制
- 中断向量表地址由 SCB->VTOR(Vector Table Offset Register) 决定
- MCU 上电或复位后,
VTOR默认指向:0x08000000 - 在 IAP 场景中:
- APP 实际运行在
0x08005000 - 若未重新设置
VTOR - 中断仍从 Bootloader 的向量表取入口地址
- APP 实际运行在
3. “能进 main 但不进中断”的本质原因
main()是通过 Bootloader 手动设置 MSP 和 PC 跳转执行的- 中断入口是由 NVIC 根据
VTOR自动查表 - 两者机制不同,导致:
- 主程序可运行
- 中断入口地址错误,无法进入 APP 的中断服务函数
四、问题定位结论
问题根因:APP 程序未将中断向量表重定位到自身的 Flash 起始地址(VTOR 未正确设置)。
五、解决方案
1. 在 APP 工程中的system_gd32f10x.c文件中添加一个宏定义
#define VECT_TAB_OFFSET (uint32_t)0x5000 /* vector table base offset */
因为在这个c文件中存在下面这个函数
#ifdef VECT_TAB_SRAM
nvic_vector_table_set(NVIC_VECTTAB_RAM, VECT_TAB_OFFSET);
#else
nvic_vector_table_set(NVIC_VECTTAB_FLASH, VECT_TAB_OFFSET);
#endif
}
2. Bootloader 与 APP 的职责划分
- Bootloader:
- 负责升级、校验、跳转
- 不负责 APP 的中断向量表设置
- APP:
- 负责自身运行环境初始化
- 包括时钟、中断、VTOR 设置
六、最终结果
- APP 程序中断功能恢复正常
- IAP 架构运行稳定
- 系统符合 Cortex-M 工程规范及工业实践
七、经验总结
- IROM1 设置 ≠ VTOR 设置
- IAP 架构下,APP 必须独立完成中断向量表重定位
- “能跳转但不进中断”是 IAP 中非常典型的问题现象
- 建议统一在
SystemInit()中完成 VTOR 配置,避免遗漏
八、一句话总结
在 IAP 架构中,APP 中断失效的根本原因是未正确重定位中断向量表(SCB->VTOR),而非程序跳转或链接地址错误。
备注:该问题是学习过程中遇到的实际问题,该文由AI辅助整理
更多推荐



所有评论(0)