针对CUEBIDE生成的APP程序在写入FLASH后无法正常跳转的问题,以下是系统化的解决方案:
SCB->VTOR,但可能被其他初始化代码覆盖。检查并修改STM32F407ZGTX_FLASH.ld:
MEMORY {
/* 调整FLASH起始点为APP偏移地址(例如0x08010000) */
FLASH (rx) : ORIGIN = 0x08010000, LENGTH = 1M - 64K /* 假设Bootloader占64K */
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
CCMRAM (xrw): ORIGIN = 0x10000000, LENGTH = 64K
}
SECTIONS {
/* 确保向量表位于FLASH起始 */
.isr_vector : {
. = ALIGN(4);
KEEP(*(.isr_vector)) /* 必须保留中断向量表 */
. = ALIGN(4);
} >FLASH
/* 添加.data段重定位到RAM */
.data : {
_sdata = .; /* 符号记录RAM中的起始地址 */
*(.data) /* 数据段 */
_edata = .; /* 符号记录结束地址 */
} >RAM AT>FLASH /* 存储在FLASH,运行时在RAM */
}在main()初始化前设置VTOR:
void SystemInit(void) {
// 添加VTOR设置(优先级高于main)
SCB->VTOR = 0x08010000; // 与链接脚本FLASH起始地址一致
}
int main(void) {
__enable_irq(); // 确保全局中断开启
// ...其他代码
}注意:如果SystemInit()被库覆盖,在启动文件startup_stm32f407xx.s的Reset_Handler中插入:
Reset_Handler:
ldr r0, =0x08010000 // 设置VTOR偏移
ldr r1, =0xE000ED08
str r0, [r1]
// ...后续初始化在startup_stm32f407xx.s中Reset_Handler添加.data复制:
Reset_Handler:
// 设置VTOR(如上)
// 复制.data段到RAM
ldr r0, =_sdata
ldr r1, =_edata
ldr r2, =_sidata // FLASH中的数据源地址
movs r3, #0
b LoopCopyDataInit
CopyDataInit:
ldr r4, [r2, r3]
str r4, [r0, r3]
adds r3, r3, #4
LoopCopyDataInit:
adds r4, r0, r3
cmp r4, r1
bcc CopyDataInitVECT_TAB_OFFSET=0x10000(对应64K偏移)。-O2)。0x20000000~0x200200000x080100xx0x00000000,表明向量表未正确链接。确认Bootloader跳转前执行:
// 关闭所有中断
__disable_irq();
// 清除中断标志(防止遗留中断)
for (int i = 0; i < 8; i++) NVIC->ICER[i] = 0xFFFFFFFF;
// 设置MSP并跳转
uint32_t pStack = *(__IO uint32_t*)APP_ADDRESS;
uint32_t pReset = *(__IO uint32_t*)(APP_ADDRESS + 4);
__set_MSP(pStack);
((void (*)())pReset)();用CUEBIDE编译后,用objdump检查.isr_vector段地址:
arm-none-eabi-objdump -t output.elf | grep isr_vector输出应为:08010000 g O .isr_vector
对比KEIL与CUEBIDE的MAP文件,确认关键段地址一致性。
烧录后单步调试Bootloader跳转过程,观察MSP值是否被正确设置为RAM地址。
通过以上步骤,90%的问题源于链接脚本偏移或启动文件的数据搬运缺失。重点检查关键内存段的实际部署地址是否与理论值匹配。
举报
更多回帖