我正在为一些内部的Cortex-M4内核开发一套调试工具。我正在使用一个gcc/binutils工具链构建嵌入式(无操作系统) ELF镜像,并使用QEMU的一个修改版本来模拟它们。我在图像的开始处(即0)创建了中断向量表,并正确初始化了堆栈指针和开始地址(即main的地址)。
目标程序运行正常,使用GDB remote协议构建的调试工具工作正常。
我现在想知道的是如何从GDB启动一个软重置。也就是说,安排目标程序重新初始化,将堆栈指针重置为向量表中的初始值,并将PC返回到起始地址。
我已经向自己演示了将PC值设置为0并运行内核的操作是不合适的,结果是调用了我的"UsageFault“异常处理程序。(我假设内核处于错误的模式,无法执行此类操作)。
有没有一种技术,即通过使用GDB远程协议的寄存器写入,我可以软重置模拟的内核,也就是说,不需要重新启动QEMU会话?
发布于 2017-12-02 02:51:06
可通过将SYSRESETREQ位+密钥写入AIRCR寄存器来进行软件重启:
AIRCR_REG_ADDRESS = 0xe000ed0c
AIRCR_KEY = 0x05fa0000
AIRCR_SYSRESETREQ_BIT = 0x00000004
AIRCR_REG = AIRCR_KEY | AIRCR_SYSRESETREQ_BIT更多信息请访问here
这是与所有皮质-M一起工作
发布于 2017-12-06 17:05:01
这是Cortex-M3的代码片段,我使用它跳转到任何包含有效代码的位置(包括跳转到0):
IRQn_Type interrupt = (IRQn_Type)0;
app_fn jump = *(app_fn *)(jumpaddr + sizeof(int)); //Reset is 2nd in table
uint32_t stack_adr = *(uint32_t *)(jumpaddr); //Stack pointer is 1st in table
//Disable interrupts before jumping
SysTick->CTRL &= ~ST_CTRL_ENABLE;
while (interrupt <= CANActivity_IRQn)
{
NVIC_DisableIRQ(interrupt);
interrupt++;
}
//Set the new stack pointer
__set_MSP(stack_adr);
//Set the new vector address
SCB->VTOR = (location & 0x1FFFFF80);
//Leap of faith!
jump();此代码假设jumpaddr是向量表的基地址,因为堆栈指针在表中是第一个,重置处理程序在表中是第二个。
禁用中断是必须的,因为您可能会在移动堆栈指针后触发中断,这通常会导致异常。
当然,这样做不会重置任何外设,因此需要在再次启用中断之前完成。
编辑:
您可以找到__set_MSP here的内容。
https://stackoverflow.com/questions/47589934
复制相似问题