使用GDB

时间:2017-12-01 09:06:56

标签: arm gdb embedded cortex-m thumb

我正在为一些内部Cortex-M4内核开发一套调试工具。我使用gcc / binutils工具链构建嵌入式(无操作系统)ELF图像,并使用QEMU的修改版本对其进行模拟。我在我的图像的开始(即0)创建中断向量表,并正确初始化堆栈指针和起始地址(即主要地址)。

目标程序正在按预期运行,使用GDB远程协议构建的调试工具正常运行。

我目前正在尝试理解的是如何从GDB启动软复位。也就是说,安排目标程序重新初始化,堆栈指针复位到向量表中的初始值,然后PC返回起始地址。

我已经向自己证明了将PC值设置为0并运行核心的操作是不合适的,结果是我的" UsageFault"异常处理程序被调用。 (我假设核心处于错误模式以执行此类操作)。

是否存在一种技术,即通过使用GDB远程协议进行寄存器写入,我可以对模拟内核进行软复位,而无需对QEMU会话进行电源循环?

2 个答案:

答案 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的内容。