我在Linux上使用带有gdb的Segger J-Link Base来调试Atmel SAM4S8C MCU。我在启动gdb时使用--command
参数指定的gdb命令文件中有以下内容:
target remote localhost:2331
monitor flash device SAM4S8C
我还在命令文件中指定了我的ELF文件和load
程序。
我注意到当我加载程序时(使用load
),堆栈指针未正确设置。 monitor reset
也不会修改堆栈指针。
J-Link User Guide表示(对于Cortex-M3设备):
此外,用户必须在复位后手动更正堆栈指针(R13)和PC(R15)以调试应用程序。
从gdb执行此操作的命令是什么?
奇怪的是,我必须手动执行此操作。堆栈指针是复位向量的第一个条目。在我开发代码时,初始堆栈指针会发生变化(特别是在具有非常不同的初始堆栈指针的应用程序之间切换,这是我第一次注意到这一点)。
有没有办法让gdb在load
期间从ELF文件中读取它并自动设置它?
答案 0 :(得分:3)
Cortex-M的设计使得不需要汇编启动代码:
在启动时,Cortex-M将自动从闪存的前两个32位字加载sp和pc寄存器
对于我的LPC1788,这意味着我需要加载r13 / sp,内容为 0x00000000 ,r15 / pc的内容为 0x00000004 :
target remote localhost:2331
monitor interface SWD
monitor endian little
monitor speed auto
monitor reset
monitor halt
monitor flash device = LPC1788
monitor flash download = 1
monitor flash breakpoints = 1
file program.elf
load program.elf
break main
monitor reg r13 = (0x00000000)
monitor reg r15 = (0x00000004)
continue
答案 1 :(得分:2)
我遇到了这个问题,因为我的产品使用了一个位于flash开头的bootloader,我想在调试时跳过它。由于堆栈指针值应存储为可执行文件中的第一个单词,而复位向量作为下一个存储,您需要以下内容:
$sp = {int} program_start_address
$pc = {int} program_start_address + 4
e.g。对于从0x08001000开始的二进制文件
$sp = {int} 0x08001000
$pc = {int} 0x08001004