C 重新定义stm32f3的初始堆栈指针值
我有一个stm32f303发现板,我正试图更多地理解链接和重新定位过程。我在这里编译并运行此示例: 重置堆栈指针值在设置脚本Device/startup_stm32f0x.s的向量表中定义。原始值为0x2000A000(即初始SRAM地址+32K)。 我能看到的唯一分配给SRAM的其他内容是.data和.bss部分:C 重新定义stm32f3的初始堆栈指针值,c,linker,arm,stm32,ld,C,Linker,Arm,Stm32,Ld,我有一个stm32f303发现板,我正试图更多地理解链接和重新定位过程。我在这里编译并运行此示例: 重置堆栈指针值在设置脚本Device/startup_stm32f0x.s的向量表中定义。原始值为0x2000A000(即初始SRAM地址+32K)。 我能看到的唯一分配给SRAM的其他内容是.data和.bss部分: 2 .data 0000004c 20000000 08000e94 00020000 2**2 CONTENTS,
2 .data 0000004c 20000000 08000e94 00020000 2**2
CONTENTS, ALLOC, LOAD, DATA
3 .bss 00000040 2000004c 08000ee0 0002004c 2**2
ALLOC
所以(忽略堆栈)从地址0x200008c到0x40000000的所有内容都应该免费供我使用,就SRAM而言
我尝试在启动脚本中将初始堆栈指针值减少32个字节(从0x2000A000减少到0x20009FD0),我们编译并运行一切正常
我尝试将初始堆栈指针值增加32个字节(从0x2000A000增加到0x2000A020),然后事情就停止了
运行GDB并在SystemInit函数处中断,导致问题的反汇编如下所示:
08000c18 <SystemInit>:
8000c18: b580 push {r7, lr}
8000c1a: af00 add r7, sp, #0
8000c1c: 4a1f ldr r2, [pc, #124] ; (8000c9c <SystemInit+0x84>)
8000c1e: 4b1f ldr r3, [pc, #124] ; (8000c9c <SystemInit+0x84>)
8000c20: f8d3 3088 ldr.w r3, [r3, #136] ; 0x88
08000c18:
8000c18:b580推送{r7,lr}
8000c1a:af00添加r7,sp,#0
8000c1c:4a1f ldr r2,[pc,#124];(8000c9c)
8000c1e:4b1f ldr r3,[pc,#124];(8000c9c)
8000c20:F8D33088 ldr.w r3[r3,#136];0x88
在这一点上,我们触发某种异常并跳转到WWDG_IRQHandler
。ldr.w指令中r3的值为0xe000ed00,这似乎是外围设备总线上的某个东西
让我困惑的是,这段代码以及所有寄存器和内存地址在运行的原始版本中都是相同的(当然,堆栈指针值除外),包括0xe000ed00+0x88处的ldr.w内存访问。知道这是怎么回事吗?除了向量表之外,还有其他管理初始堆栈指针的方法吗?我的建议
STM32F303VCT6微控制器,在LQFP100包中具有256千字节的闪存和48千字节的RAM。您绝对不能使用0x200008C-0x40000000。您的sram从0x20000000到0x2000BFFF,如ST0xe000ed00所述,应在arm文档中。是的,已确认,它在arm文档中。有趣的DV-任何原因?心情不好或报复我认为IDE的使用与这个问题无关(我没有提到我使用哪一个IDE…),我还没有找到一个比GDB TUI更有用的gui,它也适用于桌面linux开发。但是你确实解决了我的问题,并解释了为什么它会导致我看到的异常,因此,我将把这作为公认的答案。我猜异常处理程序是由指令地址8000c18处的初始堆栈推送触发的?你知道为什么PC在4条指令之后才跳转到处理程序吗?啊,可能是因为CPU是流水线的,执行原始推送需要几个周期?将在此处指示执行推送的3个周期,因此,再加上2个用于获取和解码的周期似乎与故障处理完全一致。@MatthewHampsey这里的管道问题。它只是使高频不精确。异常到达时正在刷新管道。对于uC开发来说,良好的IDE也很重要。Atolic有许多非常方便的调试插件,如HF分析仪(它节省了大量时间)、RTOS感知调试等。