GD32单片机IAP跳转后APP仅执行部分代码问题求助
GD32 IAP跳转后APP仅执行部分代码排查方案
问题描述
使用与STM32架构相似的GD32单片机进行IAP升级操作,从BootLoader跳转至APP程序后,APP仅能执行部分代码:
- Flash分区:BootLoader占用0x08000000起始的12KB区域,APP占用0x08003000起始的26KB区域
- 跳转后APP仅能执行蓝灯点亮代码,后续逻辑无响应;编译生成的APP bin文件仅5KB,远小于分区容量
- 已检查项目编译设置并修改APP代码,仍出现卡死现象
APP主函数代码:
int main(void) { // 初始化 nvic_vector_table_set(0x08000000, 0x3000); systick_config(); Usart_Init(); systimer_init(); Gpio_Init(); DbgPrintf("START \n"); Light_Display(BLUE); delay_1ms(2000); // for(uint8_t i = 0; i < 5; i++) // { // //DbgPrintf("test3\n"); // delay_1ms(1000); // Light_Display(i); // DbgPrintf("Current i: %d\n", i); // } Light_Display(GREEN); }
可能原因及解决方法
1. 向量表配置错误
APP的向量表偏移需与Flash分区严格匹配,同时BootLoader跳转时需正确加载APP的栈指针与复位地址:
- 确认APP链接脚本中ROM起始地址为
0x08003000,栈地址配置在合法RAM区域 - 修正APP中的向量表设置:
// 直接指定APP的向量表基地址 nvic_vector_table_set(0x08003000, 0); // 或使用偏移方式(Flash基地址+APP起始偏移) nvic_vector_table_set(NVIC_VECTTAB_FLASH, 0x3000);
2. BootLoader跳转前未清理中断状态
跳转前需彻底终止BootLoader的中断与定时器,避免残留状态干扰APP运行:
BootLoader跳转代码需补充以下逻辑:
__disable_irq(); // 关闭全局中断 // 停止SysTick定时器并清空寄存器 SysTick->CTRL = 0; SysTick->LOAD = 0; SysTick->VAL = 0; // 禁用所有中断并清理挂起标志 for(uint32_t i = 0; i < 8; i++){ NVIC->ICER[i] = 0xFFFFFFFF; NVIC->ICPR[i] = 0xFFFFFFFF; } // 执行APP跳转 typedef void (*pFunction)(void); pFunction JumpToApp = (pFunction)(*(uint32_t*)(0x08003000 + 4)); __set_MSP(*(uint32_t*)0x08003000); // 切换至APP栈指针 JumpToApp();
3. SysTick延时函数异常
若delay_1ms基于SysTick实现,BootLoader残留的SysTick配置可能导致延时死循环:
- 替换
delay_1ms(2000)为简单空循环测试(根据单片机主频调整循环次数):// 12MHz主频下的2秒空循环延时示例 for(uint32_t cnt = 0; cnt < 24000000; cnt++); - 若替换后能执行到绿灯点亮,需重新检查
systick_config()的时钟源、重载值配置是否正确。
4. 外设初始化冲突
BootLoader可能已初始化部分外设(如串口、定时器),APP重复初始化时未正确复位:
- 在APP的外设初始化函数前,先复位对应外设寄存器,例如串口初始化前:
rcu_periph_reset_enable(RCU_USART0); rcu_periph_reset_disable(RCU_USART0);
内容的提问来源于stack exchange,提问作者zhangkai
相关产品推荐
相关产品推荐

