我正在为一些内部Cortex-M4内核开发一套调试工具。我使用gcc / binutils工具链构建嵌入式(无操作系统)ELF图像,并使用QEMU的修改版本对其进行模拟。我在我的图像的开始(即0)创建中断向量表,并正确初始化堆栈指针和起始地址(即主要地址)。
目标程序正在按预期运行,使用GDB远程协议构建的调试工具正常运行。
我目前正在尝试理解的是如何从GDB启动软复位。也就是说,安排目标程序重新初始化,堆栈指针复位到向量表中的初始值,然后PC返回起始地址。
我已经向自己证明了将PC值设置为0并运行核心的操作是不合适的,结果是我的" UsageFault"异常处理程序被调用。 (我假设核心处于错误模式以执行此类操作)。
是否存在一种技术,即通过使用GDB远程协议进行寄存器写入,我可以对模拟内核进行软复位,而无需对QEMU会话进行电源循环?
答案 0 :(得分:0)
您可以通过将SYSRESETREQ
位+ KEY写入AIRCR
寄存器来重启SW:
AIRCR_REG_ADDRESS = 0xe000ed0c
AIRCR_KEY = 0x05fa0000
AIRCR_SYSRESETREQ_BIT = 0x00000004
AIRCR_REG = AIRCR_KEY | AIRCR_SYSRESETREQ_BIT
更多信息是here
这适用于所有cortex-M
答案 1 :(得分:0)
这是我用来跳转到任何有效代码的位置(包括跳转到0)的Cortex-M3的代码片段:
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的内容。