







根据您描述的现象和配置,qBoot跳转后卡在App系统调用处或不断重启,通常由以下原因导致:
中断向量表未重定位
// 在App的main.c开头添加(需在启用中断前执行)
SCB->VTOR = FLASH_BASE | 0x10000; // 与QBOOT_APP_ADDR对齐跳转前未完全复位外设
改进的跳转函数:
void qbt_jump_to_app(void) {
typedef void (*app_func_t)(void);
uint32_t app_addr = QBOOT_APP_ADDR;
uint32_t stk_addr = *((volatile uint32_t*)app_addr);
app_func_t app_func = (app_func_t)(*((volatile uint32_t*)(app_addr + 4)));
// 关键复位序列
__disable_irq();
SysTick->CTRL = 0;
HAL_RCC_DeInit();
HAL_DeInit();
// 禁用所有中断
for (int i = 0; i < 8; i++) {
NVIC->ICER[i] = 0xFFFFFFFF; // 禁用中断
NVIC->ICPR[i] = 0xFFFFFFFF; // 清除挂起标志
}
// 设置寄存器回到复位状态
__set_CONTROL(0);
__set_MSP(stk_addr); // 主堆栈指针重置
__DSB();
__ISB();
// 直接跳转(不使用函数调用避免堆栈问题)
asm volatile (
"BX %0"
:
: "r" (app_func)
);
}内存分区冲突
ROM_START + ROM_SIZE ≤ QBOOT_APP_ADDRQBOOT_APP_ADDRSystemInit()需包含SCB->VTOR设置堆栈指针验证
printf("[Boot] App Stack Top: 0x%08Xn", stk_addr);
printf("[Boot] App Entry Point: 0x%08Xn", app_func);时钟配置冲突
SystemClock_Config()重新初始化时钟HAL_RCC_DeInit();
__HAL_RCC_HSI_ENABLE(); // 切回内部时钟graph TD
A[Bootloader运行] --> B{检查配置}
B --> C[ROM分区是否正确?]
B --> D[VTOR地址对齐?]
B --> E[外设完全复位?]
C -->|错误| F[修正链接脚本]
D -->|未设置| G[App中添加SCB->VTOR]
E -->|残留状态| H[增强跳转函数]
F --> I[重新编译]
G --> I
H --> I
I --> J[烧录测试]
J -->|成功| K[正常进入App]
J -->|失败| L[调试内存映射]调试手段:
| 常见错误地址示例: | 配置项 | 典型错误值 | 正确示例 |
|---|---|---|---|
| QBOOT_APP_ADDR | 0x08000000 | 0x08010000 | |
| App VTOR | 未设置 | 0x08010000 | |
| FLASH SIZE | 与芯片实际不符 | 512K/1024K |
启动文件检查:
SystemInit通过以上步骤,90%以上的跳转失败问题可解决。重点排查中断向量表重定位和外设复位两个核心环节。
举报
更多回帖